From 0df593c05a14b4991219d4ec617bb0f8de07c6ca Mon Sep 17 00:00:00 2001 From: Hitonabi Date: Fri, 25 Sep 2026 12:39:54 +0200 Subject: [PATCH] homelab: nach dem Hochfahren des Hosts schon nach einer Minute wieder berichten MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Der erste Bericht nach dem Neustart vom 25.09. kam 34 s nach dem Hochfahren – Proxmox kannte die Gäste noch nicht („unknown“), und zehn Minuten lang zeigte die Oberfläche jeden Gast als unbekannt. Enthält ein Bericht solche Gäste, folgt der nächste nach 60 s. Der Grund steht jetzt auf Deutsch da. Co-Authored-By: Claude Opus 5.5 --- backend/services/homelab/inventar.py | 12 +++++++++++- backend/tests/test_homelab.py | 8 ++++++++ deploy/homelab/ausfuehrer.py | 16 ++++++++++++++-- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/backend/services/homelab/inventar.py b/backend/services/homelab/inventar.py index 46061dc..cb1e411 100644 --- a/backend/services/homelab/inventar.py +++ b/backend/services/homelab/inventar.py @@ -218,6 +218,16 @@ def _arcane_bausteine(basis: str | None, zid: str, gast: dict) -> list[BausteinS return [selbst, docker] +def _status_text(status: object) -> str: + """Warum ein Gast keine Bausteine hat — auf Deutsch. „unknown“ kommt kurz nach dem Hochfahren des Hosts, bevor + Proxmox den Zustand kennt (der Ausführer berichtet dann nach einer Minute erneut).""" + if status == "stopped": + return "Der Gast ist gestoppt." + if status == "paused": + return "Der Gast ist angehalten." + return "Proxmox kennt seinen Zustand gerade nicht (etwa kurz nach dem Hochfahren des Hosts)." + + def _gast_ziel(gast: dict, jetzt: float) -> ZielStand: art = "container" if gast["art"] == "lxc" else "vm" zid = f"{'ct' if art == 'container' else 'vm'}-{gast['vmid']}" @@ -229,7 +239,7 @@ def _gast_ziel(gast: dict, jetzt: float) -> ZielStand: rueckweg=_rueckweg(gast), rueckweg_art=_rueckweg_art(gast), platte=gast.get("platte")) if not laeuft: ziel.bausteine.append(BausteinStand(id="status", name="Status", zustand="unbekannt", - grund=f"Der Gast ist {gast.get('status') or 'unbekannt'}.")) + grund=_status_text(gast.get("status")))) return ziel if app and app.kennung == "arcane": # Arcane läuft über seine eigene Schnittstelle, nicht über den Ausführer: kein Etikett nötig — nur für den diff --git a/backend/tests/test_homelab.py b/backend/tests/test_homelab.py index af58c9c..f2cf78f 100644 --- a/backend/tests/test_homelab.py +++ b/backend/tests/test_homelab.py @@ -483,3 +483,11 @@ Remv pve-kernel-6.8.12-4-pve [6.8.12-4] behalten = {"7.0.14-12-pve", "7.0.14-19-pve"} assert a.alte_kernel(simulation, behalten) == [ "proxmox-kernel-6.14.11-2-pve-signed", "proxmox-kernel-7.0.14-5-pve-signed", "pve-kernel-6.8.12-4-pve"] + + +def test_nach_dem_hochfahren_bald_wieder_berichten(): + """25.09.2026: Der erste Bericht nach dem Neustart kam 34 s nach dem Hochfahren — alle Gäste „unknown“.""" + a = _ausfuehrer_modul() + assert a.naechster_bericht_in({"gaeste": [{"status": "running"}, {"status": "stopped"}]}) == a.BERICHT_ALLE_S + assert a.naechster_bericht_in({"gaeste": [{"status": "running"}, {"status": "unknown"}]}) == a.BERICHT_BALD_S == 60 + assert a.naechster_bericht_in({}) == a.BERICHT_ALLE_S diff --git a/deploy/homelab/ausfuehrer.py b/deploy/homelab/ausfuehrer.py index 06d6dd6..6188d62 100644 --- a/deploy/homelab/ausfuehrer.py +++ b/deploy/homelab/ausfuehrer.py @@ -1174,8 +1174,9 @@ def dauerbetrieb() -> None: while True: try: if time.time() >= naechster_bericht: - _anfrage("POST", "/api/homelab/ausfuehrer/bericht", bericht()) - naechster_bericht = time.time() + BERICHT_ALLE_S + daten = bericht() + _anfrage("POST", "/api/homelab/ausfuehrer/bericht", daten) + naechster_bericht = time.time() + naechster_bericht_in(daten) auftrag = _anfrage("GET", "/api/homelab/ausfuehrer/auftrag") if isinstance(auftrag, dict) and auftrag.get("id"): log.info("Auftrag %s: %s %s", auftrag["id"], auftrag.get("aktion"), auftrag.get("parameter")) @@ -1191,6 +1192,17 @@ def dauerbetrieb() -> None: time.sleep(ABFRAGE_ALLE_S) +BERICHT_BALD_S = 60 + + +def naechster_bericht_in(daten: dict) -> int: + """Wann der nächste Bericht fällig ist. Kurz nach dem Hochfahren kennt Proxmox den Zustand der Gäste noch nicht + („unknown“): Am 25.09.2026 kam der erste Bericht 34 s nach dem Neustart, und zehn Minuten lang zeigte die + Oberfläche jeden Gast als unbekannt. Dann schon nach einer Minute wieder.""" + unklar = any(g.get("status") not in ("running", "stopped", "paused") for g in daten.get("gaeste") or []) + return BERICHT_BALD_S if unklar else BERICHT_ALLE_S + + def _konfig_laden() -> dict: try: with open(KONFIG, encoding="utf-8") as f: