From: Michael Tremer Date: Sun, 23 Oct 2022 19:38:17 +0000 (+0000) Subject: jobs: Build UI to manually abort a job X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=660ef718b959f50a8ac3e2f74015b7652b34ce87;p=pbs.git jobs: Build UI to manually abort a job Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index 07a63ed1..2b0823ab 100644 --- a/Makefile.am +++ b/Makefile.am @@ -158,7 +158,6 @@ webdir = $(buildservicedir)/web dist_templates_DATA = \ src/templates/base.html \ src/templates/index.html \ - src/templates/jobs-abort.html \ src/templates/jobs-buildroot.html \ src/templates/log.html \ src/templates/login.html \ @@ -229,6 +228,9 @@ dist_templates_events_modules_DATA = \ templates_events_modulesdir = $(templates_eventsdir)/modules +dist_templates_jobs_DATA = \ + src/templates/jobs/abort.html + templates_jobsdir = $(templatesdir)/jobs dist_templates_jobs_messages_DATA = \ diff --git a/src/buildservice/jobs.py b/src/buildservice/jobs.py index 11ed3bf6..32f25a4f 100644 --- a/src/buildservice/jobs.py +++ b/src/buildservice/jobs.py @@ -114,6 +114,13 @@ class Job(base.DataObject): return NotImplemented + def has_perm(self, user): + """ + Check permissions + """ + # This is the same as for builds + return self.build.has_perm(user) + @property def uuid(self): return self.data.uuid @@ -314,6 +321,14 @@ class Job(base.DataObject): if self.has_finished(): return self.data.failed + # Abort + + async def abort(self, user=None): + """ + Aborts the job + """ + pass # XXX TODO + @property def message(self): return self.data.message diff --git a/src/templates/jobs-abort.html b/src/templates/jobs-abort.html deleted file mode 100644 index a915f502..00000000 --- a/src/templates/jobs-abort.html +++ /dev/null @@ -1,53 +0,0 @@ -{% extends "base.html" %} - -{% block title %}{{ _("Abort build job %s") % job.name }}{% end block %} - -{% block body %} -

{{ _("Abort build job %s") % job.name }}

-

- {{ _("You may abort a running build.") }} - {{ _("The build server will eventually stop to build the package.") }} -

- -
- {% raw xsrf_form_html() %} - - - - - - - - - - - - - - - - - - - -
{{ _("Build job") }} - {{ job.name }} - -   -
{{ _("Start time") }} - {% if job.time_started %} - {{ locale.format_date(job.time_started, full_format=True) }} - {% else %} - {{ _("No started, yet.") }} - {% end %} - -   -
{{ _("Build server") }} - {{ job.builder.name }} - -   -
- -
-
-{% end block %} diff --git a/src/templates/jobs/abort.html b/src/templates/jobs/abort.html new file mode 100644 index 00000000..f1ca06b5 --- /dev/null +++ b/src/templates/jobs/abort.html @@ -0,0 +1,37 @@ +{% extends "../base.html" %} + +{% block title %}{{ _("Abort Job %s") % job }}{% end block %} + +{% block container %} + + +
+
+

{{ _("Abort Job") }}

+ +
+
+ {% raw xsrf_form_html() %} + + +
+
+
+
+{% end block %} diff --git a/src/templates/jobs/modules/list.html b/src/templates/jobs/modules/list.html index 4a3c9c2d..900fecc7 100644 --- a/src/templates/jobs/modules/list.html +++ b/src/templates/jobs/modules/list.html @@ -43,9 +43,15 @@ -
+
{{ format_time(job.duration, shorter=True) }}
+ +
{% end %} diff --git a/src/web/__init__.py b/src/web/__init__.py index 0a698750..d2095ec8 100644 --- a/src/web/__init__.py +++ b/src/web/__init__.py @@ -131,8 +131,8 @@ class Application(tornado.web.Application): (r"/queue", jobs.QueueHandler), # Jobs + (r"/jobs/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/abort", jobs.AbortHandler), (r"/jobs/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/log", jobs.LogHandler), - (r"/job/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/abort", jobs.JobAbortHandler), (r"/job/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/buildroot", jobs.JobBuildrootHandler), # Builders diff --git a/src/web/jobs.py b/src/web/jobs.py index 27879308..83e85d7e 100644 --- a/src/web/jobs.py +++ b/src/web/jobs.py @@ -56,41 +56,33 @@ class JobBuildrootHandler(base.BaseHandler): buildroot_size=buildroot_size) -class JobAbortHandler(base.BaseHandler): - def get_job(self, uuid): +class AbortHandler(base.BaseHandler): + @tornado.web.authenticated + def get(self, uuid): job = self.backend.jobs.get_by_uuid(uuid) if not job: raise tornado.web.HTTPError(404, "Job not found: %s" % uuid) - return job - - @tornado.web.authenticated - def get(self, uuid): - job = self.get_job(uuid) - - # XXX Check if user has the right to manage the job. + # Check for permissions + if not job.has_perm(self.current_user): + raise tornado.web.HTTPError(403) - self.render("jobs-abort.html", job=job) + self.render("jobs/abort.html", job=job) @tornado.web.authenticated - def post(self, uuid): - job = self.get_job(uuid) - - # XXX Check if user has the right to manage the job. - - # Only running builds can be set to aborted state. - if not job.state == "running": - # XXX send the user a nicer error message. - self.redirect("/job/%s" % job.uuid) - return + async def post(self, uuid): + job = self.backend.jobs.get_by_uuid(uuid) + if not job: + raise tornado.web.HTTPError(404, "Job not found: %s" % uuid) - # Set the job into aborted state. - job.state = "aborted" + # Check for permissions + if not job.has_perm(self.current_user): + raise tornado.web.HTTPError(403) - # 0 means the job was aborted by the user. - job.aborted_state = 0 + with self.db.transaction(): + await job.abort(self.current_user) - self.redirect("/job/%s" % job.uuid) + self.redirect("/builds/%s" % job.build.uuid) class ListModule(ui_modules.UIModule):