From db3f215ebeb0ef8ddf483e373372a16049db824b Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Fri, 19 Aug 2022 17:20:01 -0500 Subject: [PATCH] Add way to declare failure for an upgrade doesn't really cancel it, since Tailbone isn't actually tracking the subprocess etc. but saves a step when something goes off the rails --- tailbone/templates/upgrades/view.mako | 38 ++++++++++++++++ tailbone/views/upgrades.py | 65 ++++++++++++++++++++++++--- 2 files changed, 97 insertions(+), 6 deletions(-) diff --git a/tailbone/templates/upgrades/view.mako b/tailbone/templates/upgrades/view.mako index 03fd9b6b..6a027921 100644 --- a/tailbone/templates/upgrades/view.mako +++ b/tailbone/templates/upgrades/view.mako @@ -38,6 +38,27 @@ % endif +<%def name="render_this_page()"> + ${parent.render_this_page()} + + % if master.has_perm('execute'): + ${h.form(master.get_action_url('declare_failure', instance), ref='declareFailureForm')} + ${h.csrf_token(request)} + ${h.end_form()} + % endif + + +<%def name="render_buefy_form()"> +
+ <${form.component} + % if master.has_perm('execute'): + @declare-failure="declareFailure" + % endif + > + +
+ + <%def name="render_form_buttons()"> % if not instance.executed and instance.status_code == enum.UPGRADE_STATUS_PENDING and request.has_perm('{}.execute'.format(permission_prefix)):
@@ -81,6 +102,23 @@ this.formButtonText = "Working, please wait..." } + % if master.has_perm('execute'): + + TailboneFormData.declareFailureSubmitting = false + + TailboneForm.methods.declareFailureClick = function() { + if (confirm("Really declare this upgrade a failure?")) { + this.declareFailureSubmitting = true + this.$emit('declare-failure') + } + } + + ThisPage.methods.declareFailure = function() { + this.$refs.declareFailureForm.submit() + } + + % endif + diff --git a/tailbone/views/upgrades.py b/tailbone/views/upgrades.py index ff4de768..2e7c2fc4 100644 --- a/tailbone/views/upgrades.py +++ b/tailbone/views/upgrades.py @@ -162,7 +162,7 @@ class UpgradeView(MasterView): f.remove_field('status_code') else: f.set_enum('status_code', self.enum.UPGRADE_STATUS) - # f.set_readonly('status_code') + f.set_renderer('status_code', self.render_status_code) # executing if not self.editing: @@ -205,6 +205,33 @@ class UpgradeView(MasterView): f.remove_field('package_diff') f.remove_field('exit_code') + def render_status_code(self, upgrade, field): + code = getattr(upgrade, field) + text = self.enum.UPGRADE_STATUS[code] + + if self.get_use_buefy(): + if code == self.enum.UPGRADE_STATUS_EXECUTING: + + text = HTML.tag('span', c=[text]) + + button = HTML.tag('b-button', + type='is-warning', + icon_pack='fas', + icon_left='sad-tear', + c=['{{ declareFailureSubmitting ? "Working, please wait..." : "Declare Failure" }}'], + **{':disabled': 'declareFailureSubmitting', + '@click': 'declareFailureClick'}) + + return HTML.tag('div', class_='level', c=[ + HTML.tag('div', class_='level-left', c=[ + HTML.tag('div', class_='level-item', c=[text]), + HTML.tag('div', class_='level-item', c=[button]), + ]), + ]) + + # just show status per normal + return text + def configure_clone_form(self, f): f.fields = ['description', 'notes', 'enabled'] @@ -446,23 +473,49 @@ class UpgradeView(MasterView): return data + def declare_failure(self): + upgrade = self.get_instance() + if upgrade.executing and upgrade.status_code == self.enum.UPGRADE_STATUS_EXECUTING: + upgrade.executing = False + upgrade.status_code = self.enum.UPGRADE_STATUS_FAILED + self.request.session.flash("Upgrade was declared a failure.", 'warning') + else: + self.request.session.flash("Upgrade was not currently executing! " + "So it was not declared a failure.", + 'error') + return self.redirect(self.get_action_url('view', upgrade)) + def delete_instance(self, upgrade): self.handler.delete_files(upgrade) super(UpgradeView, self).delete_instance(upgrade) @classmethod def defaults(cls, config): + cls._defaults(config) + cls._upgrade_defaults(config) + + @classmethod + def _upgrade_defaults(cls, config): route_prefix = cls.get_route_prefix() - url_prefix = cls.get_url_prefix() permission_prefix = cls.get_permission_prefix() + instance_url_prefix = cls.get_instance_url_prefix() model_key = cls.get_model_key() # execution progress - config.add_route('{}.execute_progress'.format(route_prefix), '{}/{{{}}}/execute/progress'.format(url_prefix, model_key)) - config.add_view(cls, attr='execute_progress', route_name='{}.execute_progress'.format(route_prefix), - permission='{}.execute'.format(permission_prefix), renderer='json') + config.add_route('{}.execute_progress'.format(route_prefix), + '{}/execute/progress'.format(instance_url_prefix)) + config.add_view(cls, attr='execute_progress', + route_name='{}.execute_progress'.format(route_prefix), + permission='{}.execute'.format(permission_prefix), + renderer='json') - cls._defaults(config) + # declare failure + config.add_route('{}.declare_failure'.format(route_prefix), + '{}/declare-failure'.format(instance_url_prefix), + request_method='POST') + config.add_view(cls, attr='declare_failure', + route_name='{}.declare_failure'.format(route_prefix), + permission='{}.execute'.format(permission_prefix)) def defaults(config, **kwargs):