Remove old 'tools diagnosis', superseded by the new diagnosis system

This commit is contained in:
Alexandre Aubin 2019-08-01 22:02:08 +02:00
parent 47c7c72455
commit 94f3557aeb
2 changed files with 3 additions and 195 deletions

View file

@ -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

View file

@ -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