mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-02-04 08:13:38 +00:00
- When running full diagnostics manually, we can use the Operation class. This allows us to use many of its features. - Ensure only one task is running at any time. No need to use running_task global variable and a lock for it. - Don't run the operation if app install/uninstall or other potentially contentious tasks are running. - Since Operation object creates a thread, don't create another one with glib.schedule(). Don't wait unnecessarily for the operation to finish in the glib thread (or glib created thread). - Since the app will show progress of operations when an operation is running, it would not be possible to show progress of diagnostics running. So, create a separate page for diagnostics results. Tests: - Run diagnostics and see redirection happens to diagnostics results page. Results page shows ongoing tests. It refreshes automatically. When tests are completed, 'Re-run diagnostics' button is shown. - When visiting /diagnostics/full/ URL is visited without running the test. Only the re-run button is shown. No results are shown. If tests have been run, re-run button along with results are shown. - On the app page, if the tests have been run, a button for viewing results is shown. Otherwise, the button is not shown. - In development mode, background diagnostics are run after 3 minutes (change the time to 150 seconds if database locked errors show up). Results are available in the results page. - Make a diagnostic test fail by changing code or disabling a daemon. Run diagnostics and notice that a notification is shown with the button to go to the results. Clicking on the button shows the results page. Clicking dismiss removes the notification. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
97 lines
2.8 KiB
Python
97 lines
2.8 KiB
Python
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
"""
|
|
FreedomBox app for running diagnostics.
|
|
"""
|
|
|
|
import logging
|
|
|
|
from django.http import Http404, HttpResponseRedirect
|
|
from django.template.response import TemplateResponse
|
|
from django.urls import reverse
|
|
from django.utils.translation import gettext_lazy as _
|
|
from django.views.decorators.http import require_POST
|
|
from django.views.generic import TemplateView
|
|
|
|
from plinth import operation
|
|
from plinth.app import App
|
|
from plinth.modules import diagnostics
|
|
from plinth.views import AppView
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class DiagnosticsView(AppView):
|
|
"""Diagnostics app page."""
|
|
|
|
app_id = 'diagnostics'
|
|
template_name = 'diagnostics.html'
|
|
|
|
def post(self, request):
|
|
"""Start diagnostics."""
|
|
diagnostics.start_diagnostics()
|
|
return HttpResponseRedirect(reverse('diagnostics:index'))
|
|
|
|
def get_context_data(self, **kwargs):
|
|
"""Return additional context for rendering the template."""
|
|
with diagnostics.results_lock:
|
|
results = diagnostics.current_results
|
|
|
|
context = super().get_context_data(**kwargs)
|
|
context['has_diagnostics'] = False
|
|
context['results'] = results
|
|
return context
|
|
|
|
|
|
class DiagnosticsFullView(TemplateView):
|
|
"""View to run full diagnostics."""
|
|
|
|
template_name = 'diagnostics_full.html'
|
|
|
|
def post(self, request):
|
|
"""Start diagnostics."""
|
|
diagnostics.start_diagnostics()
|
|
return self.get(self, request)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
"""Return additional context for rendering the template."""
|
|
try:
|
|
is_task_running = bool(operation.manager.get('diagnostics-full'))
|
|
except KeyError:
|
|
is_task_running = False
|
|
|
|
with diagnostics.results_lock:
|
|
results = diagnostics.current_results
|
|
|
|
context = super().get_context_data(**kwargs)
|
|
context['is_task_running'] = is_task_running
|
|
context['results'] = results
|
|
context['refresh_page_sec'] = 3 if is_task_running else None
|
|
return context
|
|
|
|
|
|
@require_POST
|
|
def diagnose_app(request, app_id):
|
|
"""Return diagnostics for a particular app."""
|
|
try:
|
|
app = App.get(app_id)
|
|
except KeyError:
|
|
raise Http404('App does not exist')
|
|
app_name = app.info.name or app_id
|
|
|
|
diagnosis = None
|
|
diagnosis_exception = None
|
|
try:
|
|
diagnosis = app.diagnose()
|
|
except Exception as exception:
|
|
logger.exception('Error running %s diagnostics - %s', app_id,
|
|
exception)
|
|
diagnosis_exception = str(exception)
|
|
|
|
return TemplateResponse(
|
|
request, 'diagnostics_app.html', {
|
|
'title': _('Diagnostic Test'),
|
|
'app_name': app_name,
|
|
'results': diagnosis,
|
|
'exception': diagnosis_exception,
|
|
})
|