diff --git a/actions/diagnostic-test b/actions/diagnostic-test deleted file mode 100755 index 44a3ee641..000000000 --- a/actions/diagnostic-test +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -# -# This file is part of Plinth. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# - -/usr/lib/freedombox/testsuite/check diff --git a/plinth/modules/diagnostics/diagnostics.py b/plinth/modules/diagnostics/diagnostics.py index ab9f8b303..0f039cc1f 100644 --- a/plinth/modules/diagnostics/diagnostics.py +++ b/plinth/modules/diagnostics/diagnostics.py @@ -19,15 +19,24 @@ Plinth module for running diagnostics """ +import collections from django.http import Http404 from django.template.response import TemplateResponse +from django.views.decorators.http import require_POST from gettext import gettext as _ import importlib +import logging +import threading -from plinth import actions from plinth import cfg from plinth import module_loader -from plinth.errors import ActionError + + +logger = logging.Logger(__name__) + +current_results = {} + +_running_task = None def init(): @@ -39,26 +48,16 @@ def init(): def index(request): """Serve the index page""" + if request.method == 'POST' and not _running_task: + _start_task() + return TemplateResponse(request, 'diagnostics.html', - {'title': _('System Diagnostics')}) + {'title': _('System Diagnostics'), + 'is_running': _running_task is not None, + 'results': current_results}) -def test(request): - """Run diagnostics and the output page""" - output = '' - error = '' - try: - output = actions.superuser_run("diagnostic-test") - except ActionError as exception: - output, error = exception.args[1:] - except Exception as exception: - error = str(exception) - - return TemplateResponse(request, 'diagnostics_test.html', - {'title': _('Diagnostic Test'), - 'diagnostics_output': output, - 'diagnostics_error': error}) - +@require_POST def module(request, module_name): """Return diagnostics for a particular module.""" found = False @@ -79,3 +78,49 @@ def module(request, module_name): {'title': _('Diagnostic Test'), 'module_name': module_name, 'results': results}) + + +def _start_task(): + """Start the run task in a separate thread.""" + if _running_task: + raise Exception('Task already running') + + global _running_task + _running_task = threading.Thread(target=_run_on_all_modules_wrapper) + _running_task.start() + + +def _run_on_all_modules_wrapper(): + """Wrapper over actual task to catch exceptions.""" + try: + run_on_all_modules() + except Exception as exception: + logger.exception('Error running diagnostics - %s', exception) + current_results['error'] = str(exception) + + global _running_task + _running_task = None + + +def run_on_all_modules(): + """Run diagnostics on all modules and store the result.""" + global current_results + current_results = {'modules': [], + 'results': collections.OrderedDict(), + 'progress_percentage': 0} + + modules = [] + for module_import_path in module_loader.loaded_modules: + loaded_module = importlib.import_module(module_import_path) + if not hasattr(loaded_module, 'diagnose'): + continue + + module_name = module_import_path.split('.')[-1] + modules.append((module_name, loaded_module)) + current_results['results'][module_name] = None + + current_results['modules'] = modules + for current_index, (module_name, loaded_module) in enumerate(modules): + current_results['results'][module_name] = loaded_module.diagnose() + current_results['progress_percentage'] = \ + int((current_index + 1) * 100 / len(modules)) diff --git a/plinth/modules/diagnostics/templates/diagnostics.html b/plinth/modules/diagnostics/templates/diagnostics.html index 9a2fbbd17..afb63254c 100644 --- a/plinth/modules/diagnostics/templates/diagnostics.html +++ b/plinth/modules/diagnostics/templates/diagnostics.html @@ -18,16 +18,61 @@ # {% endcomment %} + +{% block page_head %} + + {% if is_running %} + + {% endif %} + +{% endblock %} + + {% block content %}

{{ title }}

The system diagnostic test will run a number of checks on your -system to confirm that network services are running and configured -properly. It may take a minute to complete.

+system to confirm that applications and services are working as expected.

-

- Run diagnostic test » -

+{% if not is_running %} +
+ {% csrf_token %} + + +
+{% else %} +

Diagnotics test is currently running

+
+
+ {{ results.progress_percentage }}% +
+
+ +{% endif %} + +{% if results %} +

Results

+ {% if results.error %} +
+ × + {{ results.error }} +
+ {% else %} + {% for module, module_results in results.results.items %} +

Module: {{ module }}

+ + {% if module_results %} + {% include "diagnostics_results.html" with results=module_results %} + {% else %} +

+ {% endif %} + {% endfor %} + {% endif %} +{% endif %} {% endblock %} diff --git a/plinth/modules/diagnostics/templates/diagnostics_test.html b/plinth/modules/diagnostics/templates/diagnostics_test.html deleted file mode 100644 index d5a345e10..000000000 --- a/plinth/modules/diagnostics/templates/diagnostics_test.html +++ /dev/null @@ -1,35 +0,0 @@ -{% extends 'base.html' %} -{% comment %} -# -# This file is part of Plinth. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -{% endcomment %} - -{% block content %} - -

{{title}}

- -{% if diagnostics_error %} -

The diagnostic test encountered an error:

-

{{ diagnostics_error }}
-{% endif %} - -{% if diagnostics_output %} -

Output of diagnostic test:

-
{{ diagnostics_output }}
-{% endif %} - -{% endblock %}