From e67fc53b20b71641ce3cd36145570ffcbc0b017e Mon Sep 17 00:00:00 2001 From: Michael Sauer Date: Wed, 23 Sep 2026 21:58:54 +0200 Subject: [PATCH] fix(station): Server nennt Rettungs-Bildsatz im Journal, haertet Umschalter-Lesen ab main() glob'te die Startzeile weiter flach ueber image_dir und nannte den geltenden Rettungs-Bildsatz nie - seit image_path() aus rescue_dir() liest, zeigte das im Rettungsmodus immer "0 image(s)". rescue_set_present() (bisher toter Code) wird jetzt fuer eine eigene Journalzeile verwendet, analog zur bestehenden Migrationszeile. read_image_set() fing nur OSError - eine Umschalterdatei mit ungueltigem UTF-8 schlug durch, statt auf die sichere Vorgabe zu fallen. --- tools/station/server.py | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/tools/station/server.py b/tools/station/server.py index acb67aa..4ee9bfb 100755 --- a/tools/station/server.py +++ b/tools/station/server.py @@ -104,14 +104,16 @@ RESCUE_SET_DIRS = {"ohne-wlan": "rescue-nocreds", "mit-wlan": "rescue-wlan"} def read_image_set(path: Path | None) -> str: """Der eingestellte Bildsatz, oder DEFAULT_IMAGE_SET, wenn die Datei fehlt, unlesbar - ist oder etwas Unbekanntes enthaelt. Wirft nie - eine kaputte Umschalterdatei darf - den Server nicht abschiessen, und sie darf vor allem nicht auf den teureren der + ist (inklusive ungueltigem UTF-8 - Fixrunde 1, Kleinigkeit: ein reines "except + OSError" liess eine Datei mit kaputten Bytes durchschlagen statt auf die Vorgabe zu + fallen) oder etwas Unbekanntes enthaelt. Wirft nie - eine kaputte Umschalterdatei + darf den Server nicht abschiessen, und sie darf vor allem nicht auf den teureren der beiden Saetze zeigen (siehe IMAGE_SET_DIRS).""" if path is None: return DEFAULT_IMAGE_SET try: value = path.read_text().strip() - except OSError: + except (OSError, UnicodeDecodeError): return DEFAULT_IMAGE_SET return value if value in IMAGE_SET_DIRS else DEFAULT_IMAGE_SET @@ -191,8 +193,10 @@ class Station: def rescue_set_present(self) -> bool: """Liegt der eingestellte Rettungs-Bildsatz ueberhaupt auf dem Pi? Dieselbe Regel wie migrate_set_present() (Verzeichnis vorhanden UND mindestens ein Image - darin) - Panel und CLI sollen fuer die Rettung nach demselben Massstab - urteilen wie fuer die Migration.""" + darin), hier fuer die Startzeile im Journal (main()) verwendet. Panel + (display.py) und CLI (ninlight-station) sind eigene Prozesse und rufen diese + Methode nicht auf, urteilen aber nach DERSELBEN REGEL - eigene, gleich lautende + Pruefungen, kein gemeinsamer Code.""" try: return any(p.name.endswith(".img") for p in self.rescue_dir().iterdir()) except OSError: @@ -718,10 +722,30 @@ def main(argv: list[str] | None = None) -> int: httpd = ThreadingHTTPServer((a.bind, a.port), Handler) httpd.daemon_threads = True httpd.station = station # type: ignore[attr-defined] - images = sorted(p.name for p in a.image_dir.glob("ninlight_*_ota.img")) + # Fixrunde 1, Kleinigkeit: vor dem Bildsatz-Umschalter fuer die Rettung lagen deren + # Abbilder flach in a.image_dir, das Glob dort war also die richtige Auskunft. Seit + # image_path() aus rescue_dir() liest (dem eingestellten Satz), muss diese Zeile + # demselben Verzeichnis folgen - sonst zeigt das Journal "0 image(s)" fuer eine + # Rettung, die tatsaechlich welche hat (oder umgekehrt). + if mode == "recovery": + try: + images = sorted(p.name for p in station.rescue_dir().glob("ninlight_*_ota.img")) + except OSError: + images = [] + else: + images = [] print(f"{now_iso()} listening on {a.bind}:{a.port}, mode={mode}, {len(images)} image(s): " f"{', '.join(images) or 'none'}", flush=True) - if mode == "migration": + if mode == "recovery": + # Bildsatz auch fuer die Rettung im Journal - dieselbe Begruendung wie unten fuer + # die Migration: "warum bekam die Lampe ein Abbild ohne/mit Zugangsdaten?" ist + # sonst nirgends nachschlagbar. rescue_set_present() (bislang toter Code) ist das + # hier tatsaechlich Verwendete. + selected = station.image_set() + present = "vorhanden" if station.rescue_set_present() else "FEHLT" + print(f"{now_iso()} image set: {selected} ({station.rescue_dir()}, {present})", + flush=True) + elif mode == "migration": # Nur im Migrationsmodus: der Bildsatz betrifft ausschliesslich migrate/-Images. # Im Journal, weil "warum kam das Image mit meinem WLAN?" sonst nirgends # nachschlagbar waere - das Panel zeigt nur den JETZIGEN Zustand.