diff --git a/app/services/prepatch_check_service.py b/app/services/prepatch_check_service.py index 1b95699..a5ef72c 100644 --- a/app/services/prepatch_check_service.py +++ b/app/services/prepatch_check_service.py @@ -19,6 +19,7 @@ calcule un verdict global. from __future__ import annotations import logging +import re import socket import time from typing import Callable, Dict, List, Any @@ -30,6 +31,10 @@ log = logging.getLogger("patchcenter.prepatch") # Timeout par commande SSH EXEC_TIMEOUT = 15 +# Seuils espace disque (en Mo) +DISK_MIN_ROOT_MB = 1500 # 1.5 Go sur / +DISK_MIN_VARLOG_MB = 1000 # 1 Go sur /var/log + # Satellites SANEF par zone réseau SATELLITE_LAN = "vpdsiasat2.sanef.groupe" SATELLITE_DMZ = "vpdsiasat1.sanef.groupe" @@ -127,6 +132,65 @@ def check_ssh(ctx: Dict[str, Any]) -> Dict[str, Any]: } +def _disk_avail_mb(client, path: str): + """Renvoie l'espace dispo en Mo sur le FS contenant `path`, ou None si KO.""" + r = _exec(client, f"sudo -n df -BM --output=avail {path} 2>&1 | tail -n +2") + out = (r["stdout"] or "").strip() + m = re.search(r"(\d+)\s*M", out) + if m: + return int(m.group(1)) + return None + + +def check_disk(ctx: Dict[str, Any]) -> Dict[str, Any]: + """Vérifie l'espace disque dispo : + - / >= 1.5 Go + - /var/log >= 1 Go + KO si insuffisant → pas éligible au snapshot. + """ + client = ctx.get("client") + if client is None: + return { + "name": "disk", + "label": f"Espace disque (/ ≥ {DISK_MIN_ROOT_MB}M, /var/log ≥ {DISK_MIN_VARLOG_MB}M)", + "status": "ko", + "message": "SSH KO en amont", + "details": "", + } + root_mb = _disk_avail_mb(client, "/") + var_mb = _disk_avail_mb(client, "/var/log") + issues = [] + parts = [] + if root_mb is None: + issues.append("/ : mesure impossible") + else: + parts.append(f"/ {root_mb}M") + if root_mb < DISK_MIN_ROOT_MB: + issues.append(f"/ {root_mb}M < min {DISK_MIN_ROOT_MB}M") + if var_mb is None: + issues.append("/var/log : mesure impossible") + else: + parts.append(f"/var/log {var_mb}M") + if var_mb < DISK_MIN_VARLOG_MB: + issues.append(f"/var/log {var_mb}M < min {DISK_MIN_VARLOG_MB}M") + label = f"Espace disque (/ ≥ {DISK_MIN_ROOT_MB}M, /var/log ≥ {DISK_MIN_VARLOG_MB}M)" + details = ( + f"$ sudo df -BM --output=avail / → {root_mb if root_mb is not None else 'N/A'}M\n" + f"$ sudo df -BM --output=avail /var/log → {var_mb if var_mb is not None else 'N/A'}M" + ) + if issues: + return { + "name": "disk", "label": label, "status": "ko", + "message": " · ".join(issues), + "details": details, + } + return { + "name": "disk", "label": label, "status": "ok", + "message": " · ".join(parts) + " (au-dessus seuils)", + "details": details, + } + + def check_satellite(ctx: Dict[str, Any]) -> Dict[str, Any]: """Vérifie : 1. la joignabilité du Satellite cible (LAN ou DMZ selon Domaine) @@ -154,8 +218,11 @@ def check_satellite(ctx: Dict[str, Any]) -> Dict[str, Any]: sat_reachable = http_code in ("200", "301", "302", "403") # 2) subscription-manager identity + # Locale-indépendant : on cherche un UUID dans la sortie (présent en EN comme en FR). r1 = _exec(client, "sudo -n subscription-manager identity 2>&1") - sub_ok = (r1["rc"] == 0 and "system identity" in r1["stdout"].lower()) + sub_ok = (r1["rc"] == 0 and bool(re.search( + r"\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b", + r1["stdout"], re.IGNORECASE))) # 3) yum repolist enabled --quiet r2 = _exec(client, "sudo -n yum repolist enabled --quiet 2>&1 | head -50") @@ -205,6 +272,7 @@ def check_satellite(ctx: Dict[str, Any]) -> Dict[str, Any]: CHECKS: Dict[str, Callable[[Dict[str, Any]], Dict[str, Any]]] = { "dns": check_dns, "ssh": check_ssh, + "disk": check_disk, "satellite": check_satellite, } diff --git a/app/templates/patching_iexec.html b/app/templates/patching_iexec.html index 9db36d8..09dc92a 100644 --- a/app/templates/patching_iexec.html +++ b/app/templates/patching_iexec.html @@ -46,6 +46,7 @@