From 94f3557aeb3c6d2c95728692d59f027a2f7fe793 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 1 Aug 2019 22:02:08 +0200 Subject: [PATCH] Remove old 'tools diagnosis', superseded by the new diagnosis system --- data/actionsmap/yunohost.yml | 10 -- src/yunohost/tools.py | 188 +---------------------------------- 2 files changed, 3 insertions(+), 195 deletions(-) diff --git a/data/actionsmap/yunohost.yml b/data/actionsmap/yunohost.yml index 20eb8a0f8..1c96ce3e8 100644 --- a/data/actionsmap/yunohost.yml +++ b/data/actionsmap/yunohost.yml @@ -1606,16 +1606,6 @@ tools: help: Upgrade only the system packages action: store_true - ### tools_diagnosis() - diagnosis: - action_help: YunoHost diagnosis - api: GET /diagnosis - arguments: - -p: - full: --private - help: Show private data (domain, IP) - action: store_true - ### tools_port_available() port-available: action_help: Check availability of a local port diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index 64689fe0c..034157e3a 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -30,23 +30,19 @@ import json import subprocess import pwd import socket -from xmlrpclib import Fault from importlib import import_module -from collections import OrderedDict from moulinette import msignals, m18n from moulinette.utils.log import getActionLogger from moulinette.utils.process import check_output, call_async_output from moulinette.utils.filesystem import read_json, write_to_json, read_yaml, write_to_yaml -from yunohost.app import app_fetchlist, app_info, app_upgrade, app_ssowatconf, app_list, _install_appslist_fetch_cron +from yunohost.app import app_fetchlist, app_info, app_upgrade, app_ssowatconf, _install_appslist_fetch_cron from yunohost.domain import domain_add, domain_list, _get_maindomain, _set_maindomain from yunohost.dyndns import _dyndns_available, _dyndns_provides from yunohost.firewall import firewall_upnp -from yunohost.service import service_status, service_start, service_enable +from yunohost.service import service_start, service_enable from yunohost.regenconf import regen_conf -from yunohost.monitor import monitor_disk, monitor_system -from yunohost.utils.packages import ynh_packages_version, _dump_sources_list, _list_upgradable_apt_packages -from yunohost.utils.network import get_public_ip +from yunohost.utils.packages import _dump_sources_list, _list_upgradable_apt_packages from yunohost.utils.error import YunohostError from yunohost.log import is_unit_operation, OperationLogger @@ -726,184 +722,6 @@ def tools_upgrade(operation_logger, apps=None, system=False): operation_logger.success() -def tools_diagnosis(private=False): - """ - Return global info about current yunohost instance to help debugging - - """ - diagnosis = OrderedDict() - - # Debian release - try: - with open('/etc/debian_version', 'r') as f: - debian_version = f.read().rstrip() - except IOError as e: - logger.warning(m18n.n('diagnosis_debian_version_error', error=format(e)), exc_info=1) - else: - diagnosis['host'] = "Debian %s" % debian_version - - # Kernel version - try: - with open('/proc/sys/kernel/osrelease', 'r') as f: - kernel_version = f.read().rstrip() - except IOError as e: - logger.warning(m18n.n('diagnosis_kernel_version_error', error=format(e)), exc_info=1) - else: - diagnosis['kernel'] = kernel_version - - # Packages version - diagnosis['packages'] = ynh_packages_version() - - diagnosis["backports"] = check_output("dpkg -l |awk '/^ii/ && $3 ~ /bpo[6-8]/ {print $2}'").split() - - # Server basic monitoring - diagnosis['system'] = OrderedDict() - try: - disks = monitor_disk(units=['filesystem'], human_readable=True) - except (YunohostError, Fault) as e: - logger.warning(m18n.n('diagnosis_monitor_disk_error', error=format(e)), exc_info=1) - else: - diagnosis['system']['disks'] = {} - for disk in disks: - if isinstance(disks[disk], str): - diagnosis['system']['disks'][disk] = disks[disk] - else: - diagnosis['system']['disks'][disk] = 'Mounted on %s, %s (%s free)' % ( - disks[disk]['mnt_point'], - disks[disk]['size'], - disks[disk]['avail'] - ) - - try: - system = monitor_system(units=['cpu', 'memory'], human_readable=True) - except YunohostError as e: - logger.warning(m18n.n('diagnosis_monitor_system_error', error=format(e)), exc_info=1) - else: - diagnosis['system']['memory'] = { - 'ram': '%s (%s free)' % (system['memory']['ram']['total'], system['memory']['ram']['free']), - 'swap': '%s (%s free)' % (system['memory']['swap']['total'], system['memory']['swap']['free']), - } - - # nginx -t - p = subprocess.Popen("nginx -t".split(), - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - out, _ = p.communicate() - diagnosis["nginx"] = out.strip().split("\n") - if p.returncode != 0: - logger.error(out) - - # Services status - services = service_status() - diagnosis['services'] = {} - - for service in services: - diagnosis['services'][service] = "%s (%s)" % (services[service]['status'], services[service]['loaded']) - - # YNH Applications - try: - applications = app_list()['apps'] - except YunohostError as e: - diagnosis['applications'] = m18n.n('diagnosis_no_apps') - else: - diagnosis['applications'] = {} - for application in applications: - if application['installed']: - diagnosis['applications'][application['id']] = application['label'] if application['label'] else application['name'] - - # Private data - if private: - diagnosis['private'] = OrderedDict() - - # Public IP - diagnosis['private']['public_ip'] = {} - diagnosis['private']['public_ip']['IPv4'] = get_public_ip(4) - diagnosis['private']['public_ip']['IPv6'] = get_public_ip(6) - - # Domains - diagnosis['private']['domains'] = domain_list()['domains'] - - diagnosis['private']['regen_conf'] = regen_conf(with_diff=True, dry_run=True) - - try: - diagnosis['security'] = { - "CVE-2017-5754": { - "name": "meltdown", - "vulnerable": _check_if_vulnerable_to_meltdown(), - } - } - except Exception as e: - import traceback - traceback.print_exc() - logger.warning("Unable to check for meltdown vulnerability: %s" % e) - - return diagnosis - - -def _check_if_vulnerable_to_meltdown(): - # meltdown CVE: https://security-tracker.debian.org/tracker/CVE-2017-5754 - - # We use a cache file to avoid re-running the script so many times, - # which can be expensive (up to around 5 seconds on ARM) - # and make the admin appear to be slow (c.f. the calls to diagnosis - # from the webadmin) - # - # The cache is in /tmp and shall disappear upon reboot - # *or* we compare it to dpkg.log modification time - # such that it's re-ran if there was package upgrades - # (e.g. from yunohost) - cache_file = "/tmp/yunohost-meltdown-diagnosis" - dpkg_log = "/var/log/dpkg.log" - if os.path.exists(cache_file): - if not os.path.exists(dpkg_log) or os.path.getmtime(cache_file) > os.path.getmtime(dpkg_log): - logger.debug("Using cached results for meltdown checker, from %s" % cache_file) - return read_json(cache_file)[0]["VULNERABLE"] - - # script taken from https://github.com/speed47/spectre-meltdown-checker - # script commit id is store directly in the script - file_dir = os.path.split(__file__)[0] - SCRIPT_PATH = os.path.join(file_dir, "./vendor/spectre-meltdown-checker/spectre-meltdown-checker.sh") - - # '--variant 3' corresponds to Meltdown - # example output from the script: - # [{"NAME":"MELTDOWN","CVE":"CVE-2017-5754","VULNERABLE":false,"INFOS":"PTI mitigates the vulnerability"}] - try: - logger.debug("Running meltdown vulnerability checker") - call = subprocess.Popen("bash %s --batch json --variant 3" % - SCRIPT_PATH, shell=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - - # TODO / FIXME : here we are ignoring error messages ... - # in particular on RPi2 and other hardware, the script complains about - # "missing some kernel info (see -v), accuracy might be reduced" - # Dunno what to do about that but we probably don't want to harass - # users with this warning ... - output, err = call.communicate() - assert call.returncode in (0, 2, 3), "Return code: %s" % call.returncode - - # If there are multiple lines, sounds like there was some messages - # in stdout that are not json >.> ... Try to get the actual json - # stuff which should be the last line - output = output.strip() - if "\n" in output: - logger.debug("Original meltdown checker output : %s" % output) - output = output.split("\n")[-1] - - CVEs = json.loads(output) - assert len(CVEs) == 1 - assert CVEs[0]["NAME"] == "MELTDOWN" - except Exception as e: - import traceback - traceback.print_exc() - logger.warning("Something wrong happened when trying to diagnose Meltdown vunerability, exception: %s" % e) - raise Exception("Command output for failed meltdown check: '%s'" % output) - - logger.debug("Writing results from meltdown checker to cache file, %s" % cache_file) - write_to_json(cache_file, CVEs) - return CVEs[0]["VULNERABLE"] - - def tools_port_available(port): """ Check availability of a local port