blob: 29fb4687bdc660de7ef608cb6d68bf4e0a27b3e5 [file] [log] [blame]
# -*- coding: utf-8 -*-
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
LOGGER = logging.getLogger(__name__)
from cloud_storage_speedtest import CloudStorageSpeedTest
from disk_info import DiskInfo
from base_container_clone import BaseContainerClone
from repair_base_container import RepairBaseContainer
from diagnostic_error import DiagnosticError
class DiagnosticCheckManager:
"""
Manages access to diagnostic checks. A diagnostic check
is an on demand test that gathers some information
on the system and returns a free-form text response back
to the user. They shouldn't perform any changes to the
system, just gather information.
Diagnostic checks are organized by a category (such as
network, cloud storage, disk), and then specific diagnostics
under those categories (network - speed, disk - free space).
Diagnostic check interface is defined by AbstractDiagnosticCheck,
and any new diagnostics must inherit from this class.
"""
# The list of diagnostic checks to provide
# All checks must inherit from AbstractDiagnosticCheck
CHECKS = [
CloudStorageSpeedTest,
DiskInfo,
BaseContainerClone,
RepairBaseContainer
]
def __init__(self):
self.diagnostic_checks = {}
def init_checks(self):
"""
Creates instances of all the supported checks
"""
for check in self.CHECKS:
self._add_check(check())
def _add_check(self, check):
if check.category not in self.diagnostic_checks:
self.diagnostic_checks[check.category] = {}
self.diagnostic_checks[check.category][check.name] = check
def list_diagnostic_checks(self):
"""
Lists the available diagnostic checks
Return a list of checks organized by category, then check:
[
{
'category': 'category 1',
'checks': [{
'name': 'a test under category 1',
'description': '...'
}]
},
{
'category': 'category 2',
'checks': [{
'name': 'a test under category 2',
'description': '...'
}]
}
]
"""
check_list = []
for category in self.diagnostic_checks:
category_entry = {'category': category}
category_checks = []
for name in self.diagnostic_checks[category]:
description = self.diagnostic_checks[category][name].description
category_checks.append({
'name': name,
'description': description
})
category_entry['checks'] = category_checks
check_list.append(category_entry)
return check_list
def run_diagnostic_check(self, category, name):
"""
Runs the check specified by it's category and name
Args:
category: the category of the check to run
name: the name of the check to run
Return:
A freeform text response containing the results of the diagnostic
Raises:
DiagnosticError if the check is not found, or encounters an error
"""
try:
LOGGER.info('running diagnostic %s %s' % (category, name))
check = self.diagnostic_checks[category][name]
if check is None:
raise DiagnosticError('Check not found')
return check.run()
except KeyError:
raise DiagnosticError('Check not found')
except DiagnosticError as e:
LOGGER.error('failed to run diagnostic check: %s', str(e))
raise e