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 %}
+
+{% 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 %}