fix(station): CLI prueft Rettungs- und Migrationsbildsatz getrennt, meldet Modus dauerhaft

Fixrunde 1, Befund 1: imageset_dir()/migrate_images()/imageset_status_lines()
pruefen bislang IMMER die Migrationsverzeichnisse, unabhaengig vom Modus - im
Rettungsbetrieb meldete "status" so faelschlich "MISSING", waehrend
rescue-nocreds voll war, oder umgekehrt "vorhanden", waehrend die Rettung
nichts hatte. Ein falsches "MISSING" dort verleitet dazu, auf mit-wlan
umzuschalten - und dann liefert die Rettung tatsaechlich Abbilder mit dem
WLAN-Passwort aus. imageset_dir() nimmt jetzt den Modus als Parameter
(Vorgabe: current_mode()), dieselbe Unterscheidung wie im Panel.

Befund 2: images() griff weiter flach auf $IMAGE_DIR zu, wo seit dem
Deploy-Umbau nichts mehr liegt - "recovery on" warnte deshalb bei JEDEM Start
"answers everything with 404". Ersetzt durch imageset_images(), das dem
Bildsatz-Umschalter UND dem Modus folgt.

Befund 3 (CLI-Seite): current_mode() liest die neue dauerhafte
LAST_MODE_FILE statt der ephemeren RUN_DIR/mode - write_mode() schreibt jetzt
beide (siehe display.py-Commit fuer die Panel-Seite derselben Ursache).

tests/test_cli.sh legte weiterhin die alte flache Rettungsablage an
(images/ninlight_foo_ota.img) - die Sandbox hat jetzt eigene
rescue-wlan/rescue-nocreds-Verzeichnisse wie ein echter Pi nach diesem
Umschalter, und run_cli() setzt NINLIGHT_LAST_MODE_FILE auf einen
Sandbox-Pfad. Mehrere bestehende Bildsatz-Szenarien liefen unbemerkt gegen
den Migrationssatz, obwohl kein Modus gesetzt war (Vorgabe: recovery) -
angepasst, damit sie den tatsaechlich geltenden Satz pruefen.
This commit is contained in:
Michael Sauer
2026-09-23 21:59:25 +02:00
parent 1562a7983a
commit f31ef879ee
2 changed files with 108 additions and 29 deletions
+94 -23
View File
@@ -130,8 +130,33 @@ need_profile() {
} }
} }
images() { # --- Modus lesen/schreiben (Fixrunde 1, Befund 3) -----------------------------------
find "$IMAGE_DIR" -maxdepth 1 -name 'ninlight_*_ota.img' 2>/dev/null | sort #
# RUN_DIR/mode (write_mode() unten schreibt sie zusaetzlich) taugt NICHT als Quelle
# fuer "welcher Modus gilt gerade/als naechstes", solange die Station AUS ist: die Unit
# setzt RuntimeDirectoryPreserve=restart, das erhaelt /run/ninlight-station nur ueber
# einen "systemctl restart" (das, was "recovery on"/"migrate on" bei einem schon
# laufenden Dienst ausloesen), NICHT ueber einen echten "systemctl stop" - und genau
# den fuehrt "ninlight-station off" aus. Fehlt die Datei, gilt ueberall stillschweigend
# "recovery" (derselbe sichere Vorgabewert wie beim Bildsatz) - eine fruehere Fassung
# dieses Skripts UND von display.py hat das mit "die Datei bleibt bei jedem Zustand
# erhalten" verwechselt.
#
# LAST_MODE_FILE ist deshalb wie IMAGESET_FILE eine EIGENE, dauerhafte Ablage unter
# /var/lib - dieselbe Datei, die display.py:LAST_MODE_FILE liest (Panel und CLI muessen
# sich hier einig sein, sonst zeigt das eine "Rettung: MISSING" waehrend das andere
# "Migration: 3 image(s)" meldet).
LAST_MODE_FILE=${NINLIGHT_LAST_MODE_FILE:-/var/lib/ninlight-station/mode}
# Der zuletzt angeforderte Modus, oder "recovery" bei fehlender/unlesbarer/unbekannter
# Datei - dieselbe Vorgabe und dieselbe Begruendung wie imageset_get() unten. Scheitert
# nie: eine kaputte Datei darf weder "status" noch "bildsatz" aufhalten.
current_mode() {
_m=$(cat "$LAST_MODE_FILE" 2>/dev/null | tr -d ' \t\r\n') || true
case "$_m" in
recovery|migration) printf '%s' "$_m" ;;
*) printf '%s' "recovery" ;;
esac
} }
# --- Bildsatz lesen, schreiben, benennen -------------------------------------------- # --- Bildsatz lesen, schreiben, benennen --------------------------------------------
@@ -153,12 +178,27 @@ imageset_get() {
esac esac
} }
# Das Verzeichnis zum Namen des Bildsatzes ($1). # Das Verzeichnis zum Namen des Bildsatzes ($1), fuer den Modus $2 (Vorgabe:
# current_mode()). Rettung und Migration liegen in getrennten Verzeichnispaaren
# (server.py:RESCUE_SET_DIRS/IMAGE_SET_DIRS begruendet das) - dieselbe Unterscheidung
# wie display.py:_read_imageset(). Fixrunde 1, Befund 1: vor dieser Aenderung pruefte
# dieses Skript hier IMMER die Migrationsverzeichnisse, auch im Rettungsbetrieb - ein
# falsches "MISSING" dort verleitet dazu, auf mit-wlan umzuschalten, und DANN liefert
# die Rettung tatsaechlich Abbilder mit dem WLAN-Passwort aus.
imageset_dir() { imageset_dir() {
case "$1" in _name=$1
mit-wlan) printf '%s' "$IMAGE_DIR/migrate-wlan" ;; _mode=${2:-$(current_mode)}
*) printf '%s' "$IMAGE_DIR/migrate-nocreds" ;; if [ "$_mode" = "recovery" ]; then
esac case "$_name" in
mit-wlan) printf '%s' "$IMAGE_DIR/rescue-wlan" ;;
*) printf '%s' "$IMAGE_DIR/rescue-nocreds" ;;
esac
else
case "$_name" in
mit-wlan) printf '%s' "$IMAGE_DIR/migrate-wlan" ;;
*) printf '%s' "$IMAGE_DIR/migrate-nocreds" ;;
esac
fi
} }
imageset_label() { imageset_label() {
@@ -179,8 +219,14 @@ imageset_set() {
sudo mv -f "$_tmp" "$IMAGESET_FILE" sudo mv -f "$_tmp" "$IMAGESET_FILE"
} }
migrate_images() { # Die Abbilder des eingestellten Bildsatzes fuer den Modus $1 (Vorgabe: current_mode()).
find "$(imageset_dir "$(imageset_get)")" -maxdepth 1 -name '*.img' 2>/dev/null | sort # Ersetzt das fruehere migrate_images() (nur Migration) UND das fruehere images() (immer
# flach in $IMAGE_DIR, Fixrunde 1, Befund 2: nach dem Deploy-Umbau liegt dort nichts
# mehr - recovery_on() meldete seither bei JEDEM Start faelschlich "answers everything
# with 404", ununterscheidbar vom echten Fehlerfall).
imageset_images() {
_mode=${1:-$(current_mode)}
find "$(imageset_dir "$(imageset_get)" "$_mode")" -maxdepth 1 -name '*.img' 2>/dev/null | sort
} }
# "bildsatz" ohne Argument: nur berichten. Mit Argument: umschalten. # "bildsatz" ohne Argument: nur berichten. Mit Argument: umschalten.
@@ -204,6 +250,9 @@ bildsatz_cmd() {
} }
echo "Image set: $(imageset_label "$_want")" echo "Image set: $(imageset_label "$_want")"
[ "$_now" = "$_want" ] && echo " (was already set)" [ "$_now" = "$_want" ] && echo " (was already set)"
# Der Umschalter gilt fuer BEIDE Betriebsarten - hier wird deshalb der Satz gemeldet,
# der fuer den Modus zaehlt, in dem die Station gerade steht bzw. als naechstes
# anlaufen wuerde (current_mode()), nicht pauschal die Migration.
_dir=$(imageset_dir "$_want") _dir=$(imageset_dir "$_want")
if [ "$(find "$_dir" -maxdepth 1 -name '*.img' 2>/dev/null | wc -l | tr -d ' ')" -eq 0 ]; then if [ "$(find "$_dir" -maxdepth 1 -name '*.img' 2>/dev/null | wc -l | tr -d ' ')" -eq 0 ]; then
# Kein stiller Rueckfall auf den anderen Satz - server.py liefert dann gar nichts # Kein stiller Rueckfall auf den anderen Satz - server.py liefert dann gar nichts
@@ -212,18 +261,20 @@ bildsatz_cmd() {
echo "Warning: $_dir missing or empty - this image set serves NOTHING. Run tools/station/deploy.sh again." >&2 echo "Warning: $_dir missing or empty - this image set serves NOTHING. Run tools/station/deploy.sh again." >&2
fi fi
if [ "$_want" = "mit-wlan" ]; then if [ "$_want" = "mit-wlan" ]; then
echo "Caution: migrated lamps join the Wi-Fi from config.local.cmake right away - including lamps that are not yours and got picked up in automatic mode." >&2 echo "Caution: any lamp migrated OR rescued while this is set joins the Wi-Fi from config.local.cmake right away - including lamps that are not yours and got picked up in automatic mode." >&2
fi fi
} }
# Die zwei Zeilen, die "status" und "bildsatz" ohne Argument gemeinsam ausgeben. # Die zwei Zeilen, die "status" und "bildsatz" ohne Argument gemeinsam ausgeben - fuer
# den Modus, in dem die Station gerade steht bzw. als naechstes anlaufen wuerde.
imageset_status_lines() { imageset_status_lines() {
_mode=$(current_mode)
_set=$(imageset_get) _set=$(imageset_get)
_dir=$(imageset_dir "$_set") _dir=$(imageset_dir "$_set" "$_mode")
# "Vorhanden" heisst: mindestens ein Image darin - dieselbe Regel wie # "Vorhanden" heisst: mindestens ein Image darin - dieselbe Regel wie
# server.py:migrate_set_present() und display.py:_read_imageset(). Ein leeres # server.py:migrate_set_present()/rescue_set_present() und display.py:_read_imageset().
# Verzeichnis liefert genauso nichts aus wie ein fehlendes. # Ein leeres Verzeichnis liefert genauso nichts aus wie ein fehlendes.
_n=$(migrate_images | wc -l | tr -d ' ') _n=$(imageset_images "$_mode" | wc -l | tr -d ' ')
if [ "$_n" -gt 0 ]; then if [ "$_n" -gt 0 ]; then
_state="$_n image(s)" _state="$_n image(s)"
else else
@@ -293,12 +344,22 @@ ap_switch() {
} }
# Schreibt $RUN_DIR/mode atomar mit 0644 (Temp-Datei im selben Verzeichnis, dann # Schreibt $RUN_DIR/mode atomar mit 0644 (Temp-Datei im selben Verzeichnis, dann
# umbenennen) - server.py liest sie bei jedem Dienststart per --mode-file. # umbenennen) - server.py liest sie bei jedem Dienststart per --mode-file. ZUSAETZLICH
# dieselbe Zeichenkette nach $LAST_MODE_FILE (dauerhaft, siehe dort) - RUN_DIR/mode
# ueberlebt nur einen "systemctl restart", nicht das "systemctl stop" von
# "ninlight-station off" (Fixrunde 1, Befund 3). Beide Schreibvorgaenge muessen
# gelingen: schlaegt der dauerhafte fehl, wuerden Panel und CLI nach einem "off" auf
# den falschen (naemlich den vorherigen) Modus zurueckfallen, ohne dass das hier
# auffiele.
write_mode() { write_mode() {
sudo mkdir -p "$RUN_DIR" sudo mkdir -p "$RUN_DIR"
_tmp="$RUN_DIR/.mode-$$" _tmp="$RUN_DIR/.mode-$$"
printf '%s' "$1" | sudo tee "$_tmp" >/dev/null && sudo chmod 0644 "$_tmp" || return 1 printf '%s' "$1" | sudo tee "$_tmp" >/dev/null && sudo chmod 0644 "$_tmp" || return 1
sudo mv -f "$_tmp" "$RUN_DIR/mode" sudo mv -f "$_tmp" "$RUN_DIR/mode" || return 1
sudo mkdir -p "$(dirname "$LAST_MODE_FILE")"
_tmp2="$(dirname "$LAST_MODE_FILE")/.mode-$$"
printf '%s' "$1" | sudo tee "$_tmp2" >/dev/null && sudo chmod 0644 "$_tmp2" || return 1
sudo mv -f "$_tmp2" "$LAST_MODE_FILE"
} }
# Schreibt $RUN_DIR/control.json atomar mit 0644 - dasselbe Muster (Temp-Datei im # Schreibt $RUN_DIR/control.json atomar mit 0644 - dasselbe Muster (Temp-Datei im
@@ -612,8 +673,12 @@ autooff_arm_if_requested() {
recovery_on() { recovery_on() {
parse_for_option recovery "$@" parse_for_option recovery "$@"
need_profile "$AP_CONNECTION" need_profile "$AP_CONNECTION"
n=$(images | wc -l | tr -d ' ') # Explizit "recovery" statt current_mode(): dieser Aufruf ENTSCHEIDET gerade, dass
[ "$n" -gt 0 ] || echo "Warning: $IMAGE_DIR holds no image - the station answers everything with 404" >&2 # der naechste Start Rettung ist - write_mode() darunter schreibt das erst gleich.
# current_mode() koennte hier noch "migration" von einem vorherigen Lauf zeigen.
_setdir=$(imageset_dir "$(imageset_get)" recovery)
n=$(imageset_images recovery | wc -l | tr -d ' ')
[ "$n" -gt 0 ] || echo "Warning: $_setdir holds no image - the station answers everything with 404" >&2
ap_switch "$AP_CONNECTION" ap_switch "$AP_CONNECTION"
write_mode "recovery" write_mode "recovery"
start_and_verify "$AP_CONNECTION" "recovery" start_and_verify "$AP_CONNECTION" "recovery"
@@ -656,8 +721,10 @@ migrate_on() {
[ "$_for_seen" -eq 1 ] || _for_minutes="" [ "$_for_seen" -eq 1 ] || _for_minutes=""
need_profile "$MIGRATE_AP_CONNECTION" need_profile "$MIGRATE_AP_CONNECTION"
_set=$(imageset_get) _set=$(imageset_get)
_setdir=$(imageset_dir "$_set") # Explizit "migration", aus demselben Grund wie in recovery_on(): dieser Aufruf legt
n=$(migrate_images | wc -l | tr -d ' ') # den naechsten Modus gerade erst fest.
_setdir=$(imageset_dir "$_set" migration)
n=$(imageset_images migration | wc -l | tr -d ' ')
[ "$n" -gt 0 ] || echo "Warning: $_setdir holds no migration images - the station answers everything with 404" >&2 [ "$n" -gt 0 ] || echo "Warning: $_setdir holds no migration images - the station answers everything with 404" >&2
# Faehrt ninlight-recovery (falls es laeuft) herunter, BEVOR qconnex-firmware # Faehrt ninlight-recovery (falls es laeuft) herunter, BEVOR qconnex-firmware
# hochkommt, und prueft danach nach, dass wirklich nur eines aktiv ist. # hochkommt, und prueft danach nach, dass wirklich nur eines aktiv ist.
@@ -1052,8 +1119,12 @@ PY
autooff_status_line autooff_status_line
printf 'wlan0 : %s\n' "$(nmcli -t --escape no -f GENERAL.CONNECTION device show wlan0 2>/dev/null | cut -d: -f2-)" printf 'wlan0 : %s\n' "$(nmcli -t --escape no -f GENERAL.CONNECTION device show wlan0 2>/dev/null | cut -d: -f2-)"
printf 'Address : %s\n' "$(ip -4 -br addr show wlan0 2>/dev/null | awk '{print $3}')" printf 'Address : %s\n' "$(ip -4 -br addr show wlan0 2>/dev/null | awk '{print $3}')"
# Die Rettungsabbilder des eingestellten Bildsatzes - unabhaengig von $_modus (der
# Migrationsbildsatz hat kein passendes Trailer-Format). Fixrunde 1, Befund 2:
# frueher stand hier "images" (flach in $IMAGE_DIR) - dort liegt seit dem
# Deploy-Umbau nichts mehr.
echo "Images :" echo "Images :"
images | while read -r f; do imageset_images recovery | while read -r f; do
printf ' %-34s %s\n' "$(basename "$f")" \ printf ' %-34s %s\n' "$(basename "$f")" \
"$(python3 - "$f" <<'PY' "$(python3 - "$f" <<'PY'
import pathlib, sys import pathlib, sys
@@ -1092,7 +1163,7 @@ display_cmd() {
usage() { usage() {
echo "Usage: ninlight-station on [--for <minutes>]|recovery {on [--for <minutes>]|off}|migrate {on [--listen] [--for <minutes>]|off}|arm [<target>]|listen|bildsatz [ohne-wlan|mit-wlan]|renew [<minutes>]|hold|display {test|clear|off}|off|status" >&2 echo "Usage: ninlight-station on [--for <minutes>]|recovery {on [--for <minutes>]|off}|migrate {on [--listen] [--for <minutes>]|off}|arm [<target>]|listen|bildsatz [ohne-wlan|mit-wlan]|renew [<minutes>]|hold|display {test|clear|off}|off|status" >&2
echo "" >&2 echo "" >&2
echo " bildsatz Switch: which set of migration images is served." >&2 echo " bildsatz Switch: which set of recovery/migration images is served." >&2
echo " Without an argument it only reports. 'ohne-wlan' (default) serves" >&2 echo " Without an argument it only reports. 'ohne-wlan' (default) serves" >&2
echo " the builds from tools/build_nocreds.sh - the migrated lamp comes" >&2 echo " the builds from tools/build_nocreds.sh - the migrated lamp comes" >&2
echo " up in its own onboarding access point. 'mit-wlan' serves the" >&2 echo " up in its own onboarding access point. 'mit-wlan' serves the" >&2
+14 -6
View File
@@ -263,12 +263,19 @@ setup_sandbox() {
local sandbox=$1 unitfile=${2:-$REAL_UNIT} local sandbox=$1 unitfile=${2:-$REAL_UNIT}
rm -rf "$sandbox" rm -rf "$sandbox"
mkdir -p "$sandbox/run" "$sandbox/images/migrate-nocreds" "$sandbox/images/migrate-wlan" \ mkdir -p "$sandbox/run" "$sandbox/images/migrate-nocreds" "$sandbox/images/migrate-wlan" \
"$sandbox/images/rescue-nocreds" "$sandbox/images/rescue-wlan" \
"$sandbox/bin" "$sandbox/nmstate" "$sandbox/lib/display" "$sandbox/var" "$sandbox/bin" "$sandbox/nmstate" "$sandbox/lib/display" "$sandbox/var"
# Je ein Image je Bildsatz - "vorhanden" heisst fuer CLI, Server und Anzeige # Je ein Image je Bildsatz - "vorhanden" heisst fuer CLI, Server und Anzeige
# gleichermassen "mindestens ein Image darin". # gleichermassen "mindestens ein Image darin". Getrennte Verzeichnispaare fuer
# Rettung (rescue-*) und Migration (migrate-*), seit der Bildsatz-Umschalter auch
# die Rettung betrifft (Fixrunde 1, Befund 1/2) - VORHER lag hier ein flaches
# "images/ninlight_foo_ota.img", das server.py/deploy.sh seit diesem Umschalter
# nicht mehr benutzen; eine Testvorrichtung, die weiter diese alte Welt aufbaut,
# haette genau die beiden Befunde verdeckt.
echo "ohne" >"$sandbox/images/migrate-nocreds/foo_dev.img" echo "ohne" >"$sandbox/images/migrate-nocreds/foo_dev.img"
echo "mit" >"$sandbox/images/migrate-wlan/foo_dev.img" echo "mit" >"$sandbox/images/migrate-wlan/foo_dev.img"
echo "dummy" >"$sandbox/images/ninlight_foo_ota.img" echo "ohne" >"$sandbox/images/rescue-nocreds/ninlight_foo_ota.img"
echo "mit" >"$sandbox/images/rescue-wlan/ninlight_foo_ota.img"
# NINLIGHT_STATION_LIB zeigt auf diese Sandbox statt auf tools/station selbst. # NINLIGHT_STATION_LIB zeigt auf diese Sandbox statt auf tools/station selbst.
# products.py wird gebraucht (arm prueft das Ziel dagegen) und deshalb echt kopiert; # products.py wird gebraucht (arm prueft das Ziel dagegen) und deshalb echt kopiert;
@@ -342,6 +349,7 @@ run_cli() {
NINLIGHT_RUN_DIR="$sandbox/run" \ NINLIGHT_RUN_DIR="$sandbox/run" \
NINLIGHT_STATION_LIB="$sandbox/lib" \ NINLIGHT_STATION_LIB="$sandbox/lib" \
NINLIGHT_IMAGESET_FILE="$sandbox/var/imageset" \ NINLIGHT_IMAGESET_FILE="$sandbox/var/imageset" \
NINLIGHT_LAST_MODE_FILE="$sandbox/var/last-mode" \
"$CLI" "$@" "$CLI" "$@"
} }
@@ -1278,7 +1286,7 @@ RC=$?
set -e set -e
[ "$RC" -eq 0 ] && pass "Exit-Code 0" || fail "Exit-Code $RC: $OUT" [ "$RC" -eq 0 ] && pass "Exit-Code 0" || fail "Exit-Code $RC: $OUT"
echo "$OUT" | grep -q "ohne-wlan" && pass "ohne Datei gilt 'ohne-wlan'" || fail "Vorgabe ist nicht 'ohne-wlan': $OUT" echo "$OUT" | grep -q "ohne-wlan" && pass "ohne Datei gilt 'ohne-wlan'" || fail "Vorgabe ist nicht 'ohne-wlan': $OUT"
echo "$OUT" | grep -q "migrate-nocreds" && pass "und das zugehoerige Verzeichnis wird genannt" || fail "Verzeichnis fehlt in der Ausgabe: $OUT" echo "$OUT" | grep -q "rescue-nocreds" && pass "und das zugehoerige Verzeichnis wird genannt (Vorgabemodus: recovery)" || fail "Verzeichnis fehlt in der Ausgabe: $OUT"
[ ! -e "$SBX/var/imageset" ] && pass "das blosse Berichten legt keine Datei an" || fail "'bildsatz' ohne Argument hat geschrieben" [ ! -e "$SBX/var/imageset" ] && pass "das blosse Berichten legt keine Datei an" || fail "'bildsatz' ohne Argument hat geschrieben"
echo echo
@@ -1323,7 +1331,7 @@ setup_sandbox "$SBX"
printf 'voellig-anderes\n' >"$SBX/var/imageset" printf 'voellig-anderes\n' >"$SBX/var/imageset"
OUT=$(run_cli "$SBX" bildsatz 2>&1) OUT=$(run_cli "$SBX" bildsatz 2>&1)
echo "$OUT" | grep -q "ohne-wlan" && pass "kaputter Inhalt -> 'ohne-wlan'" || fail "kaputter Inhalt fuehrte nicht auf die Vorgabe: $OUT" echo "$OUT" | grep -q "ohne-wlan" && pass "kaputter Inhalt -> 'ohne-wlan'" || fail "kaputter Inhalt fuehrte nicht auf die Vorgabe: $OUT"
echo "$OUT" | grep -q "migrate-nocreds" && pass "und das Verzeichnis des sicheren Satzes" || fail "falsches Verzeichnis: $OUT" echo "$OUT" | grep -q "rescue-nocreds" && pass "und das Verzeichnis des sicheren Satzes (Vorgabemodus: recovery)" || fail "falsches Verzeichnis: $OUT"
# Der Bediener muss erfahren, dass sein Eintrag NICHT gewirkt hat - sonst haelt er die # Der Bediener muss erfahren, dass sein Eintrag NICHT gewirkt hat - sonst haelt er die
# Station fuer umgeschaltet. # Station fuer umgeschaltet.
echo "$OUT" | grep -q "unknown setting 'voellig-anderes'" \ echo "$OUT" | grep -q "unknown setting 'voellig-anderes'" \
@@ -1340,7 +1348,7 @@ echo
echo "=== Bildsatz E: ein gewaehlter, aber fehlender Satz wird beim Umschalten UND im Status gemeldet ===" echo "=== Bildsatz E: ein gewaehlter, aber fehlender Satz wird beim Umschalten UND im Status gemeldet ==="
SBX="$TMPROOT/bs5" SBX="$TMPROOT/bs5"
setup_sandbox "$SBX" setup_sandbox "$SBX"
rm -rf "$SBX/images/migrate-wlan" rm -rf "$SBX/images/rescue-wlan" # Vorgabemodus (ohne vorheriges "on") ist recovery
set +e set +e
ERR=$(run_cli "$SBX" bildsatz mit-wlan 2>&1 >/dev/null) ERR=$(run_cli "$SBX" bildsatz mit-wlan 2>&1 >/dev/null)
RC=$? RC=$?
@@ -1354,7 +1362,7 @@ echo
echo "=== Bildsatz F: ein LEERES Verzeichnis zaehlt genauso als fehlend ===" echo "=== Bildsatz F: ein LEERES Verzeichnis zaehlt genauso als fehlend ==="
SBX="$TMPROOT/bs6" SBX="$TMPROOT/bs6"
setup_sandbox "$SBX" setup_sandbox "$SBX"
rm -f "$SBX/images/migrate-nocreds"/*.img rm -f "$SBX/images/rescue-nocreds"/*.img # Vorgabemodus (ohne vorheriges "on") ist recovery
OUT=$(run_cli "$SBX" status 2>&1) OUT=$(run_cli "$SBX" status 2>&1)
echo "$OUT" | grep -q "MISSING" && pass "ein leeres Bildsatzverzeichnis wird als fehlend gemeldet" || fail "ein leerer Satz gilt als vorhanden: $OUT" echo "$OUT" | grep -q "MISSING" && pass "ein leeres Bildsatzverzeichnis wird als fehlend gemeldet" || fail "ein leerer Satz gilt als vorhanden: $OUT"