Drei zusammenhaengende Punkte aus dem zweiten echten Hardware-Test
(02.09.2026):
1. "Das backend40-Script/Partitionierung zeigt viele Zeilen Ausgaben...
Nach dem Entpacken kommen wieder sehr viele Zeilen Ausgaben" - neue
run_module_backend() (utils.sh) faengt jetzt auch 40_backend.sh ab
(Partitionieren/Formatieren/chroot-Fixup/Bootloader/Postinstall
verborgen wie jedes andere Modul), OHNE animierten Kreisel (statischer
Titel, da das Modul seinen eigenen Fortschritt zeigt). Der Download-
Fortschrittsbalken selbst bleibt sichtbar: curl schreibt ihn bei
aktivem TUXFLOTTE_TTY_LIVE direkt auf /dev/tty1, umgeht damit gezielt
die stdout/stderr-Umleitung des Moduls (image_deploy.sh).
2. "Wenn ich... mit Enter den Neustart auslösen möchte, kommt es zu
zahlreichen squashfs-Fehlern, weil das Dateisystem nicht mehr da ist."
- "toram" im Bootappend (build_boot_medium.sh) kopiert das gesamte
Boot-Medium beim Start einmalig in eine Tmpfs; danach ist der Stick fuer
den laufenden Betrieb komplett irrelevant, ein Ziehen jederzeit
gefahrlos moeglich - vorher blieb das laufende System per Squashfs+
Loop-Mount direkt vom physischen Medium abhaengig.
3. Neues Boot-Banner (pics/tuxflotte-terminal-80neu.txt).
Beim eigenen Testen von Punkt 1 zwei echte Bugs gefunden+behoben (siehe
Kommentare in image_deploy.sh): "pipeline || true" ueberschreibt
PIPESTATUS mit dem einelementigen Ergebnis von "true", sobald die
Pipeline fehlschlaegt - traf live bei einer echten Netzwerkunterbrechung
waehrend des Downloads auf ("pipe_status[1]: unbound variable" unter
"set -u"). Der Wechsel auf eine "if"-Bedingung (set -e-Ausnahme ohne ein
zweites Kommando) reichte allein nicht, PIPESTATUS blieb bei einem
echten, mitten im Transfer abgebrochenen curl|tar manchmal trotzdem
unvollstaendig - jetzt zusaetzlich robust mit ":-1"-Fallback direkt auf
den einzelnen Indizes statt einer vorausgesetzten vollstaendigen Kopie.
Live in QEMU verifiziert: neues Banner + verborgenes Partitionier-Rauschen
+ sichtbarer Fortschrittsbalken bestaetigt (Screenshot). Eine echte,
waehrend des Testens aufgetretene Netzwerk-Durchsatzverschlechterung
(anode nur noch ~4,6 MB/s, unabhaengig von diesem Code) verhinderte einen
weiteren vollstaendigen Erfolgsdurchlauf in dieser Session - der
pipe_status-Fix selbst wurde aber genau durch diese Unterbrechung bestaetigt
(sauberer [FEHLER]-Abbruch mit klarer Meldung statt Bash-Crash). toram
selbst (Boot bis zum Auto-Modus-Start, Konfiguration/Partitionierung liefen
durch) und die Rauschen-Unterdrueckung sind bestaetigt; die volle
Stick-waehrend-Reboot-Sequenz bleibt fuer den naechsten echten
Hardware-Test zu bestaetigen.
183 lines
5.7 KiB
Bash
183 lines
5.7 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
load_config() {
|
|
local config_file="$1"
|
|
|
|
if [[ -f "$config_file" ]]; then
|
|
# shellcheck disable=SC1090
|
|
source "$config_file"
|
|
log_info "Konfiguration geladen: $config_file"
|
|
else
|
|
log_warn "Keine Konfiguration gefunden: $config_file"
|
|
fi
|
|
}
|
|
|
|
# Module mit einem eigenen Modus (weder die generische Kreisel/Haken-
|
|
# Kompaktdarstellung noch voll verbose): 40_backend.sh ist der mit Abstand
|
|
# langlaeufigste Schritt (Minuten statt Sekunden) - Partitionieren/
|
|
# Formatieren/chroot-Fixup/Bootloader/Postinstall sind fuer den Kunden
|
|
# ebenso uninteressant wie bei jedem anderen Modul, ABER der Download-
|
|
# Fortschrittsbalken (image_deploy_extract_image_from_url()) soll trotzdem
|
|
# sichtbar bleiben - siehe run_module_backend().
|
|
declare -a TUXFLOTTE_BACKEND_MODULES=(40_backend.sh)
|
|
|
|
_tuxflotte_module_is_backend() {
|
|
local module_name="$1"
|
|
local candidate
|
|
|
|
for candidate in "${TUXFLOTTE_BACKEND_MODULES[@]}"; do
|
|
[[ "${candidate}" == "${module_name}" ]] && return 0
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
# Kompakte Modul-Ausfuehrung fuer den unbeaufsichtigten Auto-Modus (siehe
|
|
# log_module_title()/log_module_ok()/log_module_failed() in logging.sh):
|
|
# Modul laeuft im Hintergrund, waehrenddessen ein Kreisel auf derselben
|
|
# Zeile, am Ende entweder ein gruener Haken (Erfolg, Detailausgabe nur ins
|
|
# Logfile) oder ein rotes Kreuz + die volle mitgeschnittene Ausgabe auf der
|
|
# Konsole (Fehlschlag - Fehlersuche darf nie schlechter werden als vorher).
|
|
run_module_quiet() {
|
|
local module="$1"
|
|
local module_name
|
|
module_name="$(basename "${module}")"
|
|
|
|
log_module_title "${module_name}"
|
|
local title="${TUXFLOTTE_CURRENT_TITLE}"
|
|
|
|
local output_file
|
|
output_file="$(mktemp)"
|
|
|
|
# shellcheck disable=SC1090
|
|
"${module}" >"${output_file}" 2>&1 &
|
|
local pid=$!
|
|
|
|
if _tuxflotte_console_is_live; then
|
|
printf '%s ' "${title}"
|
|
local frame_index=0
|
|
local frame_count="${#_TUXFLOTTE_SPINNER_FRAMES[@]}"
|
|
while kill -0 "${pid}" 2>/dev/null; do
|
|
printf '\r%s %s' "${title}" "${_TUXFLOTTE_SPINNER_FRAMES[$((frame_index % frame_count))]}"
|
|
frame_index=$((frame_index + 1))
|
|
sleep 0.1
|
|
done
|
|
fi
|
|
|
|
# "wait || status=$?" statt eines nackten "wait"-Aufrufs - genau das
|
|
# bekannte &&/||-Gegenstueck zu "set -e" (siehe die mount-Bind-Lehre in
|
|
# image_deploy.sh), hier bewusst genutzt, um den echten Exit-Code sauber
|
|
# auszuwerten statt das ganze Skript sofort abzubrechen.
|
|
local status=0
|
|
wait "${pid}" || status=$?
|
|
|
|
if [[ "${status}" -eq 0 ]]; then
|
|
log_module_ok "${title}"
|
|
else
|
|
log_module_failed "${title}"
|
|
echo
|
|
cat "${output_file}"
|
|
echo
|
|
fi
|
|
|
|
[[ -n "${TUXFLOTTE_LOG_FILE:-}" ]] && cat "${output_file}" >>"${TUXFLOTTE_LOG_FILE}" 2>/dev/null
|
|
|
|
rm -f "${output_file}"
|
|
|
|
return "${status}"
|
|
}
|
|
|
|
# Wie run_module_quiet(), aber ohne animierten Kreisel: der Titel wird
|
|
# einmalig mit Zeilenumbruch ausgegeben (nicht per "\r" ueberschrieben) und
|
|
# das Modul laeuft im Vordergrund (kein Hintergrundprozess noetig, da kein
|
|
# Kreisel dagegen ankaempft). Grund: image_deploy_extract_image_from_url()
|
|
# schreibt den Download-Fortschrittsbalken bei aktivem TUXFLOTTE_TTY_LIVE
|
|
# direkt auf /dev/tty1 (siehe dort) - das umgeht die stdout/stderr-
|
|
# Umleitung dieser Funktion bewusst, landet also auf einer eigenen,
|
|
# unbenutzten Zeile direkt unter dem Titel, statt mit einem "\r"-Kreisel
|
|
# um dieselbe Zeile zu konkurrieren.
|
|
#
|
|
# Nutzer-Feedback (01.09.2026, zweiter echter Hardware-Test): "Das
|
|
# backend40-Script/Partitionierung zeigt viele Zeilen Ausgaben... Der
|
|
# Fortschrittsbalken ist super! Nach dem Entpacken kommen wieder sehr
|
|
# viele Zeilen Ausgaben" - Partitionieren/Formatieren/chroot-Fixup/
|
|
# Bootloader/Postinstall sollen wie jedes andere Modul verborgen bleiben,
|
|
# nur der Fortschrittsbalken bleibt sichtbar.
|
|
run_module_backend() {
|
|
local module="$1"
|
|
local module_name
|
|
module_name="$(basename "${module}")"
|
|
|
|
log_module_title "${module_name}"
|
|
local title="${TUXFLOTTE_CURRENT_TITLE}"
|
|
printf '%s ...\n' "${title}"
|
|
|
|
local output_file
|
|
output_file="$(mktemp)"
|
|
|
|
local status=0
|
|
# shellcheck disable=SC1090
|
|
"${module}" >"${output_file}" 2>&1 || status=$?
|
|
|
|
if [[ "${status}" -eq 0 ]]; then
|
|
printf '%s \033[1;32m[OK]\033[0m\n' "${title}"
|
|
else
|
|
printf '%s \033[1;31m[FEHLER]\033[0m\n' "${title}"
|
|
echo
|
|
cat "${output_file}"
|
|
echo
|
|
fi
|
|
|
|
[[ -n "${TUXFLOTTE_LOG_FILE:-}" ]] && cat "${output_file}" >>"${TUXFLOTTE_LOG_FILE}" 2>/dev/null
|
|
|
|
rm -f "${output_file}"
|
|
|
|
return "${status}"
|
|
}
|
|
|
|
run_module() {
|
|
local module="$1"
|
|
local mode="${2:-normal}"
|
|
local module_name
|
|
module_name="$(basename "$module")"
|
|
|
|
[[ -f "$module" ]] || error_exit "Modul nicht gefunden: $module"
|
|
|
|
if [[ "${DRY_RUN:-false}" == true && "$mode" != "always" ]]; then
|
|
log_step "${module_name}"
|
|
log_warn "Dry-Run: Modul übersprungen: $module"
|
|
return 0
|
|
fi
|
|
|
|
# Kompakte Kreisel/Haken-Darstellung nur im echten Auto-Modus: nur dort
|
|
# ist sichergestellt, dass kein Modul interaktiv nach Eingaben fragt
|
|
# (12_enrollment_auth.sh/20_profile_selection.sh/25_installation_confirm.sh
|
|
# pruefen TUXFLOTTE_AUTO_MODE selbst und ueberspringen ihre Prompts) -
|
|
# ein Prompt-Text waere sonst zusammen mit der restlichen Ausgabe in
|
|
# output_file gefangen und fuer die Person vor dem Geraet unsichtbar.
|
|
if [[ "${TUXFLOTTE_AUTO_MODE:-false}" == "true" ]]; then
|
|
if _tuxflotte_module_is_backend "${module_name}"; then
|
|
run_module_backend "$module"
|
|
else
|
|
run_module_quiet "$module"
|
|
fi
|
|
return "$?"
|
|
fi
|
|
|
|
log_step "${module_name}"
|
|
log_info "Starte Modul: ${module_name}"
|
|
|
|
# shellcheck disable=SC1090
|
|
"$module"
|
|
|
|
log_success "Modul abgeschlossen: ${module_name}"
|
|
}
|
|
|
|
require_root() {
|
|
[[ "$EUID" -eq 0 ]] || error_exit "Installer muss als root ausgeführt werden."
|
|
}
|
|
|
|
command_exists() {
|
|
command -v "$1" >/dev/null 2>&1
|
|
}
|