diff --git a/tools/station/ninlight-display.service b/tools/station/ninlight-display.service index 0c81a5a..7415261 100644 --- a/tools/station/ninlight-display.service +++ b/tools/station/ninlight-display.service @@ -33,6 +33,29 @@ Environment=NINLIGHT_STATION_CONF=/etc/ninlight-station.conf # trotzdem (mit den Environment=-Vorgaben oben) statt mit einem harten Fehler - "die # Anzeige darf nirgends Voraussetzung sein" gilt auch fuer ihre eigene Konfiguration. EnvironmentFile=-/etc/ninlight-station.conf +# RuntimeDirectory=/WorkingDirectory=/Environment=HOME= zusammen beheben einen Fund aus +# der Hardware-Abnahme: lgpio (gpiozero's bevorzugte Pin-Factory) legt beim Start eine +# Benachrichtigungs-Pipe unter "$HOME/.lgd-nfy0" an. Unter systemd ist HOME per Vorgabe +# LEER und das Arbeitsverzeichnis "/" - der Pfad wird "//.lgd-nfy0", und ProtectSystem= +# strict (unten) macht "/" schreibgeschuetzt. lgpio scheitert dann mit "Can't set +# permissions", gpiozero faellt ueber rpigpio/pigpio bis zur experimentellen NativeFactory +# durch, und DIE scheitert ihrerseits mit [Errno 22] Invalid argument - display.py faengt +# das korrekt als DisplayUnavailable ab und beendet sich mit 0 (siehe Kommentar zu +# Restart=on-failure unten), aber das Panel bleibt schwarz und das Journal sieht aus wie +# "kein Panel angeschlossen", obwohl die Hardware in Ordnung ist. Am Geraet nachgemessen +# (systemd-run mit denselben zwei Property=, gegen ein Shell-echo von $HOME und pwd). +# +# RuntimeDirectory=ninlight-display ist ABSICHTLICH ein eigenes Verzeichnis, nicht das +# RuntimeDirectory=ninlight-station der Hauptunit: dieser Dienst liest von dort nur +# (status.json/control.json ueber NINLIGHT_RUN_DIR, s.o.), er soll dort nichts anlegen +# koennen. Schriebe die Anzeige in fremden Laufzeitzustand, waere das eine unnoetige +# Kopplung an dessen Lebenszyklus (siehe die Begruendung zu ReadOnlyPaths= weiter unten: +# server.py's RuntimeDirectory wird beim Stop/Neustart geleert). systemd legt +# /run/ninlight-display beim Start dieser Unit selbst an (Vorgabe 0755, vom User dieses +# Dienstes - hier root, s.u. - beschreibbar) und raeumt es beim Stop wieder auf. +RuntimeDirectory=ninlight-display +WorkingDirectory=/run/ninlight-display +Environment=HOME=/run/ninlight-display ExecStart=/usr/bin/python3 /opt/ninlight-station/display/display.py # display.py faengt ein fehlendes/abgestuerztes Panel als DisplayUnavailable ab, diff --git a/tools/station/tests/test_setup_pi.sh b/tools/station/tests/test_setup_pi.sh index f8c0624..2f3b398 100755 --- a/tools/station/tests/test_setup_pi.sh +++ b/tools/station/tests/test_setup_pi.sh @@ -683,6 +683,42 @@ echo "$PROBE_OUT" | grep -q WEITERGELAUFEN && fail "nach dem Strg-C lief das Skr [ "$PROBE_RC" -eq 130 ] && pass "Exit-Code 130 (128+SIGINT), nicht 0" || fail "Exit-Code $PROBE_RC statt 130" [ -n "$PROBE_DIR" ] && [ ! -d "$PROBE_DIR" ] && pass "das Temp-Verzeichnis mit dem Passwort wurde dabei aufgeraeumt" || fail "Temp-Verzeichnis blieb liegen: $PROBE_DIR" +echo +echo "=== Szenario 19 (Hardware-Abnahme): der Anzeigedienst bekommt ein beschreibbares Arbeitsverzeichnis und ein gesetztes HOME ===" +# Befund vom echten Pi: unter systemd ist HOME leer und das Arbeitsverzeichnis "/" - +# lgpio legt seine Benachrichtigungs-Pipe unter "$HOME/.lgd-nfy0" an, das wird +# "//.lgd-nfy0", und ProtectSystem=strict (s.u.) macht "/" schreibgeschuetzt. lgpio +# scheitert, gpiozero faellt bis zur experimentellen NativeFactory durch, und die +# scheitert ihrerseits - das Panel bleibt schwarz, obwohl die Hardware in Ordnung ist. +# Kein systemd auf diesem (macOS-)Testrechner, also keine echte Namensraum-Pruefung - +# aber die Unit ist eine Textdatei, und "RuntimeDirectory=/WorkingDirectory=/ +# Environment=HOME= sind gesetzt" laesst sich daran pruefen, ob nun im Repo direkt +# oder (hier) in der von setup_pi.sh ausgelieferten Kopie - Szenario 12 bewacht +# schon, dass beide je identisch sind. +STATE="$TMPROOT/s19-state"; STUBBIN="$TMPROOT/bin19"; LOG="$TMPROOT/s19.log" +setup_state "$STATE" +setup_stubbin "$STUBBIN" "$LOG" +: >"$LOG" +set +e +OUT=$(run_setup "$STATE" "$STUBBIN" 2>&1) +RC=$? +set -e +[ "$RC" -eq 0 ] && pass "Exit-Code 0" || fail "Exit-Code $RC, Ausgabe: $OUT" +INSTALLED_DISPLAY_UNIT="$STATE/etc/systemd/system/ninlight-display.service" +if [ -f "$INSTALLED_DISPLAY_UNIT" ]; then + grep -Eq '^RuntimeDirectory=ninlight-display$' "$INSTALLED_DISPLAY_UNIT" \ + && pass "RuntimeDirectory=ninlight-display gesetzt (eigenes Verzeichnis, nicht das der Hauptunit)" \ + || fail "RuntimeDirectory=ninlight-display fehlt - lgpio findet kein beschreibbares HOME unter systemd" + grep -Eq '^WorkingDirectory=/run/ninlight-display$' "$INSTALLED_DISPLAY_UNIT" \ + && pass "WorkingDirectory=/run/ninlight-display gesetzt" \ + || fail "WorkingDirectory=/run/ninlight-display fehlt" + grep -Eq '^Environment=HOME=/run/ninlight-display$' "$INSTALLED_DISPLAY_UNIT" \ + && pass "Environment=HOME=/run/ninlight-display gesetzt" \ + || fail "Environment=HOME=/run/ninlight-display fehlt - lgpio legt seine Pipe sonst unter //.lgd-nfy0 an (schreibgeschuetzt durch ProtectSystem=strict)" +else + fail "ninlight-display.service wurde nicht installiert - Szenario 19 kann nichts pruefen" +fi + echo if [ "$FAILED" -eq 0 ]; then echo "Alle Tests bestanden."