From ac73780bd9e2041de8110e2e32daa4a44f265793 Mon Sep 17 00:00:00 2001 From: Paul Eggleton Date: Tue, 18 Sep 2018 15:30:03 +1200 Subject: [PATCH] Properly show update task success/failure If a distro comparison update task fails (returning a non-zero value to indicate as such) we were not able to see this easily from the frontend. Show success/failure in the form of a label on the task page and general update list/detail, and if the task fails while we're watching then make the progress bar go red as well. Also make a distinction between the process failing (retcode > 0) and being terminated (retcode < 0, e.g. process was killed). Signed-off-by: Paul Eggleton --- layerindex/migrations/0025_update_retcode.py | 20 +++++++++++++++++++ layerindex/models.py | 1 + layerindex/tasks.py | 9 +++++++++ layerindex/views.py | 5 +++++ templates/layerindex/task.html | 21 +++++++++++++++++++- templates/layerindex/updatedetail.html | 4 +++- templates/layerindex/updatelist.html | 5 ++++- 7 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 layerindex/migrations/0025_update_retcode.py diff --git a/layerindex/migrations/0025_update_retcode.py b/layerindex/migrations/0025_update_retcode.py new file mode 100644 index 0000000..d1ad814 --- /dev/null +++ b/layerindex/migrations/0025_update_retcode.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.12 on 2018-09-18 00:46 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('layerindex', '0024_layerupdate_vcs_revs'), + ] + + operations = [ + migrations.AddField( + model_name='update', + name='retcode', + field=models.IntegerField(default=0), + ), + ] diff --git a/layerindex/models.py b/layerindex/models.py index 6255c60..c1a2c67 100644 --- a/layerindex/models.py +++ b/layerindex/models.py @@ -97,6 +97,7 @@ class Update(models.Model): reload = models.BooleanField('Reloaded', default=False, help_text='Was this update a reload?') task_id = models.CharField(max_length=50, blank=True, db_index=True) triggered_by = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL) + retcode = models.IntegerField(default=0) def error_count(self): sums = self.layerupdate_set.aggregate(errors=models.Sum('errors')) diff --git a/layerindex/tasks.py b/layerindex/tasks.py index 7ed0663..ec6e8fe 100644 --- a/layerindex/tasks.py +++ b/layerindex/tasks.py @@ -47,13 +47,22 @@ def run_update_command(self, branch_name, update_command): except FileExistsError: pass logfile = os.path.join(settings.TASK_LOG_DIR, 'task_%s.log' % str(self.request.id)) + retcode = 0 + erroutput = None try: output = utils.runcmd(update_command, os.path.dirname(os.path.dirname(__file__)), outfile=logfile) except subprocess.CalledProcessError as e: output = e.output + erroutput = output + retcode = e.returncode except Exception as e: + print('ERROR: %s' % str(e)) output = str(e) + erroutput = output + retcode = -1 finally: updateobj.log = output updateobj.finished = datetime.now() + updateobj.retcode = retcode updateobj.save() + return {'retcode': retcode, 'output': erroutput} diff --git a/layerindex/views.py b/layerindex/views.py index 8dc1b61..f25b1bd 100644 --- a/layerindex/views.py +++ b/layerindex/views.py @@ -1401,6 +1401,11 @@ def task_log_view(request, task_id): updateobj = get_object_or_404(Update, task_id=task_id) response['Task-Duration'] = utils.timesince2(updateobj.started, updateobj.finished) response['Task-Progress'] = 100 + if result.info: + if isinstance(result.info, dict): + response['Task-Result'] = result.info.get('retcode', None) + else: + response['Task-Result'] = -1 else: response['Task-Done'] = '0' preader = utils.ProgressReader(settings.TASK_LOG_DIR, task_id) diff --git a/templates/layerindex/task.html b/templates/layerindex/task.html index a57e730..0937e03 100644 --- a/templates/layerindex/task.html +++ b/templates/layerindex/task.html @@ -19,7 +19,7 @@ {% block content %} {% autoescape on %} -

Task status for {{ update.task_id }} started by {{ update.triggered_by }} on {{ update.started }}{% if update.finished %} (finished in {{ update.started | timesince2:update.finished }}){% endif %}:

+

Task status for {{ update.task_id }} started by {{ update.triggered_by }} on {{ update.started }}{% if update.finished %} (finished in {{ update.started | timesince2:update.finished }}){% endif %}:{% if update.finished %}{% if update.retcode < 0 %}TERMINATED ({{ update.retcode }}){% elif update.retcode %}FAILED{% else %}SUCCEEDED{% endif %}{% endif %}

{{ update.log }}
@@ -69,6 +69,25 @@ $('#progressbar').css('width', progress + '%').attr('aria-valuenow', progress); $("#progressbar").html(progress + '%') } + result = xhr.getResponseHeader('Task-Result'); + if(result && result != 0) { + progress = 100 + $('#progressbar').css('width', progress + '%').attr('aria-valuenow', progress); + if(result < 0) { + failstr = "TERMINATED (" + result + ")"; + } + else { + failstr = "FAILED"; + } + $("#progressbar").html(failstr); + $("#progressbar").removeClass('progress-bar-info').addClass('progress-bar-danger'); + $("#status-label").html(failstr); + $("#status-label").addClass('label-danger'); + } + else if(done == '1') { + $("#status-label").html('SUCCEEDED'); + $("#status-label").addClass('label-success'); + } } }).always(function () { if(done == '1') { diff --git a/templates/layerindex/updatedetail.html b/templates/layerindex/updatedetail.html index 619d239..4438223 100644 --- a/templates/layerindex/updatedetail.html +++ b/templates/layerindex/updatedetail.html @@ -24,7 +24,9 @@ -

{{ update.started }} {% if update.reload %}(reload){% endif %}

+

{{ update.started }} {% if update.reload %}(reload){% endif %} +{% if update.finished %}{% if update.retcode < 0 %}TERMINATED ({{ update.retcode }}){% elif update.retcode %}FAILED{% endif %}{% endif %} +

{% if update.log %}
{{ update.log }}
diff --git a/templates/layerindex/updatelist.html b/templates/layerindex/updatelist.html index afc5d68..a6987b4 100644 --- a/templates/layerindex/updatelist.html +++ b/templates/layerindex/updatelist.html @@ -37,7 +37,10 @@ {% for update in updates %} {% with error_count=update.error_count warning_count=update.warning_count %} - {{ update.started }}{% if update.reload %} (reload){% endif %} + + {{ update.started }}{% if update.reload %} (reload){% endif %} + {% if update.finished and update.retcode %}{% if update.retcode < 0 %}TERMINATED{% elif update.retcode %}FAILED{% endif %}{% endif %} + {% if update.finished %}{{ update.started|timesince2:update.finished }}{% else %}(in progress){% endif %} {% if error_count %}{{ error_count }}{% endif %} {% if warning_count %}{{ warning_count }}{% endif %}