mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-01 10:22:08 +00:00
Let dismissed remote mount warnings clear the health status
This commit is contained in:
@@ -1738,16 +1738,16 @@
|
||||
"portCustomUrlPlaceholder": "Benutzerdefinierte URL (z. B. https://vault.example.com) überschreibt IP:port",
|
||||
"stackMemberTitle": "Teil einer Multi-Container-Anwendung",
|
||||
"stackMemberBody": "Dieser Container gehört zu einer Anwendung, deren Hauptcontainer {primary} ist. Die Anwendung, ihre Weblinks und ihre Version werden dort angezeigt.",
|
||||
"nativeEvidencePort": "Überwachung des TCP-Ports",
|
||||
"nativeEvidencePort": "Lauschender TCP-Port",
|
||||
"nativeEvidenceFile": "Installierte Datei",
|
||||
"nativeEvidenceProcess": "Ausführbare Datei ausführen",
|
||||
"nativeEvidenceProcess": "Laufende ausführbare Datei",
|
||||
"nativeEvidenceDirectory": "Arbeitsverzeichnis",
|
||||
"nativeEvidenceService": "Dienstdefinition",
|
||||
"nativeScanFailed": "Die Anwendungssuche konnte nicht abgeschlossen werden.Frühere Beweise könnten veraltet sein;versuchen Sie es erneut.",
|
||||
"nativeScanPartial": "Die Anwendungssuche ist unvollständig.Überprüfen Sie die verfügbaren Beweise und versuchen Sie es erneut.",
|
||||
"nativeScanFailed": "Die Anwendungssuche konnte nicht abgeschlossen werden. Frühere Ergebnisse sind möglicherweise veraltet; versuchen Sie es erneut.",
|
||||
"nativeScanPartial": "Die Anwendungssuche ist unvollständig. Prüfen Sie die gefundenen Hinweise und versuchen Sie es erneut.",
|
||||
"nativeVersionUnknown": "Installierte Version unbekannt",
|
||||
"nativeEvidenceStale": "Die Beweise sind möglicherweise veraltet oder unvollständig.",
|
||||
"nativeRegisterOnly": "Registrierung im Editor bestätigen.Eine bekannte Version ist ein manueller Wert;Es ist kein Updater konfiguriert."
|
||||
"nativeEvidenceStale": "Die Hinweise sind möglicherweise veraltet oder unvollständig.",
|
||||
"nativeRegisterOnly": "Bestätigen Sie die Registrierung im Editor. Eine bekannte Version wird als manueller Wert gespeichert; es wird kein Updater eingerichtet."
|
||||
},
|
||||
"statusFilter": {
|
||||
"ariaLabel": "Virtuelle Maschinen und Container filtern",
|
||||
|
||||
@@ -1738,16 +1738,16 @@
|
||||
"portCustomUrlPlaceholder": "URL personnalisée (par exemple https://vault.example.com) — remplace IP:port",
|
||||
"stackMemberTitle": "Fait partie d'une application multi-conteneurs",
|
||||
"stackMemberBody": "Ce conteneur fait partie d'une application dont le conteneur principal est {primary}. L'application, ses liens web et sa version y sont affichés.",
|
||||
"nativeEvidencePort": "Écoute du port TCP",
|
||||
"nativeEvidencePort": "Port TCP en écoute",
|
||||
"nativeEvidenceFile": "Fichier installé",
|
||||
"nativeEvidenceProcess": "Exécuter un exécutable",
|
||||
"nativeEvidenceProcess": "Exécutable en cours d'exécution",
|
||||
"nativeEvidenceDirectory": "Répertoire de travail",
|
||||
"nativeEvidenceService": "Définition du service",
|
||||
"nativeScanFailed": "La recherche d'application n'a pas pu se terminer.Les preuves antérieures peuvent être obsolètes ;essayer à nouveau.",
|
||||
"nativeScanPartial": "La recherche d’applications est incomplète.Examinez les preuves disponibles et réessayez.",
|
||||
"nativeVersionUnknown": "version installée inconnue",
|
||||
"nativeEvidenceStale": "Les preuves peuvent être obsolètes ou incomplètes.",
|
||||
"nativeRegisterOnly": "Confirmez l'inscription dans l'éditeur.Une version connue est une valeur manuelle ;aucun programme de mise à jour n'est configuré."
|
||||
"nativeScanFailed": "La recherche d'applications n'a pas pu se terminer. Les résultats précédents peuvent être obsolètes ; réessayez.",
|
||||
"nativeScanPartial": "La recherche d'applications est incomplète. Vérifiez les éléments trouvés et réessayez.",
|
||||
"nativeVersionUnknown": "Version installée inconnue",
|
||||
"nativeEvidenceStale": "Les éléments trouvés peuvent être obsolètes ou incomplets.",
|
||||
"nativeRegisterOnly": "Confirmez l'enregistrement dans l'éditeur. Une version connue est enregistrée comme valeur manuelle ; aucun outil de mise à jour n'est configuré."
|
||||
},
|
||||
"statusFilter": {
|
||||
"ariaLabel": "Filtrer les machines virtuelles et les conteneurs",
|
||||
|
||||
@@ -1738,16 +1738,16 @@
|
||||
"portCustomUrlPlaceholder": "URL personalizzato (ad es. https://vault.example.com) — sostituisce IP:port",
|
||||
"stackMemberTitle": "Parte di un'applicazione multi-container",
|
||||
"stackMemberBody": "Questo container supporta un’applicazione il cui container principale è {primary}. L’applicazione, i suoi collegamenti web e la sua versione sono mostrati lì.",
|
||||
"nativeEvidencePort": "porta TCP in ascolto",
|
||||
"nativeEvidenceFile": "file installato",
|
||||
"nativeEvidenceProcess": "esecuzione dell'eseguibile",
|
||||
"nativeEvidenceDirectory": "directory di lavoro",
|
||||
"nativeEvidenceService": "definizione del servizio",
|
||||
"nativeScanFailed": "impossibile completare la ricerca dell'applicazione.Le prove precedenti potrebbero essere obsolete;riprova.",
|
||||
"nativeScanPartial": "la ricerca dell'applicazione è incompleta.Esaminare le prove disponibili e riprovare.",
|
||||
"nativeVersionUnknown": "versione installata sconosciuta",
|
||||
"nativeEvidenceStale": "le prove potrebbero essere obsolete o incomplete.",
|
||||
"nativeRegisterOnly": "conferma la registrazione nell'editor.Una versione nota è un valore manuale;nessun programma di aggiornamento è configurato."
|
||||
"nativeEvidencePort": "Porta TCP in ascolto",
|
||||
"nativeEvidenceFile": "File installato",
|
||||
"nativeEvidenceProcess": "Eseguibile in esecuzione",
|
||||
"nativeEvidenceDirectory": "Directory di lavoro",
|
||||
"nativeEvidenceService": "Definizione del servizio",
|
||||
"nativeScanFailed": "La ricerca delle applicazioni non è stata completata. I risultati precedenti potrebbero non essere aggiornati; riprova.",
|
||||
"nativeScanPartial": "La ricerca delle applicazioni è incompleta. Controlla gli elementi trovati e riprova.",
|
||||
"nativeVersionUnknown": "Versione installata sconosciuta",
|
||||
"nativeEvidenceStale": "Gli elementi trovati potrebbero non essere aggiornati o essere incompleti.",
|
||||
"nativeRegisterOnly": "Conferma la registrazione nell'editor. Una versione nota viene salvata come valore manuale; non viene configurato alcun aggiornamento automatico."
|
||||
},
|
||||
"statusFilter": {
|
||||
"ariaLabel": "Filtra macchine virtuali e container",
|
||||
|
||||
@@ -1738,16 +1738,16 @@
|
||||
"portCustomUrlPlaceholder": "URL personalizada (por exemplo, https://vault.example.com) — substitui IP:port",
|
||||
"stackMemberTitle": "Parte de um aplicativo multicontêiner",
|
||||
"stackMemberBody": "Este contêiner faz parte de um aplicativo cujo contêiner principal é {primary}. O aplicativo, seus links da web e sua versão são mostrados lá.",
|
||||
"nativeEvidencePort": "Porta TCP de escuta",
|
||||
"nativeEvidenceFile": "arquivo instalado",
|
||||
"nativeEvidenceProcess": "Executando executável",
|
||||
"nativeEvidenceDirectory": "diretório de trabalho",
|
||||
"nativeEvidenceService": "definição de serviço",
|
||||
"nativeScanFailed": "a pesquisa do aplicativo não pôde ser concluída.As evidências anteriores podem estar desatualizadas;tente novamente.",
|
||||
"nativeScanPartial": "a pesquisa do aplicativo está incompleta.Revise as evidências disponíveis e tente novamente.",
|
||||
"nativeEvidencePort": "Porta TCP em escuta",
|
||||
"nativeEvidenceFile": "Arquivo instalado",
|
||||
"nativeEvidenceProcess": "Executável em execução",
|
||||
"nativeEvidenceDirectory": "Diretório de trabalho",
|
||||
"nativeEvidenceService": "Definição do serviço",
|
||||
"nativeScanFailed": "A pesquisa de aplicativos não pôde ser concluída. Os resultados anteriores podem estar desatualizados; tente novamente.",
|
||||
"nativeScanPartial": "A pesquisa de aplicativos está incompleta. Revise os itens encontrados e tente novamente.",
|
||||
"nativeVersionUnknown": "Versão instalada desconhecida",
|
||||
"nativeEvidenceStale": "as evidências podem estar desatualizadas ou incompletas.",
|
||||
"nativeRegisterOnly": "Confirme o cadastro no editor.Uma versão conhecida é um valor manual;nenhum atualizador está configurado."
|
||||
"nativeEvidenceStale": "Os itens encontrados podem estar desatualizados ou incompletos.",
|
||||
"nativeRegisterOnly": "Confirme o registro no editor. Uma versão conhecida é salva como valor manual; nenhum atualizador é configurado."
|
||||
},
|
||||
"statusFilter": {
|
||||
"ariaLabel": "Filtrar máquinas virtuais e contêineres",
|
||||
|
||||
@@ -1740,14 +1740,14 @@
|
||||
"stackMemberBody": "Den här behållaren stöder en applikation vars huvudbehållare är {primary}. Applikationen, dess webblänkar och dess version visas där.",
|
||||
"nativeEvidencePort": "Lyssnande TCP-port",
|
||||
"nativeEvidenceFile": "Installerad fil",
|
||||
"nativeEvidenceProcess": "Kör körbar fil",
|
||||
"nativeEvidenceProcess": "Körande programfil",
|
||||
"nativeEvidenceDirectory": "Arbetskatalog",
|
||||
"nativeEvidenceService": "Servicedefinition",
|
||||
"nativeScanFailed": "Programsökningen kunde inte avslutas.Tidigare bevis kan vara föråldrade;försök igen.",
|
||||
"nativeScanPartial": "Sökningen är ofullständig.Granska de tillgängliga bevisen och försök igen.",
|
||||
"nativeEvidenceService": "Tjänstdefinition",
|
||||
"nativeScanFailed": "Programsökningen kunde inte slutföras. Tidigare resultat kan vara inaktuella; försök igen.",
|
||||
"nativeScanPartial": "Programsökningen är ofullständig. Granska det som hittades och försök igen.",
|
||||
"nativeVersionUnknown": "Installerad version okänd",
|
||||
"nativeEvidenceStale": "Bevisen kan vara föråldrade eller ofullständiga.",
|
||||
"nativeRegisterOnly": "Bekräfta registreringen i editorn.En känd version är ett manuellt värde;ingen uppdatering är konfigurerad."
|
||||
"nativeEvidenceStale": "Det som hittades kan vara inaktuellt eller ofullständigt.",
|
||||
"nativeRegisterOnly": "Bekräfta registreringen i redigeraren. En känd version sparas som ett manuellt värde; ingen uppdatering konfigureras."
|
||||
},
|
||||
"statusFilter": {
|
||||
"ariaLabel": "Filtrera virtuella maskiner och containrar",
|
||||
|
||||
@@ -6076,6 +6076,8 @@ class HealthMonitor:
|
||||
if status == 'stale':
|
||||
checks[check_label] = {
|
||||
'status': 'CRITICAL',
|
||||
'error_key': error_key,
|
||||
'dismissable': True,
|
||||
'detail': f'{fstype} mount stale: {error or "unreachable"}',
|
||||
'fstype': fstype,
|
||||
'source': m.get('source', ''),
|
||||
@@ -6105,6 +6107,8 @@ class HealthMonitor:
|
||||
elif status == 'readonly':
|
||||
checks[check_label] = {
|
||||
'status': 'WARNING',
|
||||
'error_key': error_key,
|
||||
'dismissable': True,
|
||||
'detail': f'{fstype} mount unexpectedly read-only',
|
||||
'fstype': fstype,
|
||||
'source': m.get('source', ''),
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
"""Remote mount checks carry the key their dismissal is saved under."""
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from types import ModuleType, SimpleNamespace
|
||||
from unittest.mock import patch
|
||||
|
||||
SCRIPTS_DIR = Path(__file__).resolve().parents[1]
|
||||
if str(SCRIPTS_DIR) not in sys.path:
|
||||
sys.path.insert(0, str(SCRIPTS_DIR))
|
||||
|
||||
_health_persistence_module = ModuleType("health_persistence")
|
||||
_health_persistence_module.health_persistence = SimpleNamespace(cleanup_old_errors=lambda: None)
|
||||
_health_persistence_module.disk_base_name = lambda name: str(name).replace("/dev/", "")
|
||||
sys.modules.setdefault("health_persistence", _health_persistence_module)
|
||||
sys.modules.setdefault("psutil", ModuleType("psutil"))
|
||||
sys.modules.setdefault("flask_server", SimpleNamespace(
|
||||
get_proxmox_node_name=lambda: "fixture",
|
||||
get_cached_pvesh_cluster_resources_vm=lambda: [],
|
||||
get_cached_vm_disk=lambda _vmid: None,
|
||||
))
|
||||
|
||||
import health_monitor # noqa: E402
|
||||
|
||||
|
||||
class _Persistence:
|
||||
def __init__(self):
|
||||
self.recorded = []
|
||||
|
||||
def record_error(self, **kwargs):
|
||||
self.recorded.append(kwargs)
|
||||
|
||||
def get_active_errors(self, *args, **kwargs):
|
||||
return []
|
||||
|
||||
def clear_error(self, key):
|
||||
pass
|
||||
|
||||
|
||||
class RemoteMountDismissal(unittest.TestCase):
|
||||
def check(self, host, lxc=()):
|
||||
persistence = _Persistence()
|
||||
mounts = SimpleNamespace(scan_remote_mounts=lambda force: list(host),
|
||||
scan_lxc_mounts=lambda force: list(lxc))
|
||||
with patch.object(health_monitor, "MOUNT_MONITOR_AVAILABLE", True), \
|
||||
patch.object(health_monitor, "mount_monitor", mounts, create=True), \
|
||||
patch.object(health_monitor, "health_persistence", persistence):
|
||||
result = health_monitor.HealthMonitor._check_remote_mounts(SimpleNamespace())
|
||||
return result, persistence
|
||||
|
||||
def test_stale_and_read_only_mounts_carry_their_saved_key(self):
|
||||
result, persistence = self.check(
|
||||
[{"target": "/mnt/pve/nas", "status": "stale", "fstype": "nfs4"},
|
||||
{"target": "/mnt/share", "status": "ok", "fstype": "cifs"}],
|
||||
[{"target": "/media", "status": "readonly", "fstype": "nfs4", "lxc_id": "120", "lxc_name": "app"}])
|
||||
checks = result["checks"]
|
||||
self.assertEqual(checks["/mnt/pve/nas"]["error_key"], "mount_stale_/mnt/pve/nas")
|
||||
self.assertEqual(checks["CT 120 (app) /media"]["error_key"], "mount_readonly_ct120:/media")
|
||||
self.assertTrue(checks["/mnt/pve/nas"]["dismissable"])
|
||||
self.assertTrue(checks["CT 120 (app) /media"]["dismissable"])
|
||||
self.assertNotIn("error_key", checks["/mnt/share"])
|
||||
self.assertEqual({entry["error_key"] for entry in persistence.recorded},
|
||||
{"mount_stale_/mnt/pve/nas", "mount_readonly_ct120:/media"})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user