From 39320b446db170a193231d49fb3d2dd484e97c1e Mon Sep 17 00:00:00 2001 From: Hitonabi Date: Thu, 24 Sep 2026 19:01:20 +0200 Subject: [PATCH] homelab: eigener Container nicht in der Geraeteliste, Geheimnis beim Einrichten richtig anstossen, Deploy zieht den Homelab-Teil mit Co-Authored-By: Claude Opus 5.5 --- backend/services/homelab/inventar.py | 4 +++- backend/tests/test_homelab.py | 8 ++++++++ deploy/deploy.sh | 19 +++++++++++++++++++ deploy/homelab/einrichten.sh | 5 +++-- docs/BETRIEB.md | 5 ++++- 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/backend/services/homelab/inventar.py b/backend/services/homelab/inventar.py index 4adca52..a3197a6 100644 --- a/backend/services/homelab/inventar.py +++ b/backend/services/homelab/inventar.py @@ -24,6 +24,7 @@ from services.homelab import apps, arcane, kanal BERICHT_ALT_S = 30 * 60 LISTEN_ALT_S = 14 * 24 * 3600 +EIGENES_ETIKETT = "mc2" ERREICHBAR_CACHE_S = 60 _erreichbar_cache: dict[str, tuple[float, bool]] = {} @@ -217,7 +218,8 @@ def ziele() -> dict: return {"ziele": [], "bericht": None, "ausfuehrer": ausfuehrer} b = eingang["bericht"] liste = [_host_ziel(b.get("host") or {})] - liste += [_gast_ziel(g, jetzt) for g in b.get("gaeste") or []] + # Der Container des Orchestrators selbst (Etikett „mc2“) ist kein Gerät, das er pflegt. + liste += [_gast_ziel(g, jetzt) for g in b.get("gaeste") or [] if EIGENES_ETIKETT not in (g.get("etiketten") or [])] for z in liste: z.geprueft = eingang["empfangen"] return {"ziele": [z.als_dict() for z in liste], diff --git a/backend/tests/test_homelab.py b/backend/tests/test_homelab.py index 0d4a27c..0835f91 100644 --- a/backend/tests/test_homelab.py +++ b/backend/tests/test_homelab.py @@ -289,3 +289,11 @@ def test_ausfuehrer_nur_lesen(monkeypatch): assert antwort["code"] == 2 and "Nur-Lesen" in antwort["text"] and ausgefuehrt == [] monkeypatch.setattr(a, "bericht", lambda: {"gaeste": []}) assert a.ausfuehren({"aktion": "bericht", "parameter": {}})["code"] == 0 + + +def test_eigener_container_erscheint_nicht(daten): + bericht = json.loads(json.dumps(BERICHT)) + bericht["gaeste"].append({"vmid": 107, "art": "lxc", "name": "homelab-orchestrator", "status": "running", + "etiketten": ["mc2"], "erlaubt": False, "ip": "192.168.178.31"}) + kanal.bericht_speichern(bericht) + assert "ct-107" not in {z["id"] for z in inventar.ziele()["ziele"]} diff --git a/deploy/deploy.sh b/deploy/deploy.sh index f7bd22c..f697b75 100644 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -174,6 +174,25 @@ stufe2() { trap - ERR echo "$(date -Is) $neu (vorher ${vorher:0:7})" >> "$DEPLOY_LOG" 2>/dev/null || true echo "✅ Deploy $neu ist live (vorher ${vorher:0:7})." + homelab_mitziehen +} + +# 8. Den Homelab-Teil gleich mitziehen (seit 24.09.2026): Ist ein Partner eingerichtet (box-partner.sh legt +# partner.conf an), bekommt sein Container denselben Stand — sonst liefen beide Instanzen auseinander. +# Scheitert das, bleibt die Box trotzdem live; es gibt eine dringende Meldung. MC_DEPLOY_OHNE_HOMELAB=1 lässt es aus. +homelab_mitziehen() { + local conf="$HOME/.config/systemd/user/mission-control-2.service.d/partner.conf" ziel + [ "${MC_DEPLOY_OHNE_HOMELAB:-0}" = "1" ] && return 0 + ziel="$(grep -o 'MC_PARTNER_URL=http://[0-9.]*' "$conf" 2>/dev/null | head -n 1 | cut -d/ -f3)" + [ -n "$ziel" ] || return 0 + echo "Ziehe den Homelab-Teil ($ziel) nach…" + if bash deploy/homelab/ausrollen.sh "$ziel" > /tmp/mc2-homelab-ausrollen.log 2>&1; then + echo "✅ Homelab-Teil ($ziel) hat denselben Stand." + else + echo "✗ Homelab-Teil ($ziel) ließ sich nicht aktualisieren (/tmp/mc2-homelab-ausrollen.log)." + bash deploy/notify.sh -d -s "[Alarm] Deploy" \ + "Die Box ist auf dem neuen Stand, der Homelab-Teil ($ziel) aber nicht — Protokoll: /tmp/mc2-homelab-ausrollen.log." || true + fi } # Beides in Funktionen und ein exit direkt dahinter: bash liest ein Skript häppchenweise, und diff --git a/deploy/homelab/einrichten.sh b/deploy/homelab/einrichten.sh index 384d5c1..b0959f5 100644 --- a/deploy/homelab/einrichten.sh +++ b/deploy/homelab/einrichten.sh @@ -31,6 +31,7 @@ for _ in $(seq 1 20); do sleep 1 done curl -sf -m 3 http://127.0.0.1:9001/api/health && echo -# Das gemeinsame Geheimnis für den Ausführer entsteht beim ersten Abruf (0600, Nutzer mc2). -curl -sf -m 5 http://127.0.0.1:9001/api/homelab/ausfuehrer >/dev/null || true +# Das gemeinsame Geheimnis für den Ausführer entsteht beim ersten Zugriff mit Kopfzeile (0600, Nutzer mc2); +# die Antwort ist 403, gewollt. +curl -s -o /dev/null -m 5 -H 'X-MC2-Ausfuehrer: erzeugen' http://127.0.0.1:9001/api/homelab/ausfuehrer/auftrag || true echo "✅ Homelab-Teil läuft." diff --git a/docs/BETRIEB.md b/docs/BETRIEB.md index e7c8d33..335a7b5 100644 --- a/docs/BETRIEB.md +++ b/docs/BETRIEB.md @@ -127,7 +127,10 @@ systemd-Einheiten und überleben den Neustart von MC2. Dann den alten Stand merk 7. Neustart von `mc2-gateway`, `mission-control-2` und `mc2-steward`, dann bis zu 60 s Nachprüfung: `/api/health`, `/gw/health`, Steward aktiv. -Erfolg: eine Zeile in `/srv/models/mc2-deploy.log` und „Deploy ist live". Scheitert ein Schritt: +Erfolg: eine Zeile in `/srv/models/mc2-deploy.log` und „Deploy ist live". Danach (Schritt 8) zieht der Deploy den +Homelab-Teil mit, sobald `box-partner.sh` einen Partner eingerichtet hat: `deploy/homelab/ausrollen.sh` mit der IP aus +`partner.conf`. Scheitert das, bleibt die Box live und es kommt „[Alarm] Deploy"; `MC_DEPLOY_OHNE_HOMELAB=1` lässt +den Schritt aus. Scheitert ein Schritt: `git reset --hard` auf den alten Stand, llama-swap-Config zurück (falls ersetzt), Dienste neu, Zeile `GESCHEITERT` im Log und die dringende Meldung „[Alarm] Deploy".