feat(station): Tasterdienst per deploy.sh/setup_pi.sh ausliefern
This commit is contained in:
@@ -90,15 +90,20 @@ echo "== Server, CLI und Units installieren =="
|
||||
"$SSH_BIN" "$HOST" bash -s <<'REMOTE'
|
||||
set -e
|
||||
STAGE_DIR=${NINLIGHT_STAGE_DIR:-/tmp}
|
||||
rm -rf "$STAGE_DIR/ninlight-display"
|
||||
rm -rf "$STAGE_DIR/ninlight-display" "$STAGE_DIR/ninlight-button"
|
||||
REMOTE
|
||||
"$SCP_BIN" -q "$HERE/server.py" "$HERE/products.py" "$HERE/ninlight-station" \
|
||||
"$HERE/ninlight-station.service" "$HERE/ninlight-display.service" "$HOST:$STAGE_DIR/"
|
||||
"$HERE/ninlight-station.service" "$HERE/ninlight-display.service" "$HERE/ninlight-button.service" \
|
||||
"$HOST:$STAGE_DIR/"
|
||||
# Das Anzeigeverzeichnis als Ganzes: render.py, display.py, epdconfig.py, die beiden
|
||||
# uebernommenen Panel-Treiber und HERKUNFT.md (der Herkunftsnachweis gehoert mit auf den
|
||||
# Pi). "scp -r" statt rsync, weil setup_pi.sh - anders als deploy.sh - ausdruecklich nur
|
||||
# ssh/scp voraussetzt; __pycache__ wird auf der Gegenseite weggeraeumt (unten).
|
||||
"$SCP_BIN" -q -r "$HERE/display" "$HOST:$STAGE_DIR/ninlight-display"
|
||||
# Das Tasterverzeichnis genauso: als Ganzes, mit demselben "vorher aufraeumen"-Schutz
|
||||
# gegen ein "scp -r" auf ein bereits vorhandenes Ziel (siehe Kommentar oben zu
|
||||
# ninlight-display).
|
||||
"$SCP_BIN" -q -r "$HERE/button" "$HOST:$STAGE_DIR/ninlight-button"
|
||||
# Pfade als Variablen mit Default (wie in deploy.sh): so kann ein Test die
|
||||
# Installation gegen ein Sandbox-Verzeichnis statt gegen echte Systempfade laufen
|
||||
# lassen.
|
||||
@@ -109,6 +114,7 @@ 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}
|
||||
BUTTON_UNIT_PATH=${NINLIGHT_BUTTON_UNIT:-/etc/systemd/system/ninlight-button.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
|
||||
@@ -117,11 +123,12 @@ DISPLAY_UNIT_PATH=${NINLIGHT_DISPLAY_UNIT:-/etc/systemd/system/ninlight-display.
|
||||
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"
|
||||
"$STAGE_DIR/ninlight-display" "$STAGE_DIR/ninlight-button.service" \
|
||||
"$STAGE_DIR/ninlight-button"
|
||||
}
|
||||
trap cleanup_stage EXIT
|
||||
|
||||
rm -rf "$STAGE_DIR/ninlight-display/__pycache__"
|
||||
rm -rf "$STAGE_DIR/ninlight-display/__pycache__" "$STAGE_DIR/ninlight-button/__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
|
||||
@@ -134,11 +141,19 @@ rm -rf "$STAGE_DIR/ninlight-display/__pycache__"
|
||||
# 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
|
||||
echo " Nichts installiert: $ROOT_DIR, $BIN_PATH und alle drei Units sind unveraendert. Ablage aufgeraeumt, Lauf einfach wiederholen." >&2
|
||||
exit 1
|
||||
fi
|
||||
# Dieselbe harte Vorbedingung wie bei display.py, aus demselben Grund: ohne button.py in
|
||||
# der Ablage hat das scp nicht geliefert, was es sollte, und die Installationsschleife
|
||||
# unten wuerde das stillschweigend als "nichts zu tun" verbuchen.
|
||||
if [ ! -f "$STAGE_DIR/ninlight-button/button.py" ]; then
|
||||
echo "Fehler: $STAGE_DIR/ninlight-button/button.py fehlt - die Uebertragung des Tasterverzeichnisses ist fehlgeschlagen." >&2
|
||||
echo " Nichts installiert: $ROOT_DIR, $BIN_PATH und alle drei 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 -d -m 0755 "$ROOT_DIR" "$ROOT_DIR/images" "$ROOT_DIR/display" "$ROOT_DIR/button"
|
||||
sudo install -m 0755 "$STAGE_DIR/server.py" "$ROOT_DIR/server.py"
|
||||
sudo install -m 0644 "$STAGE_DIR/products.py" "$ROOT_DIR/products.py"
|
||||
sudo install -m 0755 "$STAGE_DIR/ninlight-station" "$BIN_PATH"
|
||||
@@ -165,6 +180,25 @@ for f in "$ROOT_DIR"/display/*; do
|
||||
fi
|
||||
done
|
||||
sudo install -m 0644 "$STAGE_DIR/ninlight-display.service" "$DISPLAY_UNIT_PATH"
|
||||
# Taster: dieselbe Behandlung wie die Anzeige - button.py ist ausfuehrbar (die Unit ruft
|
||||
# es zwar ueber /usr/bin/python3 auf, von Hand pruefen laesst es sich trotzdem), der Rest
|
||||
# (aktuell nichts weiter) waere importierter Code.
|
||||
for f in "$STAGE_DIR"/ninlight-button/*; do
|
||||
[ -f "$f" ] || continue
|
||||
case "$(basename "$f")" in
|
||||
button.py) sudo install -m 0755 "$f" "$ROOT_DIR/button/$(basename "$f")" ;;
|
||||
*) sudo install -m 0644 "$f" "$ROOT_DIR/button/$(basename "$f")" ;;
|
||||
esac
|
||||
done
|
||||
# Dasselbe Argument wie bei display/: button/ ist reiner Code aus dem Repo.
|
||||
for f in "$ROOT_DIR"/button/*; do
|
||||
[ -e "$f" ] || continue
|
||||
if [ ! -e "$STAGE_DIR/ninlight-button/$(basename "$f")" ]; then
|
||||
sudo rm -rf "$f"
|
||||
echo " veraltete Datei entfernt: button/$(basename "$f")"
|
||||
fi
|
||||
done
|
||||
sudo install -m 0644 "$STAGE_DIR/ninlight-button.service" "$BUTTON_UNIT_PATH"
|
||||
# Das Aufraeumen der Ablage macht der EXIT-Trap oben - auf beiden Wegen aus diesem Block.
|
||||
sudo systemctl daemon-reload
|
||||
echo " installiert"
|
||||
@@ -335,6 +369,21 @@ sudo systemctl restart ninlight-display.service >/dev/null 2>&1 || \
|
||||
echo " Anzeigedienst aktiviert"
|
||||
REMOTE
|
||||
|
||||
echo "== Tasterdienst aktivieren =="
|
||||
# Dieselbe weiche Behandlung wie die Anzeige, aus demselben Grund: der Taster ist
|
||||
# nirgends Voraussetzung. Fehlt gpiozero, fehlt der Taster oder ist GPIO23 belegt,
|
||||
# beendet sich button.py still mit 0 (siehe dessen Modul-Docstring) - ein
|
||||
# fehlgeschlagenes enable/start darf setup_pi.sh trotzdem nicht abbrechen, denn eine
|
||||
# Station ohne Taster muss vollstaendig benutzbar bleiben.
|
||||
"$SSH_BIN" "$HOST" bash -s <<'REMOTE'
|
||||
set -e
|
||||
sudo systemctl enable ninlight-button.service >/dev/null 2>&1 || \
|
||||
echo " Warnung: 'systemctl enable ninlight-button' fehlgeschlagen - der Taster startet nach einem Neustart des Pi nicht von allein mit" >&2
|
||||
sudo systemctl restart ninlight-button.service >/dev/null 2>&1 || \
|
||||
echo " Warnung: 'systemctl restart ninlight-button' fehlgeschlagen - journalctl -u ninlight-button" >&2
|
||||
echo " Tasterdienst aktiviert"
|
||||
REMOTE
|
||||
|
||||
echo "== NetworkManager-Profile =="
|
||||
# Zwei Dinge, die man an einer echten Lampenstation nicht falsch machen darf:
|
||||
# - /etc/ninlight-station.conf ist 0600 root:root (das Passwort soll nicht
|
||||
@@ -486,4 +535,7 @@ Naechste Schritte:
|
||||
tools/station/deploy.sh <pi-host> Images ausliefern
|
||||
ssh <pi-host> ninlight-station on Station einschalten
|
||||
ssh <pi-host> ninlight-station off wieder ausschalten (nicht vergessen)
|
||||
|
||||
Der Taster auf GPIO23 ist mit eingerichtet: kurzer Druck oeffnet das Menue am Geraet,
|
||||
3 s gehalten brechen eine laufende Migration/Rettung ab.
|
||||
EOF
|
||||
|
||||
Reference in New Issue
Block a user