homelab: Arcane-Docker ehrlich zum Rückweg – Snapshot der VM nur mit Etikett watcher
Die Update-Liste zeigte bei Arcane „Snapshot vorher, bei Rot zurück“, obwohl das Docker-Update keinen Snapshot anlegte (und der Ausführer VM 106 ohne Etikett gar nicht anfassen darf). Jetzt: - Gäste ohne Freigabe haben Rückweg „keiner“, Rückfrage und Plan sagen es. - Echte Docker-Updates legen vorher einen Snapshot der VM an, wenn sie freigegeben ist, prüfen danach (Fehler-Container, Arcane antwortet binnen 3 min) und gehen bei Rot zurück – wie bei den Containern. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c37c0dccbb
commit
67ed0458a9
@@ -9,7 +9,8 @@ Wie ehrlich der Stand ist, steht dabei: Sind die Paketlisten im Gast älter als
|
||||
„unbekannt“ (mit Knopf zum Suchen) statt „aktuell“; ist der Bericht älter als eine halbe Stunde, sagt
|
||||
die Übersicht, dass der Ausführer schweigt. Ist das Update-Skript einer App frisch geändert, bleibt sie
|
||||
„neu“, aber ohne Knopf (karenz.py). Rückweg und Rückfrage sagen, was vor dem Update geschieht: Snapshot,
|
||||
wo keiner geht eine Sicherung, sonst keiner.
|
||||
wo keiner geht eine Sicherung, sonst keiner. Ohne Freigabe (Etikett) legt der Ausführer weder das eine noch
|
||||
das andere an — das betrifft Arcane, dessen Docker-Updates auch ohne Etikett über Arcane selbst laufen.
|
||||
"""
|
||||
|
||||
import re
|
||||
@@ -28,6 +29,7 @@ BERICHT_ALT_S = 30 * 60
|
||||
LISTEN_ALT_S = 14 * 24 * 3600
|
||||
EIGENES_ETIKETT = "mc2"
|
||||
ERREICHBAR_CACHE_S = 60
|
||||
OHNE_FREIGABE = "Das Etikett „watcher“ fehlt, der Ausführer darf hier keinen Snapshot anlegen"
|
||||
|
||||
_erreichbar_cache: dict[str, tuple[float, bool]] = {}
|
||||
_erreichbar_lock = threading.Lock()
|
||||
@@ -74,6 +76,8 @@ def _datum(ts: float | None) -> str:
|
||||
|
||||
def _rueckweg(gast: dict) -> str:
|
||||
"""Die Zeile „Rückweg“ der Karte: was vor jedem Update geschieht."""
|
||||
if not gast.get("erlaubt"):
|
||||
return f"Kein automatischer Rückweg: {OHNE_FREIGABE}."
|
||||
if gast.get("snapshot_moeglich"):
|
||||
return "Snapshot vor jedem Update"
|
||||
grund = gast.get("snapshot_grund") or "kein Snapshot möglich"
|
||||
@@ -86,6 +90,8 @@ def _rueckweg(gast: dict) -> str:
|
||||
|
||||
def _rueckweg_art(gast: dict) -> str:
|
||||
"""Dasselbe in einem Wort — die Oberfläche fasst den Rückweg in der Update-Liste kurz."""
|
||||
if not gast.get("erlaubt"):
|
||||
return "keiner"
|
||||
if gast.get("snapshot_moeglich"):
|
||||
return "snapshot"
|
||||
return "sicherung" if gast.get("sicherung_moeglich") else "keiner"
|
||||
@@ -93,6 +99,8 @@ def _rueckweg_art(gast: dict) -> str:
|
||||
|
||||
def _rueckweg_frage(gast: dict) -> str:
|
||||
"""Der Satz zum Rückweg in der Rückfrage vor „Jetzt updaten“."""
|
||||
if not gast.get("erlaubt"):
|
||||
return f"{OHNE_FREIGABE} — scheitert das Update, gibt es keinen automatischen Rückweg."
|
||||
if gast.get("snapshot_moeglich"):
|
||||
return "Vorher wird ein Snapshot angelegt; ist die Prüfung danach rot, geht es von selbst zurück."
|
||||
if gast.get("sicherung_moeglich"):
|
||||
@@ -166,7 +174,7 @@ def _os_baustein(gast: dict, zid: str, jetzt: float) -> BausteinStand:
|
||||
return stand
|
||||
|
||||
|
||||
def _arcane_bausteine(basis: str | None, zid: str) -> list[BausteinStand]:
|
||||
def _arcane_bausteine(basis: str | None, zid: str, gast: dict) -> list[BausteinStand]:
|
||||
"""Arcane selbst (öffentliche Version) und die Docker-Images (mit API-Schlüssel)."""
|
||||
app = arcane.app_version(basis) if basis else None
|
||||
selbst = BausteinStand(id="arcane", name="Arcane", zustand="unbekannt",
|
||||
@@ -195,7 +203,8 @@ def _arcane_bausteine(basis: str | None, zid: str) -> list[BausteinStand]:
|
||||
docker.aktion = Aktion(
|
||||
"POST", f"/api/homelab/ziele/{zid}/docker",
|
||||
("Arcane prüft im Probelauf, welche Container es aktualisieren würde — geändert wird noch nichts."
|
||||
if probe else "Arcane aktualisiert jetzt die Container mit neuen Images; Daten-Volumes bleiben."),
|
||||
if probe else "Arcane aktualisiert jetzt die Container mit neuen Images; Daten-Volumes bleiben. "
|
||||
+ _rueckweg_frage(gast)),
|
||||
label="Probelauf" if probe else "Jetzt updaten")
|
||||
else:
|
||||
docker.zustand = "aktuell"
|
||||
@@ -216,8 +225,9 @@ def _gast_ziel(gast: dict, jetzt: float) -> ZielStand:
|
||||
grund=f"Der Gast ist {gast.get('status') or 'unbekannt'}."))
|
||||
return ziel
|
||||
if app and app.kennung == "arcane":
|
||||
# Arcane läuft über seine eigene Schnittstelle, nicht über den Ausführer: kein Etikett nötig.
|
||||
ziel.bausteine += _arcane_bausteine(url.rstrip("/") if url else None, zid)
|
||||
# Arcane läuft über seine eigene Schnittstelle, nicht über den Ausführer: kein Etikett nötig — nur für den
|
||||
# Snapshot vorher (Rückweg), den legt der Ausführer an.
|
||||
ziel.bausteine += _arcane_bausteine(url.rstrip("/") if url else None, zid, gast)
|
||||
return ziel
|
||||
if not gast.get("erlaubt"):
|
||||
ziel.bausteine.append(BausteinStand(
|
||||
|
||||
Reference in New Issue
Block a user