From b9bfc1e60c1cf68bab4937137f41d10a8139dd97 Mon Sep 17 00:00:00 2001 From: Maxim Kulkin Date: Tue, 1 Oct 2013 13:30:52 +0400 Subject: [PATCH] Added better handling and reporting of unexpected errors during validation --- ostack_validator/celery.py | 26 ++++++++++++----- .../templates/validation_error.html | 29 +++++++++++++++++++ ostack_validator/webui.py | 12 +++++--- 3 files changed, 55 insertions(+), 12 deletions(-) create mode 100644 ostack_validator/templates/validation_error.html diff --git a/ostack_validator/celery.py b/ostack_validator/celery.py index b769026..e5c5357 100644 --- a/ostack_validator/celery.py +++ b/ostack_validator/celery.py @@ -2,6 +2,7 @@ from __future__ import absolute_import import os import time import logging +import traceback from celery import Celery @@ -26,24 +27,33 @@ class InspectionRequest(object): self.private_key = private_key class InspectionResult(object): - def __init__(self, request, openstack): + def __init__(self, request, value): super(InspectionResult, self).__init__() self.request = request - self.openstack = openstack + self.value = value @app.task def ostack_inspect_task(request): + logger = logging.getLogger('ostack_validator.task.inspect') + discovery = OpenstackDiscovery() - openstack = discovery.discover(request.nodes, request.username, private_key=request.private_key) + try: + openstack = discovery.discover(request.nodes, request.username, private_key=request.private_key) + except: + message = traceback.format_exc() + logger.error(message) + return InspectionResult(request, message) all_inspections = [KeystoneAuthtokenSettingsInspection] for inspection in all_inspections: - x = inspection() - x.inspect(openstack) - - # For dramatic effect! =) - time.sleep(2) + try: + x = inspection() + x.inspect(openstack) + except: + message = traceback.format_exc() + logger.error(message) + openstack.report_issue(Issue(Issue.ERROR, 'Unexpected error running inspection "%s". See log for details' % inspection.name)) return InspectionResult(request, openstack) diff --git a/ostack_validator/templates/validation_error.html b/ostack_validator/templates/validation_error.html new file mode 100644 index 0000000..78db8bd --- /dev/null +++ b/ostack_validator/templates/validation_error.html @@ -0,0 +1,29 @@ +{% extends "bootstrap/base.html" %} +{% import "bootstrap/wtf.html" as wtf %} + +{% block title %}OpenStack Validator Result{% endblock %} + +{% block content %} +
+

OpenStack Validation Error

+ +

+ {{ message }} +

+ +
+
+ {{ form.hidden_tag() }} + + {{ wtf.form_field(form.nodes) }} + {{ wtf.form_field(form.username) }} + {{ wtf.form_field(form.private_key) }} +
+ + New inspection +
+ +
+ +{% endblock %} + diff --git a/ostack_validator/webui.py b/ostack_validator/webui.py index bd07486..372bf90 100644 --- a/ostack_validator/webui.py +++ b/ostack_validator/webui.py @@ -8,6 +8,7 @@ from wtforms.validators import DataRequired from ostack_validator.celery import app as celery, ostack_inspect_task, InspectionRequest from ostack_validator.common import Issue, MarkedIssue +from ostack_validator.model import Openstack app = Flask(__name__) Bootstrap(app) @@ -62,12 +63,15 @@ def job(id): form.username.data = r.username form.private_key.data = r.private_key - openstack = job.result.openstack + openstack = job.result.value - issue_source_f = lambda i: i.mark.source if isinstance(i, MarkedIssue) else None - source_groupped_issues = groupby(sorted(openstack.issues, key=issue_source_f), key=issue_source_f) + if isinstance(openstack, Openstack): + issue_source_f = lambda i: i.mark.source if isinstance(i, MarkedIssue) else None + source_groupped_issues = groupby(sorted(openstack.issues, key=issue_source_f), key=issue_source_f) - return render_template('validation_result.html', form=form, openstack=openstack, grouped_issues=source_groupped_issues) + return render_template('validation_result.html', form=form, openstack=openstack, grouped_issues=source_groupped_issues) + else: + return render_template('validation_error.html', form=form, message=openstack) else: return render_template('validation_state.html', state=job.state)