Commit Graph

2 Commits (cddba14993b2a0d07c6bf63837b09dfc8e18451b)

Author SHA1 Message Date
nexxo e8b51f3c70 Der Waechter nimmt die Sperre erst beim Eingriff, nicht beim Nachsehen
tests / pest (push) Waiting to run Details
tests / assets (push) Waiting to run Details
tests / release (push) Blocked by required conditions Details
Der Update-Agent meldete dauerhaft "kommt nicht an die Arbeit", obwohl nichts
kaputt war. Wächter und Agent haben beide einen minütlichen Zeitgeber und nahmen
beide `.agent.lock` in ihren ersten Zeilen — bevor sie wussten, ob sie überhaupt
etwas tun würden. Der Wächter tut an fast jedem Tag nichts: seine vier Prüfungen
sind allesamt lesend. Er hielt die Sperre trotzdem, jede Minute; der Agent kam
leer aus und schrieb einen Übersprung-Vermerk. Weil der Agent der ist, der an die
Konsole berichtet, stand dort eine Dauerstörung, während beide Dienste genau das
taten, was sie sollten.

Der Wächter sieht jetzt ungesperrt nach und nimmt die Sperre erst, wenn wirklich
etwas zu richten ist — im gesunden Fall fasst er sie nie an. Wo er eingreift,
wird die Lage nach dem Nehmen der Sperre noch einmal geprüft: zwischen dem
ungesperrten Blick und der Sperre kann ein Update fertig geworden sein, und
`--force-recreate` auf gesunde Container reißt jede offene Verbindung ab.

Versetzte Zeitgeber wären nur seltener gewesen, nicht weg — zwei Takte derselben
Länge wandern gegeneinander, und systemd zieht sie über AccuracySec aktiv auf
gemeinsame Weckpunkte zusammen. Eine zweite Sperre wäre schlimmer als der Fehler
gewesen: dann liefe der Wächter mitten in ein Update hinein.

Dazu zwei Dinge, die derselbe Vorfall aufgedeckt hat:

- Vierzehn Aufrufe nach draußen standen im Wächter ohne Frist, alle unter der
  Sperre. Der Agent hat `timeout -k` am 4. August gelernt, der Wächter nie — ein
  `docker compose exec`, das auf den Daemon wartet, hätte die Sperre unbegrenzt
  gehalten.
- Ein übersprungener Lauf sah im Journal aus wie ein erfolgreicher: der Agent
  beendet sich sauber, systemd meldet Starting → Deactivated. Das hat die
  Fehlersuche zweimal in die falsche Richtung geschickt. Er sagt es jetzt, mit
  Halter und Zähler in der Zeile.

WatchdogLockContentionTest lässt beide echten Skripte gegeneinander laufen statt
die Sperrenlogik nachzurechnen — und prüft beide Richtungen: der Agent kommt an
die Arbeit, während der Wächter nur nachsieht, und der Wächter hält still,
während ein Update die Sperre hält.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 14:08:44 +02:00
nexxo 5ae2dc41fc Ein Waechter, der aufraeumt — und die vier offenen Punkte aus dem Betrieb
DER WAECHTER. Ein abgebrochenes Update liess den Stapel halb unten liegen, den
Tunnel weg und die Seite eine Stunde lang mit 500 antworten — bis jemand von
Hand nachsah. Das wartet nie wieder auf einen Menschen.

deploy/watchdog.sh laeuft jede Minute als systemd-Dienst AUF DEM WIRT, nicht in
einem Container: ein Waechter im Container braeuchte den Docker-Socket
hineingereicht (Root auf dem Wirt fuer jeden, der je hineinkommt) und waere
genau dann tot, wenn man ihn braucht. Er nimmt dieselbe Sperre wie der
Update-Agent und fasst waehrend eines Updates nichts an.

Er kennt vier Fehlerbilder, alle vier heute wirklich passiert, und fuer jedes
genau einen Griff: fehlende Dienste starten; Container, die einander nicht mehr
finden, NEU ERZEUGEN (ein Neustart hilft da nicht); wg0 hochziehen; einen seit
ueber einer halben Stunde haengenden Wartungsmodus beenden. Was er nicht kennt,
protokolliert er und laesst es in Ruhe. `maintenance-hold` ist die Handbremse.
Beides nachgemessen: Dienst gestoppt -> wieder da; wg0 abgeraeumt -> wieder oben.

DREI LUECKEN, DIE DERSELBE VORFALL AUFGEDECKT HAT:

1. `phase()` machte `mkdir -p` ohne Fangnetz. Gehoerte storage/ nach einem
   frueheren Fehltritt root, starb das Update mit `set -e` an seiner ERSTEN
   Zeile, ohne eine einzige Ausgabe. Von aussen sah das aus wie
   "haengengeblieben"; in Wahrheit war es nach einer Millisekunde vorbei.
2. Ein zweiter Aufruf meldete "Already up to date" und tat NICHTS — der Checkout
   stand ja schon auf dem Ziel. Der Commit ist die falsche Frage; jetzt wird der
   Zustand gefragt: laeuft jeder Dienst, ist der Wartungsmodus aus.
3. Nach einer Netz-Umstellung reicht `up -d` nicht: nur neu gestartete Container
   haengen weiter am alten Netz, alle laufen, und trotzdem loest kein Name mehr
   auf. Jetzt `--force-recreate`.

DIE VIER PUNKTE AUS DEM BETRIEB:

- Provisioning zeigte 15/16 in der Liste und "16 von 16" in der Karte daneben,
  bei Status "Fertig" und 100 %. Die Liste rechnete `current_step + 1` — "dieser
  Schritt laeuft gerade" —, und bei einem fertigen Lauf laeuft keiner mehr.
- Mahngebuehren standen in CENT im Feld. Wer eine Gebuehr eintraegt, denkt in
  Euro und tippt "5"; daraus wurden fuenf Cent, ohne Widerspruch. Jetzt Euro im
  Feld, Cent in der Datenbank, gerundet statt abgeschnitten ((int)(19.99*100)
  ist 1998). Und Fristen und Geld stehen in zwei eigenen Bloecken mit eigener
  Ueberschrift, die Einheit im Feld statt in der Beschriftung.
- Die Bueroadresse stand in der Konsole neben dem Management-Netz mit dem
  Vermerk "nicht entfernbar" — sie kommt aber aus TRUSTED_RANGES in der .env und
  ist sehr wohl aenderbar. Beim naechsten Umzug des Anschlusses waere das ein
  Aussperren gewesen. Strukturell sind nur zwei Eintraege; alles andere steht
  jetzt als das da, was es ist, mit dem Weg heraus.
- Ein Host-Zugang hiess weiter "pve-fns-1", waehrend der Host laengst "fsn-01"
  hiess. Die Zeile zeigt jetzt den Namen des Hosts, nicht den einmal
  gespeicherten — damit traegt sie jede kuenftige Umbenennung von selbst.

Und die Frage "wofuer brauche ich Uptime Kuma": es ist benutzt — RegisterMonitoring
legt fuer jede Kunden-Instanz eine Ueberwachung an, SyncMonitoringStatus holt den
Stand, und ein Ausfall steht auf der Uebersicht. Ohne Kunden-Instanzen gibt es
nichts zu sehen, was wie "unbenutzt" aussieht. Das steht jetzt in den
Einstellungen, statt dort nur "API-Token und wo die Bruecke erreichbar ist".

2522 Tests gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 09:43:33 +02:00