mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge pull request #1217 from YunoHost/app-diagnosis
Add diagnosis section to check that app are in catalog with good quality, check for deprecated practices
This commit is contained in:
commit
c35d25c14d
3 changed files with 90 additions and 4 deletions
76
data/hooks/diagnosis/80-apps.py
Normal file
76
data/hooks/diagnosis/80-apps.py
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from yunohost.app import app_list
|
||||||
|
|
||||||
|
from yunohost.diagnosis import Diagnoser
|
||||||
|
|
||||||
|
class AppDiagnoser(Diagnoser):
|
||||||
|
|
||||||
|
id_ = os.path.splitext(os.path.basename(__file__))[0].split("-")[1]
|
||||||
|
cache_duration = 300
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
|
||||||
|
apps = app_list(full=True)["apps"]
|
||||||
|
for app in apps:
|
||||||
|
app["issues"] = list(self.issues(app))
|
||||||
|
|
||||||
|
if not any(app["issues"] for app in apps):
|
||||||
|
yield dict(
|
||||||
|
meta={"test": "apps"},
|
||||||
|
status="SUCCESS",
|
||||||
|
summary="diagnosis_apps_allgood",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
for app in apps:
|
||||||
|
|
||||||
|
if not app["issues"]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
level = "ERROR" if any(issue[0] == "error" for issue in app["issues"]) else "WARNING"
|
||||||
|
|
||||||
|
yield dict(
|
||||||
|
meta={"test": "apps", "app": app["name"]},
|
||||||
|
status=level,
|
||||||
|
summary="diagnosis_apps_issue",
|
||||||
|
details=[issue[1] for issue in app["issues"]]
|
||||||
|
)
|
||||||
|
|
||||||
|
def issues(self, app):
|
||||||
|
|
||||||
|
# Check quality level in catalog
|
||||||
|
|
||||||
|
if not app.get("from_catalog") or app["from_catalog"].get("state") != "working":
|
||||||
|
yield ("error", "diagnosis_apps_not_in_app_catalog")
|
||||||
|
elif not isinstance(app["from_catalog"].get("level"), int) or app["from_catalog"]["level"] == 0:
|
||||||
|
yield ("error", "diagnosis_apps_broken")
|
||||||
|
elif app["from_catalog"]["level"] <= 4:
|
||||||
|
yield ("warning", "diagnosis_apps_bad_quality")
|
||||||
|
|
||||||
|
# Check for super old, deprecated practices
|
||||||
|
|
||||||
|
yunohost_version_req = app["manifest"].get("requirements", {}).get("yunohost", "").strip(">= ")
|
||||||
|
if yunohost_version_req.startswith("2."):
|
||||||
|
yield ("error", "diagnosis_apps_outdated_ynh_requirement")
|
||||||
|
|
||||||
|
deprecated_helpers = [
|
||||||
|
"yunohost app setting",
|
||||||
|
"yunohost app checkurl",
|
||||||
|
"yunohost app checkport",
|
||||||
|
"yunohost app initdb",
|
||||||
|
"yunohost tools port-available",
|
||||||
|
]
|
||||||
|
for deprecated_helper in deprecated_helpers:
|
||||||
|
if os.system(f"grep -nr -q '{deprecated_helper}' {app['setting_path']}/scripts/") == 0:
|
||||||
|
yield ("error", "diagnosis_apps_deprecated_practices")
|
||||||
|
|
||||||
|
old_arg_regex = r'^domain=\${?[0-9]'
|
||||||
|
if os.system(f"grep -q '{old_arg_regex}' {app['setting_path']}/scripts/install") == 0:
|
||||||
|
yield ("error", "diagnosis_apps_deprecated_practices")
|
||||||
|
|
||||||
|
|
||||||
|
def main(args, env, loggers):
|
||||||
|
return AppDiagnoser(args, env, loggers).diagnose()
|
|
@ -249,6 +249,14 @@
|
||||||
"diagnosis_description_web": "Web",
|
"diagnosis_description_web": "Web",
|
||||||
"diagnosis_description_mail": "Email",
|
"diagnosis_description_mail": "Email",
|
||||||
"diagnosis_description_regenconf": "System configurations",
|
"diagnosis_description_regenconf": "System configurations",
|
||||||
|
"diagnosis_description_apps": "Applications",
|
||||||
|
"diagnosis_apps_allgood": "All installed apps respect basic packaging practices",
|
||||||
|
"diagnosis_apps_issue": "An issue was found for app {app}",
|
||||||
|
"diagnosis_apps_not_in_app_catalog": "This application is not in YunoHost's application catalog. If it was in the past and got removed, you should consider uninstalling this app as it won't receive upgrade, and may compromise the integrity and security of your system.",
|
||||||
|
"diagnosis_apps_broken": "This application is currently flagged as broken on YunoHost's application catalog. This may be a temporary issue while the maintainers attempt to fix the issue. In the meantime, upgrading this app is disabled.",
|
||||||
|
"diagnosis_apps_bad_quality": "This application is currently flagged as broken on YunoHost's application catalog. This may be a temporary issue while the maintainers attempt to fix the issue. In the meantime, upgrading this app is disabled.",
|
||||||
|
"diagnosis_apps_outdated_ynh_requirement": "This app's installed version only requires yunohost >= 2.x, which tends to indicate that it's not up to date with recommended packaging practices and helpers. You should really consider upgrading it.",
|
||||||
|
"diagnosis_apps_deprecated_practices": "This app's installed version still uses some super-old deprecated packaging practices. You should really consider upgrading it.",
|
||||||
"diagnosis_ports_could_not_diagnose": "Could not diagnose if ports are reachable from outside in IPv{ipversion}.",
|
"diagnosis_ports_could_not_diagnose": "Could not diagnose if ports are reachable from outside in IPv{ipversion}.",
|
||||||
"diagnosis_ports_could_not_diagnose_details": "Error: {error}",
|
"diagnosis_ports_could_not_diagnose_details": "Error: {error}",
|
||||||
"diagnosis_ports_unreachable": "Port {port} is not reachable from outside.",
|
"diagnosis_ports_unreachable": "Port {port} is not reachable from outside.",
|
||||||
|
|
|
@ -194,7 +194,8 @@ def app_info(app, full=False):
|
||||||
"app_not_installed", app=app, all_apps=_get_all_installed_apps_id()
|
"app_not_installed", app=app, all_apps=_get_all_installed_apps_id()
|
||||||
)
|
)
|
||||||
|
|
||||||
local_manifest = _get_manifest_of_app(os.path.join(APPS_SETTING_PATH, app))
|
setting_path = os.path.join(APPS_SETTING_PATH, app)
|
||||||
|
local_manifest = _get_manifest_of_app(setting_path)
|
||||||
permissions = user_permission_list(full=True, absolute_urls=True, apps=[app])[
|
permissions = user_permission_list(full=True, absolute_urls=True, apps=[app])[
|
||||||
"permissions"
|
"permissions"
|
||||||
]
|
]
|
||||||
|
@ -213,6 +214,7 @@ def app_info(app, full=False):
|
||||||
if not full:
|
if not full:
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
ret["setting_path"] = setting_path
|
||||||
ret["manifest"] = local_manifest
|
ret["manifest"] = local_manifest
|
||||||
ret["manifest"]["arguments"] = _set_default_ask_questions(
|
ret["manifest"]["arguments"] = _set_default_ask_questions(
|
||||||
ret["manifest"].get("arguments", {})
|
ret["manifest"].get("arguments", {})
|
||||||
|
@ -223,11 +225,11 @@ def app_info(app, full=False):
|
||||||
ret["from_catalog"] = _load_apps_catalog()["apps"].get(absolute_app_name, {})
|
ret["from_catalog"] = _load_apps_catalog()["apps"].get(absolute_app_name, {})
|
||||||
ret["upgradable"] = _app_upgradable(ret)
|
ret["upgradable"] = _app_upgradable(ret)
|
||||||
ret["supports_change_url"] = os.path.exists(
|
ret["supports_change_url"] = os.path.exists(
|
||||||
os.path.join(APPS_SETTING_PATH, app, "scripts", "change_url")
|
os.path.join(setting_path, "scripts", "change_url")
|
||||||
)
|
)
|
||||||
ret["supports_backup_restore"] = os.path.exists(
|
ret["supports_backup_restore"] = os.path.exists(
|
||||||
os.path.join(APPS_SETTING_PATH, app, "scripts", "backup")
|
os.path.join(setting_path, "scripts", "backup")
|
||||||
) and os.path.exists(os.path.join(APPS_SETTING_PATH, app, "scripts", "restore"))
|
) and os.path.exists(os.path.join(setting_path, "scripts", "restore"))
|
||||||
ret["supports_multi_instance"] = is_true(
|
ret["supports_multi_instance"] = is_true(
|
||||||
local_manifest.get("multi_instance", False)
|
local_manifest.get("multi_instance", False)
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Reference in a new issue