mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Add some bits of magic to simplify the way we yield test items
This commit is contained in:
parent
587a07a6e6
commit
3cff370c62
11 changed files with 94 additions and 77 deletions
|
@ -23,55 +23,48 @@ class BaseSystemDiagnoser(Diagnoser):
|
|||
hardware = dict(meta={"test": "hardware"},
|
||||
status="INFO",
|
||||
data={"virt": virt, "arch": arch},
|
||||
summary=("diagnosis_basesystem_hardware", {"virt": virt, "arch": arch}))
|
||||
summary="diagnosis_basesystem_hardware")
|
||||
if os.path.exists("/proc/device-tree/model"):
|
||||
model = read_file('/proc/device-tree/model').strip()
|
||||
hardware["data"]["board"] = model
|
||||
hardware["details"] = [("diagnosis_basesystem_hardware_board", {"model": model})]
|
||||
hardware["data"]["model"] = model
|
||||
hardware["details"] = ["diagnosis_basesystem_hardware_board"]
|
||||
|
||||
yield hardware
|
||||
|
||||
# Kernel version
|
||||
kernel_version = read_file('/proc/sys/kernel/osrelease').strip()
|
||||
yield dict(meta={"test": "kernel"},
|
||||
data={"kernel_version": kernel_version},
|
||||
status="INFO",
|
||||
summary=("diagnosis_basesystem_kernel", {"kernel_version": kernel_version}))
|
||||
summary="diagnosis_basesystem_kernel")
|
||||
|
||||
# Debian release
|
||||
debian_version = read_file("/etc/debian_version").strip()
|
||||
yield dict(meta={"test": "host"},
|
||||
data={"debian_version": debian_version},
|
||||
status="INFO",
|
||||
summary=("diagnosis_basesystem_host", {"debian_version": debian_version}))
|
||||
summary="diagnosis_basesystem_host")
|
||||
|
||||
# Yunohost packages versions
|
||||
ynh_packages = ynh_packages_version()
|
||||
# We check if versions are consistent (e.g. all 3.6 and not 3 packages with 3.6 and the other with 3.5)
|
||||
# This is a classical issue for upgrades that failed in the middle
|
||||
# (or people upgrading half of the package because they did 'apt upgrade' instead of 'dist-upgrade')
|
||||
# Here, ynh_core_version is for example "3.5.4.12", so [:3] is "3.5" and we check it's the same for all packages
|
||||
ynh_packages = ynh_packages_version()
|
||||
ynh_core_version = ynh_packages["yunohost"]["version"]
|
||||
consistent_versions = all(infos["version"][:3] == ynh_core_version[:3] for infos in ynh_packages.values())
|
||||
ynh_version_details = [("diagnosis_basesystem_ynh_single_version",
|
||||
{"package":package,
|
||||
"version": infos["version"],
|
||||
"repo": infos["repo"]}
|
||||
)
|
||||
for package, infos in ynh_packages.items()]
|
||||
)
|
||||
for package, infos in ynh_packages.items()]
|
||||
|
||||
if consistent_versions:
|
||||
yield dict(meta={"test": "ynh_versions"},
|
||||
data={"main_version": ynh_core_version, "repo": ynh_packages["yunohost"]["repo"]},
|
||||
status="INFO",
|
||||
summary=("diagnosis_basesystem_ynh_main_version",
|
||||
{"main_version": ynh_core_version,
|
||||
"repo": ynh_packages["yunohost"]["repo"]}),
|
||||
details=ynh_version_details)
|
||||
else:
|
||||
yield dict(meta={"test": "ynh_versions"},
|
||||
data={"main_version": ynh_core_version, "repo": ynh_packages["yunohost"]["repo"]},
|
||||
status="ERROR",
|
||||
summary=("diagnosis_basesystem_ynh_inconsistent_versions", {}),
|
||||
details=ynh_version_details)
|
||||
yield dict(meta={"test": "ynh_versions"},
|
||||
data={"main_version": ynh_core_version, "repo": ynh_packages["yunohost"]["repo"]},
|
||||
status="INFO" if consistent_versions else "ERROR",
|
||||
summary="diagnosis_basesystem_ynh_main_version" if consistent_versions else "diagnosis_basesystem_ynh_inconsistent_versions",
|
||||
details=ynh_version_details)
|
||||
|
||||
|
||||
def main(args, env, loggers):
|
||||
|
|
|
@ -28,7 +28,7 @@ class IPDiagnoser(Diagnoser):
|
|||
if not can_ping_ipv4 and not can_ping_ipv6:
|
||||
yield dict(meta={"test": "ping"},
|
||||
status="ERROR",
|
||||
summary=("diagnosis_ip_not_connected_at_all", {}))
|
||||
summary="diagnosis_ip_not_connected_at_all")
|
||||
# Not much else we can do if there's no internet at all
|
||||
return
|
||||
|
||||
|
@ -49,20 +49,19 @@ class IPDiagnoser(Diagnoser):
|
|||
if not can_resolve_dns:
|
||||
yield dict(meta={"test": "dnsresolv"},
|
||||
status="ERROR",
|
||||
summary=("diagnosis_ip_broken_dnsresolution", {}) if good_resolvconf
|
||||
else ("diagnosis_ip_broken_resolvconf", {}))
|
||||
summary="diagnosis_ip_broken_dnsresolution" if good_resolvconf else "diagnosis_ip_broken_resolvconf")
|
||||
return
|
||||
# Otherwise, if the resolv conf is bad but we were able to resolve domain name,
|
||||
# still warn that we're using a weird resolv conf ...
|
||||
elif not good_resolvconf:
|
||||
yield dict(meta={"test": "dnsresolv"},
|
||||
status="WARNING",
|
||||
summary=("diagnosis_ip_weird_resolvconf", {}),
|
||||
details=[("diagnosis_ip_weird_resolvconf_details", {})])
|
||||
summary="diagnosis_ip_weird_resolvconf",
|
||||
details=["diagnosis_ip_weird_resolvconf_details"])
|
||||
else:
|
||||
yield dict(meta={"test": "dnsresolv"},
|
||||
status="SUCCESS",
|
||||
summary=("diagnosis_ip_dnsresolution_working", {}))
|
||||
summary="diagnosis_ip_dnsresolution_working")
|
||||
|
||||
# ##################################################### #
|
||||
# IP DIAGNOSIS : Check that we're actually able to talk #
|
||||
|
@ -72,17 +71,16 @@ class IPDiagnoser(Diagnoser):
|
|||
ipv4 = self.get_public_ip(4) if can_ping_ipv4 else None
|
||||
ipv6 = self.get_public_ip(6) if can_ping_ipv6 else None
|
||||
|
||||
yield dict(meta={"test": "ip", "version": '4'},
|
||||
data=ipv4,
|
||||
yield dict(meta={"test": "ipv4"},
|
||||
data={"global": ipv4},
|
||||
status="SUCCESS" if ipv4 else "ERROR",
|
||||
summary=("diagnosis_ip_connected_ipv4", {}) if ipv4
|
||||
else ("diagnosis_ip_no_ipv4", {}))
|
||||
summary="diagnosis_ip_connected_ipv4" if ipv4 else "diagnosis_ip_no_ipv4")
|
||||
|
||||
yield dict(meta={"test": "ip", "version": '6'},
|
||||
data=ipv6,
|
||||
yield dict(meta={"test": "ipv6"},
|
||||
data={"global": ipv6},
|
||||
status="SUCCESS" if ipv6 else "WARNING",
|
||||
summary=("diagnosis_ip_connected_ipv6", {}) if ipv6
|
||||
else ("diagnosis_ip_no_ipv6", {}))
|
||||
summary="diagnosis_ip_connected_ipv6" if ipv6 else "diagnosis_ip_no_ipv6")
|
||||
|
||||
|
||||
# TODO / FIXME : add some attempt to detect ISP (using whois ?) ?
|
||||
|
||||
|
|
|
@ -62,19 +62,18 @@ class DNSRecordsDiagnoser(Diagnoser):
|
|||
discrepancies.append(("diagnosis_dns_discrepancy", r))
|
||||
|
||||
if discrepancies:
|
||||
discrepancies = [("diagnosis_dns_point_to_doc", {})] + discrepancies
|
||||
status = "ERROR" if (category == "basic" or (is_main_domain and category != "extra")) else "WARNING"
|
||||
summary = ("diagnosis_dns_bad_conf", {"domain": domain, "category": category})
|
||||
summary = "diagnosis_dns_bad_conf"
|
||||
else:
|
||||
status = "SUCCESS"
|
||||
summary = ("diagnosis_dns_good_conf", {"domain": domain, "category": category})
|
||||
summary = "diagnosis_dns_good_conf"
|
||||
|
||||
output = dict(meta={"domain": domain, "category": category},
|
||||
status=status,
|
||||
summary=summary)
|
||||
|
||||
if discrepancies:
|
||||
output["details"] = discrepancies
|
||||
output["details"] = ["diagnosis_dns_point_to_doc"] + discrepancies
|
||||
|
||||
yield output
|
||||
|
||||
|
|
|
@ -47,15 +47,16 @@ class PortsDiagnoser(Diagnoser):
|
|||
category = services[service].get("category", "[?]")
|
||||
if r["ports"].get(str(port), None) is not True:
|
||||
yield dict(meta={"port": str(port)},
|
||||
data={"service": service, "category": category},
|
||||
status="ERROR",
|
||||
summary=("diagnosis_ports_unreachable", {"port": port}),
|
||||
details=[("diagnosis_ports_needed_by", {"service": service, "category": category}),
|
||||
("diagnosis_ports_forwarding_tip", {})])
|
||||
summary="diagnosis_ports_unreachable",
|
||||
details=["diagnosis_ports_needed_by", "diagnosis_ports_forwarding_tip"])
|
||||
else:
|
||||
yield dict(meta={"port": str(port)},
|
||||
data={"service": service, "category": category},
|
||||
status="SUCCESS",
|
||||
summary=("diagnosis_ports_ok", {"port": port}),
|
||||
details=[("diagnosis_ports_needed_by", {"service": service, "category": category})])
|
||||
summary="diagnosis_ports_ok",
|
||||
details=["diagnosis_ports_needed_by"])
|
||||
|
||||
|
||||
def main(args, env, loggers):
|
||||
|
|
|
@ -45,13 +45,13 @@ class WebDiagnoser(Diagnoser):
|
|||
if r["status"] == "ok":
|
||||
yield dict(meta={"domain": domain},
|
||||
status="SUCCESS",
|
||||
summary=("diagnosis_http_ok", {"domain": domain}))
|
||||
summary="diagnosis_http_ok")
|
||||
else:
|
||||
detail = r["code"].replace("error_http_check", "diagnosis_http") if "code" in r else "diagnosis_http_unknown_error"
|
||||
yield dict(meta={"domain": domain},
|
||||
status="ERROR",
|
||||
summary=("diagnosis_http_unreachable", {"domain": domain}),
|
||||
details=[(detail,{})])
|
||||
summary="diagnosis_http_unreachable",
|
||||
details=[detail])
|
||||
|
||||
# In there or idk where else ...
|
||||
# try to diagnose hairpinning situation by crafting a request for the
|
||||
|
|
|
@ -17,11 +17,11 @@ class MailDiagnoser(Diagnoser):
|
|||
if os.system('/bin/nc -z -w2 yunohost.org 25') == 0:
|
||||
yield dict(meta={"test": "ougoing_port_25"},
|
||||
status="SUCCESS",
|
||||
summary=("diagnosis_mail_ougoing_port_25_ok",{}))
|
||||
summary="diagnosis_mail_ougoing_port_25_ok")
|
||||
else:
|
||||
yield dict(meta={"test": "outgoing_port_25"},
|
||||
status="ERROR",
|
||||
summary=("diagnosis_mail_ougoing_port_25_blocked",{}))
|
||||
summary="diagnosis_mail_ougoing_port_25_blocked")
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -17,21 +17,22 @@ class ServicesDiagnoser(Diagnoser):
|
|||
|
||||
for service, result in sorted(all_result.items()):
|
||||
|
||||
item = dict(meta={"service": service})
|
||||
item = dict(meta={"service": service},
|
||||
data={"status": result["status"], "configuration": result["configuration"]})
|
||||
|
||||
if result["status"] != "running":
|
||||
item["status"] = "ERROR"
|
||||
item["summary"] = ("diagnosis_services_bad_status", {"service": service, "status": result["status"]})
|
||||
item["details"] = [("diagnosis_services_bad_status_tip", {"service":service})]
|
||||
item["summary"] = "diagnosis_services_bad_status"
|
||||
item["details"] = ["diagnosis_services_bad_status_tip"]
|
||||
|
||||
elif result["configuration"] == "broken":
|
||||
item["status"] = "WARNING"
|
||||
item["summary"] = ("diagnosis_services_conf_broken", {"service": service})
|
||||
item["details"] = [(d, {}) for d in result["configuration-details"]]
|
||||
item["summary"] = "diagnosis_services_conf_broken"
|
||||
item["details"] = result["configuration-details"]
|
||||
|
||||
else:
|
||||
item["status"] = "SUCCESS"
|
||||
item["summary"] = ("diagnosis_services_running", {"service": service, "status": result["status"]})
|
||||
item["summary"] = "diagnosis_services_running"
|
||||
|
||||
yield item
|
||||
|
||||
|
|
|
@ -20,17 +20,19 @@ class SystemResourcesDiagnoser(Diagnoser):
|
|||
ram_total_abs_MB = ram.total / (1024**2)
|
||||
ram_available_abs_MB = ram.available / (1024**2)
|
||||
ram_available_percent = round(100 * ram.available / ram.total)
|
||||
item = dict(meta={"test": "ram"})
|
||||
infos = {"total_abs_MB": ram_total_abs_MB, "available_abs_MB": ram_available_abs_MB, "available_percent": ram_available_percent}
|
||||
item = dict(meta={"test": "ram"},
|
||||
data={"total_abs_MB": ram_total_abs_MB,
|
||||
"available_abs_MB": ram_available_abs_MB,
|
||||
"available_percent": ram_available_percent})
|
||||
if ram_available_abs_MB < 100 or ram_available_percent < 5:
|
||||
item["status"] = "ERROR"
|
||||
item["summary"] = ("diagnosis_ram_verylow", infos)
|
||||
item["summary"] = "diagnosis_ram_verylow"
|
||||
elif ram_available_abs_MB < 200 or ram_available_percent < 10:
|
||||
item["status"] = "WARNING"
|
||||
item["summary"] = ("diagnosis_ram_low", infos)
|
||||
item["summary"] = "diagnosis_ram_low"
|
||||
else:
|
||||
item["status"] = "SUCCESS"
|
||||
item["summary"] = ("diagnosis_ram_ok", infos)
|
||||
item["summary"] = "diagnosis_ram_ok"
|
||||
yield item
|
||||
|
||||
#
|
||||
|
@ -39,19 +41,21 @@ class SystemResourcesDiagnoser(Diagnoser):
|
|||
|
||||
swap = psutil.swap_memory()
|
||||
swap_total_abs_MB = swap.total / (1024*1024)
|
||||
item = dict(meta={"test": "swap"})
|
||||
infos = {"total_MB": swap_total_abs_MB}
|
||||
item = dict(meta={"test": "swap"},
|
||||
data={"total_MB": swap_total_abs_MB})
|
||||
if swap_total_abs_MB <= 0:
|
||||
item["status"] = "ERROR"
|
||||
item["summary"] = ("diagnosis_swap_none", infos)
|
||||
item["summary"] = "diagnosis_swap_none"
|
||||
elif swap_total_abs_MB <= 256:
|
||||
item["status"] = "WARNING"
|
||||
item["summary"] = ("diagnosis_swap_notsomuch", infos)
|
||||
item["summary"] = "diagnosis_swap_notsomuch"
|
||||
else:
|
||||
item["status"] = "SUCCESS"
|
||||
item["summary"] = ("diagnosis_swap_ok", infos)
|
||||
item["summary"] = "diagnosis_swap_ok"
|
||||
yield item
|
||||
|
||||
# FIXME : add a check that swapiness is low if swap is on a sdcard...
|
||||
|
||||
#
|
||||
# Disks usage
|
||||
#
|
||||
|
@ -66,17 +70,17 @@ class SystemResourcesDiagnoser(Diagnoser):
|
|||
free_abs_GB = usage.free / (1024 ** 3)
|
||||
free_percent = 100 - usage.percent
|
||||
|
||||
item = dict(meta={"test": "diskusage", "mountpoint": mountpoint})
|
||||
infos = {"mountpoint": mountpoint, "device": device, "free_abs_GB": free_abs_GB, "free_percent": free_percent}
|
||||
item = dict(meta={"test": "diskusage", "mountpoint": mountpoint},
|
||||
data={"device": device, "free_abs_GB": free_abs_GB, "free_percent": free_percent})
|
||||
if free_abs_GB < 1 or free_percent < 5:
|
||||
item["status"] = "ERROR"
|
||||
item["summary"] = ("diagnosis_diskusage_verylow", infos)
|
||||
item["summary"] = "diagnosis_diskusage_verylow"
|
||||
elif free_abs_GB < 2 or free_percent < 10:
|
||||
item["status"] = "WARNING"
|
||||
item["summary"] = ("diagnosis_diskusage_low", infos)
|
||||
item["summary"] = "diagnosis_diskusage_low"
|
||||
else:
|
||||
item["status"] = "SUCCESS"
|
||||
item["summary"] = ("diagnosis_diskusage_ok", infos)
|
||||
item["summary"] = "diagnosis_diskusage_ok"
|
||||
|
||||
yield item
|
||||
|
||||
|
|
|
@ -22,14 +22,14 @@ class RegenconfDiagnoser(Diagnoser):
|
|||
if regenconf_modified_files == []:
|
||||
yield dict(meta={"test": "regenconf"},
|
||||
status="SUCCESS",
|
||||
summary=("diagnosis_regenconf_allgood", {})
|
||||
summary="diagnosis_regenconf_allgood"
|
||||
)
|
||||
else:
|
||||
for f in regenconf_modified_files:
|
||||
yield dict(meta={"test": "regenconf", "file": f},
|
||||
status="WARNING",
|
||||
summary=("diagnosis_regenconf_manually_modified", {"file": f}),
|
||||
details=[("diagnosis_regenconf_manually_modified_details", {})]
|
||||
summary="diagnosis_regenconf_manually_modified",
|
||||
details=["diagnosis_regenconf_manually_modified_details"]
|
||||
)
|
||||
|
||||
#for f in debian_modified_files:
|
||||
|
|
|
@ -21,13 +21,13 @@ class SecurityDiagnoser(Diagnoser):
|
|||
if self.is_vulnerable_to_meltdown():
|
||||
yield dict(meta={"test": "meltdown"},
|
||||
status="ERROR",
|
||||
summary=("diagnosis_security_vulnerable_to_meltdown", {}),
|
||||
details=[("diagnosis_security_vulnerable_to_meltdown_details", {})]
|
||||
summary="diagnosis_security_vulnerable_to_meltdown",
|
||||
details=["diagnosis_security_vulnerable_to_meltdown_details"]
|
||||
)
|
||||
else:
|
||||
yield dict(meta={},
|
||||
status="SUCCESS",
|
||||
summary=("diagnosis_security_all_good", {})
|
||||
summary="diagnosis_security_all_good"
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -453,11 +453,32 @@ class Diagnoser():
|
|||
|
||||
report["description"] = Diagnoser.get_description(report["id"])
|
||||
|
||||
def is_tuple_or_list(stuff):
|
||||
return isinstance(stuff, tuple) or isinstance(stuff, list)
|
||||
|
||||
for item in report["items"]:
|
||||
|
||||
# For the summary and each details, we want to call
|
||||
# m18n() on the string, with the appropriate data for string
|
||||
# formatting which can come from :
|
||||
# - infos super-specific to the summary/details (if it's a tuple(key,dict_with_info) and not just a string)
|
||||
# - 'meta' info = parameters of the test (e.g. which domain/category for DNS conf record)
|
||||
# - actual 'data' retrieved from the test (e.g. actual global IP, ...)
|
||||
|
||||
meta_data = item.get("meta", {}).copy()
|
||||
meta_data.update(item.get("data", {}))
|
||||
|
||||
if not is_tuple_or_list(item["summary"]):
|
||||
item["summary"] = (item["summary"], {})
|
||||
summary_key, summary_args = item["summary"]
|
||||
summary_args.update(meta_data)
|
||||
|
||||
item["summary"] = m18n.n(summary_key, **summary_args)
|
||||
|
||||
if "details" in item:
|
||||
item["details"] = [(d[0], d[1]) if is_tuple_or_list(d) else (d, {}) for d in item["details"]]
|
||||
for d in item["details"]:
|
||||
d[1].update(meta_data)
|
||||
item["details"] = [m18n.n(key, **values) for key, values in item["details"]]
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue