]> git.ipfire.org Git - pbs.git/commitdiff
builders: Refactor deleteing builders
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 29 May 2023 12:51:54 +0000 (12:51 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 29 May 2023 12:51:54 +0000 (12:51 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/buildservice/builders.py
src/database.sql
src/templates/builders/delete.html
src/templates/builders/show.html
src/web/__init__.py
src/web/builders.py

index 104a9ba2d58ec536238064b2e2d4647d90c6a08a..c2dcb8c8e7b6cc2e6a5438a573ac2d6ad7634e55 100644 (file)
@@ -31,7 +31,7 @@ class Builders(base.Object):
 
        def __iter__(self):
                builders = self._get_builders("SELECT * FROM builders \
-                       WHERE deleted IS FALSE ORDER BY name")
+                       WHERE deleted_at IS NULL ORDER BY name")
 
                return iter(builders)
 
@@ -54,7 +54,7 @@ class Builders(base.Object):
 
        def get_by_name(self, name):
                return self._get_builder("SELECT * FROM builders \
-                       WHERE name = %s AND deleted IS FALSE", name)
+                       WHERE name = %s AND deleted_at IS NULL", name)
 
        @property
        def connected(self):
@@ -729,6 +729,18 @@ class Builder(base.DataObject):
                # Otherwise return a neutral preference
                return 0
 
+       # Delete
+
+       def delete(self, user=None):
+               """
+                       Deletes this builder
+               """
+               log.info("Deleted builder %s" % self)
+
+               self._set_attribute_now("deleted_at")
+               if user:
+                       self._set_attribute("deleted_by", user)
+
        # Stats
 
        @lazy_property
index 69cb4c5f6b6585bf01ecf95f6296a1e4e806721f..54b66adbcfd5b2d7ced0c243c8d9c3449c0048d9 100644 (file)
@@ -336,7 +336,6 @@ CREATE TABLE public.builders (
     name text NOT NULL,
     description text,
     enabled boolean DEFAULT false NOT NULL,
-    deleted boolean DEFAULT false NOT NULL,
     loadavg text DEFAULT '0'::character varying NOT NULL,
     maintenance boolean DEFAULT false NOT NULL,
     max_jobs bigint DEFAULT (1)::bigint NOT NULL,
@@ -345,14 +344,15 @@ CREATE TABLE public.builders (
     cpu_model text,
     cpu_count integer DEFAULT 1 NOT NULL,
     host_key_id text,
-    time_created timestamp without time zone DEFAULT now() NOT NULL,
     updated_at timestamp without time zone,
-    time_keepalive timestamp without time zone,
-    online_until timestamp without time zone,
     cpu_arch text,
     instance_id text,
     instance_type text,
-    mem_total bigint
+    mem_total bigint,
+    created_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
+    created_by integer,
+    deleted_at timestamp without time zone,
+    deleted_by integer
 );
 
 
@@ -1593,7 +1593,7 @@ CREATE UNIQUE INDEX build_watchers_unique ON public.build_watchers USING btree (
 -- Name: builders_name; Type: INDEX; Schema: public; Owner: -
 --
 
-CREATE UNIQUE INDEX builders_name ON public.builders USING btree (name) WHERE (deleted IS FALSE);
+CREATE UNIQUE INDEX builders_name ON public.builders USING btree (name) WHERE (deleted_at IS NULL);
 
 
 --
@@ -1995,6 +1995,22 @@ ALTER TABLE ONLY public.builder_stats
     ADD CONSTRAINT builder_stats_builder_id FOREIGN KEY (builder_id) REFERENCES public.builders(id);
 
 
+--
+-- Name: builders builders_created_by; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.builders
+    ADD CONSTRAINT builders_created_by FOREIGN KEY (created_by) REFERENCES public.users(id);
+
+
+--
+-- Name: builders builders_deleted_by; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.builders
+    ADD CONSTRAINT builders_deleted_by FOREIGN KEY (deleted_by) REFERENCES public.users(id);
+
+
 --
 -- Name: builds builds_build_group_id; Type: FK CONSTRAINT; Schema: public; Owner: -
 --
index c62a41711082917d4bf301911e9a2c858315a7df..c22505bcf60192461e76c2300c28c6c7d73167a8 100644 (file)
@@ -1,48 +1,43 @@
-{% extends "../base.html" %}
+{% extends "../modal.html" %}
 
-{% block title %}{{ _("Delete builder %s") % builder.name }}{% end block %}
+{% block title %}{{ _("Delete Builder") }} - {{ builder }}{% end block %}
 
-{% block body %}
-       <div class="row">
-               <div class="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-12">
-                       <nav aria-label="breadcrumb" role="navigation">
-                               <ol class="breadcrumb">
-                                       <li class="breadcrumb-item"><a href="/">{{ _("Home") }}</a></li>
-                                       <li class="breadcrumb-item"><a href="/builders">{{ _("Builders") }}</a></li>
-                                       <li class="breadcrumb-item"><a href="/builders/{{ builder.name }}">{{ builder.name }}</a></li>
-                                       <li class="breadcrumb-item active">
-                                                       <a href="/builders/{{ builder.name }}/delete">{{ _("Delete") }}</a>
-                                       </li>
-                               </ol>
-                       </nav>
-               </div>
-       </div>
+{% block breadcrumbs %}
+       <nav class="breadcrumb" aria-label="breadcrumbs">
+               <ul>
+                       <li>
+                               <a href="/builders">{{ _("Builders") }}</a>
+                       </li>
+                       <li>
+                               <a href="/builders/{{ builder.hostname }}">{{ builder }}</a>
+                       </li>
+                       <li class="is-active">
+                               <a href="#" aria-current="page">{{ _("Delete") }}</a>
+                       </li>
+               </ul>
+       </nav>
+{% end block %}
+
+{% block modal_title %}
+       <h4 class="title is-4">{{ _("Delete Builder") }}</h4>
+       <h6 class="subtitle is-6">{{ builder }}</h6>
+{% end block %}
+
+{% block modal %}
+       <form method="POST" action="">
+               {% raw xsrf_form_html() %}
 
-       <div class="row">
-               <div class="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-12">
-                       <div class="alert alert-danger" role="alert">
-                               <h2 class="alert-heading" style="word-wrap: break-word;">
-                                       {{ _("Delete builder: %s") % builder.name }}
-                               </h2>
-                               <p>
-                                       {{ _("You are going to delete the build host %s.") % builder.name }}
-                               </p>
-                       </div>
+               <div class="content">
+                       <p>
+                               {{ _("Are you sure you want to delete %s?") % builder }}
+                       </p>
                </div>
-       </div>
 
-       <div class="row">
-               <div class="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-12">
-                       <div class="btn-toolbar" role="toolbar">
-                               <div class="btn-group mr-2 mb-2" role="group">
-                                       <a class="btn btn-danger" href="/builders/{{ builder.name }}/delete?confirmed=1">
-                                               {{ _("Delete %s") % builder.name }}
-                                       </a>
-                               </div>
-                               <div class="btn-group mb-2" role="group">
-                                       <a class="btn btn-primary" href="/builders/{{ builder.name }}">{{ _("Cancel") }}</a>
-                               </div>
-                       </div>
+               {# Submit! #}
+               <div class="field">
+                       <button type="submit" class="button is-danger is-fullwidth">
+                               {{ _("Delete") }}
+                       </button>
                </div>
-       </div>
+       </form>
 {% end block %}
index f0764607e3e1c5c6488e25fdab4db223aea3c712..b777598fd8c3c7d6a46bf5a147603e7739aeac2a 100644 (file)
                                <a class="button is-warning" href="/builders/{{ builder.hostname }}/edit">
                                        {{ _("Edit") }}
                                </a>
+
+                               <a class="button is-danger" href="/builders/{{ builder.hostname }}/delete">
+                                       {{ _("Delete") }}
+                               </a>
                        </div>
                </section>
        {% end %}
index 9208ac2ef53d26b40560fb3c42b6e3abfd7b4e4d..8e52a8b8ad383c18bd406cc75b6a96721756cbc2 100644 (file)
@@ -182,7 +182,7 @@ class Application(tornado.web.Application):
                        (r"/builders", builders.IndexHandler),
                        (r"/builders/create", builders.CreateHandler),
                        (r"/builders/([A-Za-z0-9\-\.]+)", builders.ShowHandler),
-                       (r"/builders/([A-Za-z0-9\-\.]+)/delete", builders.BuilderDeleteHandler),
+                       (r"/builders/([A-Za-z0-9\-\.]+)/delete", builders.DeleteHandler),
                        (r"/builders/([A-Za-z0-9\-\.]+)/edit", builders.BuilderEditHandler),
                        (r"/builders/([A-Za-z0-9\-\.]+)/stats", builders.StatsHandler),
                        (r"/api/v1/builders/control", builders.APIv1ControlHandler),
index 0327d03ffc5573c5acaee63bb3be0591427c04a1..89336b4ddd544dba6875fcec9ebeaf1053ab5372 100644 (file)
@@ -146,7 +146,7 @@ class BuilderEditHandler(base.BaseHandler):
                self.redirect("/builders/%s" % builder.hostname)
 
 
-class BuilderDeleteHandler(base.BaseHandler):
+class DeleteHandler(base.BaseHandler):
        @tornado.web.authenticated
        def get(self, name):
                builder = self.backend.builders.get_by_name(name)
@@ -157,15 +157,23 @@ class BuilderDeleteHandler(base.BaseHandler):
                if not builder.has_perm(self.current_user):
                        raise tornado.web.HTTPError(403)
 
-               confirmed = self.get_argument("confirmed", None)
-               if confirmed:
-                       with self.db.transaction():
-                               builder.deleted = True
+               self.render("builders/delete.html", builder=builder)
 
-                       self.redirect("/builders")
-                       return
+       @tornado.web.authenticated
+       async def post(self, hostname):
+               builder = self.backend.builders.get_by_name(hostname)
+               if not builder:
+                       raise tornado.web.HTTPError(404, "Builder not found: %s" % hostname)
 
-               self.render("builders/delete.html", builder=builder)
+               # Check permissions
+               if not builder.has_perm(self.current_user):
+                       raise tornado.web.HTTPError(403)
+
+               # Delete the builder
+               with self.db.transaction():
+                       builder.delete(user=self.current_user)
+
+               self.redirect("/builders")
 
 
 class StatsModule(ui_modules.UIModule):