From b80b2bd5d2e4b4459c9e328c1eabf15e4fef91a8 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Wed, 3 May 2023 16:23:38 +0000 Subject: [PATCH] jobs: Move finish handling into a regular handler This allows us to reliably send a success message to the builder. Signed-off-by: Michael Tremer --- src/buildservice/jobs.py | 5 +++++ src/web/__init__.py | 4 +++- src/web/jobs.py | 40 +++++++++++++++++++++++++--------------- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/buildservice/jobs.py b/src/buildservice/jobs.py index d02ff3c5..2f567a84 100644 --- a/src/buildservice/jobs.py +++ b/src/buildservice/jobs.py @@ -13,6 +13,7 @@ import pakfire import pakfire.config from . import base +from . import builders from . import users from .constants import * @@ -225,6 +226,10 @@ class Job(base.DataObject): """ Check permissions """ + # Check if this builder can modify the job + if isinstance(user, builders.Builder): + return self.builder == user + # This is the same as for builds return self.build.has_perm(user) diff --git a/src/web/__init__.py b/src/web/__init__.py index 84e2ac81..ada33433 100644 --- a/src/web/__init__.py +++ b/src/web/__init__.py @@ -144,7 +144,9 @@ class Application(tornado.web.Application): (r"/jobs/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/retry", jobs.RetryHandler), (r"/job/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/buildroot", jobs.JobBuildrootHandler), (r"/api/v1/jobs/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})", - jobs.APIv1DetailHandler), + jobs.APIv1ControlHandler), + (r"/api/v1/jobs/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/finished", + jobs.APIv1FinishedHandler), (r"/api/v1/jobs/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/log/stream", jobs.APIv1LogStreamHandler), diff --git a/src/web/jobs.py b/src/web/jobs.py index 2811917c..e4d6d3ac 100644 --- a/src/web/jobs.py +++ b/src/web/jobs.py @@ -10,7 +10,7 @@ from . import ui_modules # Setup logging log = logging.getLogger("pbs.web.jobs") -class APIv1DetailHandler(base.APIMixin, tornado.websocket.WebSocketHandler): +class APIv1ControlHandler(base.APIMixin, tornado.websocket.WebSocketHandler): """ Builders connect to this handler when they are running a build. @@ -54,10 +54,6 @@ class APIv1DetailHandler(base.APIMixin, tornado.websocket.WebSocketHandler): if type == "log": await self._handle_log(**data) - # Handle finished message - elif type == "finished": - await self._handle_finished(**data) - # Unknown message else: log.warning("Received a message of an unknown type: %s" % t) @@ -68,21 +64,30 @@ class APIv1DetailHandler(base.APIMixin, tornado.websocket.WebSocketHandler): """ await self.logstream.message(timestamp, level, message) - async def _handle_finished(self, success=False, logfile=None, packages=[], **kwargs): - """ - Called when a job has finished - whether successfully or not - """ - # Fetch the log - if logfile: - logfile = self.backend.uploads.get_by_uuid(logfile) + +class APIv1FinishedHandler(base.APIMixin, tornado.web.RequestHandler): + @tornado.web.authenticated + async def post(self, uuid): + job = self.backend.jobs.get_by_uuid(uuid) + if not job: + raise tornado.web.HTTPError(404, "Could not find job %s" % uuid) + + # Check permissions + if not job.has_perm(self.current_user): + raise tornado.web.HTTPError(403, "%s cannot edit job %s" % (self.current_user, job)) + + # Success Status + success = self.get_argument_bool("success") + + # Fetch the logfile + logfile = self.get_argument_upload("logfile") # Fetch the packages - if packages: - packages = [self.backend.uploads.get_by_uuid(p) for p in packages] + packages = self.get_argument_uploads("packages") # Mark the job as finished with self.db.transaction(): - builds = await self.job.finished(success=success, + builds = await job.finished(success=success, logfile=logfile, packages=packages) # Try to dispatch the next job @@ -92,6 +97,11 @@ class APIv1DetailHandler(base.APIMixin, tornado.websocket.WebSocketHandler): if builds: self.backend.run_task(self.backend.builds.launch, builds) + # Send something back to the builder + self.finish({ + "status" : "ok", + }) + class APIv1LogStreamHandler(base.BackendMixin, tornado.websocket.WebSocketHandler): # No authentication required -- 2.47.2