fix(station): ehrliche Abbruchmeldung, apt-update darf scheitern
Fixrunde 2 zu Task 6b. - Die Vorbedingung "display.py liegt in der Ablage" steht jetzt VOR dem ersten sudo install. Vorher stand sie dahinter, und die Meldung "Nichts installiert" war schlicht unwahr: server.py, products.py, das CLI und die Stations-Unit lagen dann schon auf dem Pi. Ausgerechnet an dem Werkbank-Moment, fuer den die Pruefung gedacht ist, log das Skript den Bediener an. Die Ablage raeumt ein EXIT-Trap jetzt auf beiden Wegen aus dem Block ab, nicht nur im Erfolgsfall. - "apt-get update" ist keine Voraussetzung mehr fuer "apt-get install": update meldet schon dann einen Fehler, wenn eine einzige Quelle nicht erreichbar ist, und ein Pi, auf dem das Paket aus dem Cache gekommen waere, bekam so still kein Pillow. - Die Signalhandler beenden jetzt selbst (130/143/129). Ein Handler ohne exit laesst bash weiterlaufen - ein Strg-C konnte in "fertig, Exit 0" muenden. Die Begruendung im Kommentar war falsch und ist korrigiert: zum Aufraeumen haette der EXIT-Trap allein genuegt. - test_host.sh ruft die Shell-Suiten aus einer Liste auf, und der Coverage-Test prueft diese Liste gegen das Dateisystem statt im Skripttext nach Dateinamen zu suchen - ein nachgestellter Kommentar hebelte die alte Regel aus. Er deckt jetzt ganz tools/ ab, nicht nur station/tests. - Neue Szenarien: Wahrheitsgehalt der Abbruchmeldung, apt-update-Fall, und ein Strg-C, das aus den Trap-Zeilen des Skripts selbst geprueft wird.
This commit is contained in:
+51
-20
@@ -109,6 +109,35 @@ ROOT_DIR=${NINLIGHT_STATION_ROOT:-/opt/ninlight-station}
|
||||
BIN_PATH=${NINLIGHT_STATION_BIN:-/usr/local/bin/ninlight-station}
|
||||
UNIT_PATH=${NINLIGHT_STATION_UNIT:-/etc/systemd/system/ninlight-station.service}
|
||||
DISPLAY_UNIT_PATH=${NINLIGHT_DISPLAY_UNIT:-/etc/systemd/system/ninlight-display.service}
|
||||
|
||||
# Die Ablage wird in JEDEM Fall abgeraeumt, auch wenn dieser Block vorzeitig aussteigt
|
||||
# (Task 6b F2, N1). Vorher stand das "rm -rf" nur am Blockende und wurde beim Abbruch
|
||||
# uebersprungen - die uebertragenen Dateien blieben unter /tmp liegen und waren beim
|
||||
# naechsten Lauf genau der Reststand, gegen den der Block eigentlich absichert.
|
||||
cleanup_stage() {
|
||||
rm -rf "$STAGE_DIR/server.py" "$STAGE_DIR/products.py" "$STAGE_DIR/ninlight-station" \
|
||||
"$STAGE_DIR/ninlight-station.service" "$STAGE_DIR/ninlight-display.service" \
|
||||
"$STAGE_DIR/ninlight-display"
|
||||
}
|
||||
trap cleanup_stage EXIT
|
||||
|
||||
rm -rf "$STAGE_DIR/ninlight-display/__pycache__"
|
||||
# Harte Vorbedingung, und zwar VOR dem ersten "sudo install" (Task 6b F2, N1): ohne
|
||||
# display.py in der Ablage hat das scp nicht geliefert, was es sollte - abgebrochen,
|
||||
# falsch verschachtelt oder gar nicht gelaufen. Die Installationsschleife weiter unten
|
||||
# wuerde das stillschweigend als "nichts zu tun" verbuchen, der Lauf meldete Erfolg und
|
||||
# der aktivierte Anzeigedienst liefe gegen eine nicht existierende Datei.
|
||||
#
|
||||
# Die Pruefung stand zuerst NACH den vier "sudo install" darunter - die Meldung "Nichts
|
||||
# installiert" war damit schlicht unwahr: server.py, products.py, das CLI und die
|
||||
# Stations-Unit lagen dann bereits auf dem Pi. Ausgerechnet an dem Werkbank-Moment, fuer
|
||||
# den diese Pruefung gedacht ist, log das Skript den Bediener an. Jetzt stimmt der Satz.
|
||||
if [ ! -f "$STAGE_DIR/ninlight-display/display.py" ]; then
|
||||
echo "Fehler: $STAGE_DIR/ninlight-display/display.py fehlt - die Uebertragung des Anzeigeverzeichnisses ist fehlgeschlagen." >&2
|
||||
echo " Nichts installiert: $ROOT_DIR, $BIN_PATH und beide Units sind unveraendert. Ablage aufgeraeumt, Lauf einfach wiederholen." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo install -d -m 0755 "$ROOT_DIR" "$ROOT_DIR/images" "$ROOT_DIR/display"
|
||||
sudo install -m 0755 "$STAGE_DIR/server.py" "$ROOT_DIR/server.py"
|
||||
sudo install -m 0644 "$STAGE_DIR/products.py" "$ROOT_DIR/products.py"
|
||||
@@ -116,16 +145,6 @@ sudo install -m 0755 "$STAGE_DIR/ninlight-station" "$BIN_PATH"
|
||||
sudo install -m 0644 "$STAGE_DIR/ninlight-station.service" "$UNIT_PATH"
|
||||
# Anzeige: display.py ist ausfuehrbar (die Unit ruft es zwar ueber /usr/bin/python3 auf,
|
||||
# "ninlight-station display test" aber auch von Hand), der Rest ist importierter Code.
|
||||
rm -rf "$STAGE_DIR/ninlight-display/__pycache__"
|
||||
# Harte Vorbedingung (Task 6b F1, I1): ohne display.py in der Ablage hat das scp nicht
|
||||
# geliefert, was es sollte - abgebrochen, falsch verschachtelt oder gar nicht gelaufen.
|
||||
# Die Schleife darunter wuerde das stillschweigend als "nichts zu tun" verbuchen, der
|
||||
# Lauf meldete Erfolg und der aktivierte Anzeigedienst liefe gegen eine nicht
|
||||
# existierende Datei. Lieber hier laut abbrechen.
|
||||
if [ ! -f "$STAGE_DIR/ninlight-display/display.py" ]; then
|
||||
echo "Fehler: $STAGE_DIR/ninlight-display/display.py fehlt - die Uebertragung des Anzeigeverzeichnisses ist fehlgeschlagen. Nichts installiert." >&2
|
||||
exit 1
|
||||
fi
|
||||
for f in "$STAGE_DIR"/ninlight-display/*; do
|
||||
[ -f "$f" ] || continue
|
||||
case "$(basename "$f")" in
|
||||
@@ -146,9 +165,7 @@ for f in "$ROOT_DIR"/display/*; do
|
||||
fi
|
||||
done
|
||||
sudo install -m 0644 "$STAGE_DIR/ninlight-display.service" "$DISPLAY_UNIT_PATH"
|
||||
rm -rf "$STAGE_DIR/server.py" "$STAGE_DIR/products.py" "$STAGE_DIR/ninlight-station" \
|
||||
"$STAGE_DIR/ninlight-station.service" "$STAGE_DIR/ninlight-display.service" \
|
||||
"$STAGE_DIR/ninlight-display"
|
||||
# Das Aufraeumen der Ablage macht der EXIT-Trap oben - auf beiden Wegen aus diesem Block.
|
||||
sudo systemctl daemon-reload
|
||||
echo " installiert"
|
||||
REMOTE
|
||||
@@ -175,8 +192,15 @@ if python3 -c 'import PIL' 2>/dev/null; then
|
||||
else
|
||||
# "update" zuerst: auf einem laenger nicht gepflegten Pi zeigen die Paketlisten auf
|
||||
# Versionen, die es im Archiv nicht mehr gibt, und "install" scheitert mit 404.
|
||||
# Beide Aufrufe duerfen nur warnen - siehe oben.
|
||||
if sudo apt-get update >/dev/null 2>&1 && sudo apt-get install -y python3-pil; then
|
||||
#
|
||||
# Aber "|| true", und "install" laeuft UNABHAENGIG davon (Task 6b F2, N2): "apt-get
|
||||
# update" liefert schon dann einen Fehler, wenn eine einzige Quelle nicht erreichbar
|
||||
# ist - eine veraltete Drittanbieter-Liste, teilweises Netz. Mit "update && install"
|
||||
# bekaeme ein Pi, auf dem "install" aus dem Paketcache oder den erreichbaren Quellen
|
||||
# muehelos durchgelaufen waere, still kein Pillow. Das Auffrischen ist eine
|
||||
# Verbesserung der Chancen, keine Voraussetzung.
|
||||
sudo apt-get update >/dev/null 2>&1 || true
|
||||
if sudo apt-get install -y python3-pil; then
|
||||
echo " python3-pil installiert"
|
||||
else
|
||||
echo " Warnung: python3-pil liess sich nicht installieren (kein Netz? veraltete Paketlisten?)." >&2
|
||||
@@ -233,10 +257,14 @@ eval "$(sudo cat "$CONF")"
|
||||
# Variable gar nicht mehr. Deshalb ein gemeinsames Verzeichnis mit genau einem
|
||||
# Trap darum herum (0700, mktemp -d legt es so an).
|
||||
#
|
||||
# Auch auf INT/TERM/HUP, nicht nur EXIT: bash fuehrt den EXIT-Trap zwar nach einem
|
||||
# abgefangenen Signal aus, aber nur, wenn das Signal ueberhaupt abgefangen wird - ohne
|
||||
# eigenen Handler beendet ein Strg-C (INT) oder ein abbrechendes ssh (HUP) die Shell
|
||||
# sofort, und der EXIT-Trap laeuft nie. Genau dann bliebe die Datei liegen.
|
||||
# Zur Reichweite des Traps (Task 6b F2, N3 - die Begruendung hier war vorher falsch):
|
||||
# der EXIT-Trap allein WUERDE bei einem Strg-C schon reichen, bash fuehrt ihn auch beim
|
||||
# Abbruch durch ein nicht abgefangenes SIGINT aus (Exit 130). Der Grund fuer die
|
||||
# Signalhandler ist ein anderer: sie sollen den Exit-Code ehrlich halten. Ein Handler
|
||||
# fuer INT/TERM, der nicht selbst beendet, laesst bash naemlich NACH dem Handler
|
||||
# weiterlaufen - ein Strg-C mitten im Schreiben der Profile koennte dann in "fertig,
|
||||
# Exit 0" muenden, obwohl der Lauf abgebrochen wurde. Deshalb raeumt jeder Handler auf
|
||||
# und beendet danach ausdruecklich mit dem ueblichen Signal-Code (128+n).
|
||||
#
|
||||
# Mit ausdruecklicher Vorlage unter ${TMPDIR:-/tmp}, nicht als blankes "mktemp -d":
|
||||
# BSD-mktemp (macOS, wo diese Suite auch laeuft) beachtet TMPDIR ohne Vorlage gar nicht
|
||||
@@ -245,7 +273,10 @@ eval "$(sudo cat "$CONF")"
|
||||
# der nachsieht, ob wirklich nichts liegengeblieben ist, sucht dann auf macOS an der
|
||||
# falschen Stelle und ist gruen, ohne etwas geprueft zu haben.
|
||||
PROFILE_TMPDIR=$(mktemp -d "${TMPDIR:-/tmp}/ninlight-profile.XXXXXX")
|
||||
trap 'rm -rf "$PROFILE_TMPDIR"' EXIT INT TERM HUP
|
||||
trap 'rm -rf "$PROFILE_TMPDIR"' EXIT
|
||||
trap 'rm -rf "$PROFILE_TMPDIR"; exit 130' INT
|
||||
trap 'rm -rf "$PROFILE_TMPDIR"; exit 143' TERM
|
||||
trap 'rm -rf "$PROFILE_TMPDIR"; exit 129' HUP
|
||||
|
||||
# $1 = Profilname, $2 = SSID, $3 = PSK, $4 = "update" (bestehendes Profil neu schreiben,
|
||||
# UUID behalten) oder "keep" (bestehendes Profil unangetastet lassen).
|
||||
|
||||
Reference in New Issue
Block a user