From 8615d9fde1e41457a492773123b7970d5f689af9 Mon Sep 17 00:00:00 2001 From: Thomas Stallinger Date: Tue, 1 Sep 2026 15:46:18 +0200 Subject: [PATCH] Konsole: kompakte Kreisel/Haken-Anzeige statt Log-Wand + Kernel-Zeitstempel entfernt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nutzer-Feedback (01.09.2026, echter Hardware-Test) mit mehreren zusammenhaengenden Konsolen-UX-Punkten: - "Die Darstellung des Abarbeitens der Skripte und Module ist noch nicht schön... Modul XY läuft (kreiselnde Symbole)... gründer Haken als erledigt" - neue run_module_quiet() (utils.sh) fuehrt ein Modul im Hintergrund aus, zeigt waehrenddessen einen Kreisel auf derselben Zeile, am Ende [OK] (gruen) oder [FEHLER] (rot) + volle mitgeschnittene Ausgabe bei einem Fehlschlag. Nur im echten Auto-Modus aktiv (dort fragt kein Modul interaktiv nach) - 40_backend.sh bleibt bewusst verbose (TUXFLOTTE_VERBOSE_MODULES), da dort der neue Download-Fortschrittsbalken sichtbar bleiben soll. - "Bei Entpacken und schreiben des Archivs, kann man das einen Fortschrittsbalken... anzeigen lassen?" - curl "--silent" durch "--progress-bar" ersetzt (image_deploy.sh). - "Der Kernel Zeitstempel ist für den Kunden nicht interessant, sondern nur verwirrend." - eigentliche Ursache war nicht der GRUB-Splash (separater Commit), sondern StandardOutput=journal+console im systemd-Unit: journald spiegelt Konsolenausgaben im kmsg-Stil mit monotonem "[ 12.345678]"-Zeitstempel, sah aus wie ein Kernel-Log. Jetzt "StandardOutput/Error=console" (direkt an /dev/tty1, kein journald) - journalctl zeigt dadurch nur noch Dienst-Lebenszyklus- Meldungen, die volle Ausgabe bleibt vollstaendig in /var/log/tuxflotte-installer.log (bereits der dokumentierte Weg). Zwei echte Bugs beim eigenen Boot-Test dieser Aenderung gefunden+behoben: (1) log_module_title() gab den Titel per Command-Substitution zurueck - lief dadurch in einer Subshell, der TUXFLOTTE_STEP_COUNT-Zaehler blieb immer bei 1 stehen ("[1/12]" bei jedem Modul). Jetzt ueber eine globale TUXFLOTTE_CURRENT_TITLE-Variable statt Command-Substitution. (2) Unicode-Kreisel (⠋⠙...) und Haken (✓/✗) wurden von der vt-Konsolenschriftart nicht abgedeckt, zeigten nur einen generischen Ersatz-Kasten - auf reines ASCII (|/-\, "[OK]"/"[FEHLER]") umgestellt, garantiert auf jeder Konsolenschriftart lesbar. Ausserdem: Beep + "Stick jetzt entfernen"-Hinweis + ENTER-Bestaetigung (oder automatischer Neustart nach 5 Minuten) direkt vor dem finalen Reboot in backend.sh (separater Commit, siehe backend_postinstall()). Live in QEMU boot-getestet (Zaehler/Farben/Kreisel im Rohlog verifiziert, kompletter Auto-Modus-Durchlauf inkl. Fehlerfall-Dump getestet, voller End-to-End-Durchlauf bis zum echten Mint-Cinnamon-Login-Bildschirm nach Reboot bestaetigt). --- .../system/tuxflotte-installer.service | 20 +++- .../opt/tuxflotte/scripts/boot-autostart.sh | 18 ++++ .../opt/tuxflotte/scripts/lib/logging.sh | 76 ++++++++++++++- .../opt/tuxflotte/scripts/lib/utils.sh | 97 ++++++++++++++++++- scripts/boot-autostart.sh | 18 ++++ scripts/lib/logging.sh | 76 ++++++++++++++- scripts/lib/utils.sh | 97 ++++++++++++++++++- 7 files changed, 390 insertions(+), 12 deletions(-) diff --git a/boot-medium/config/includes.chroot/etc/systemd/system/tuxflotte-installer.service b/boot-medium/config/includes.chroot/etc/systemd/system/tuxflotte-installer.service index 9adfadb..d47adbe 100644 --- a/boot-medium/config/includes.chroot/etc/systemd/system/tuxflotte-installer.service +++ b/boot-medium/config/includes.chroot/etc/systemd/system/tuxflotte-installer.service @@ -8,8 +8,8 @@ Wants=NetworkManager.service Type=idle ExecStart=/opt/tuxflotte/scripts/boot-autostart.sh StandardInput=tty-force -StandardOutput=journal+console -StandardError=journal+console +StandardOutput=console +StandardError=console TTYPath=/dev/tty1 TTYReset=yes TTYVHangup=yes @@ -18,6 +18,22 @@ TTYVHangup=yes # TTY-Teardown). Geloest stattdessen in boot-autostart.sh selbst: die # Konsole faellt nach installer.sh deterministisch in eine interaktive # Shell, kein getty-Neustart noetig. +# +# StandardOutput/Error war zuerst "journal+console" (journalctl konnte die +# Installationsausgabe so zusaetzlich zeigen) - Nutzer-Feedback (01.09.2026, +# echter Hardware-Test): "Der Kernel Zeitstempel ist für den Kunden nicht +# interessant, sondern nur verwirrend." journald spiegelt Konsolen-Ausgaben +# im kmsg-Stil mit einem monotonen "[ 12.345678]"-Zeitstempel je Zeile - +# genau das sah aus wie ein Kernel-Log, obwohl es nur unsere eigene +# Installationsausgabe war. "console" (ohne "journal+") verbindet fd1/fd2 +# stattdessen direkt mit /dev/tty1, ohne journald-Vermittlung: kein +# Zeitstempel-Praefix mehr, und "-t 1" ist ab hier wieder ein echter, +# zuverlaessiger tty-Test (siehe TUXFLOTTE_TTY_LIVE in boot-autostart.sh). +# journalctl -u tuxflotte-installer zeigt dadurch nur noch die eigenen +# Lebenszyklus-Meldungen des Dienstes, nicht mehr die volle +# Installationsausgabe - die bleibt weiterhin vollstaendig in +# /var/log/tuxflotte-installer.log einsehbar (das war laut Kopfkommentar +# oben ohnehin schon der dokumentierte Weg, "ohne journalctl zu brauchen"). [Install] WantedBy=multi-user.target diff --git a/boot-medium/config/includes.chroot/opt/tuxflotte/scripts/boot-autostart.sh b/boot-medium/config/includes.chroot/opt/tuxflotte/scripts/boot-autostart.sh index f30547a..3870e9f 100755 --- a/boot-medium/config/includes.chroot/opt/tuxflotte/scripts/boot-autostart.sh +++ b/boot-medium/config/includes.chroot/opt/tuxflotte/scripts/boot-autostart.sh @@ -23,6 +23,24 @@ if [[ -r "${BANNER_FILE}" ]]; then { cat "${BANNER_FILE}"; echo; } | tee -a "${LOG_FILE}" fi +# TUXFLOTTE_TTY_LIVE steuert, ob log_module_ok()/log_module_failed() +# (logging.sh) Kreisel/Haken mit ANSI-Fettschrift/Farbe zeigen oder einen +# reinen Klartext-Fallback. "-t 1" selbst ist hier IMMER falsch: das +# systemd-Unit setzt "StandardOutput=journal+console" (siehe +# tuxflotte-installer.service) - fd1 dieses Prozesses ist deshalb ein +# Journal-Socket, kein rohes tty-Zeichengeraet, ganz unabhaengig von der +# "installer.sh | tee"-Pipe weiter unten. journald spiegelt die Bytes +# trotzdem unveraendert (inkl. ANSI-Escapes) auf die echte Konsole - live +# gefunden (01.09.2026, QEMU-Regressionstest): mit "-t 1" als Kriterium +# blieb die geplante Fettschrift/Kreisel-Darstellung auf der echten Konsole +# deshalb IMMER inaktiv (Klartext-Fallback), obwohl ein Mensch am Geraet +# echte ANSI-Codes zu sehen bekommen haette. Da dieses Skript ausschliesslich +# ueber genau dieses systemd-Unit gestartet wird, ist "immer aktiv" hier die +# richtige, zuverlaessige Antwort - "-t 1" bleibt in logging.sh als Fallback +# fuer andere Aufrufkontexte (z.B. installer.sh manuell per SSH-Pty). +export TUXFLOTTE_TTY_LIVE=true +export TUXFLOTTE_LOG_FILE="${LOG_FILE}" + /opt/tuxflotte/scripts/installer.sh 2>&1 | tee -a "${LOG_FILE}" STATUS="${PIPESTATUS[0]}" diff --git a/boot-medium/config/includes.chroot/opt/tuxflotte/scripts/lib/logging.sh b/boot-medium/config/includes.chroot/opt/tuxflotte/scripts/lib/logging.sh index bd8bedc..2c20c46 100644 --- a/boot-medium/config/includes.chroot/opt/tuxflotte/scripts/lib/logging.sh +++ b/boot-medium/config/includes.chroot/opt/tuxflotte/scripts/lib/logging.sh @@ -16,6 +16,26 @@ log_success() { echo "[ OK ] $*" } +# Live gefunden (01.09.2026, echter Hardware-Test): "[[ -t 1 ]]" ist auf +# der echten Konsole IMMER falsch, weil boot-autostart.sh installer.sh +# grundsaetzlich durch "| tee -a logfile" schickt (fuer die persistente +# Logdatei, siehe Phase 2) - installer.sh selbst schreibt deshalb nie +# direkt auf ein tty, sondern immer in eine Pipe. Ergebnis: die geplante +# Fettschrift/Farb-Hervorhebung war auf dem echten Geraet nie aktiv, ganz +# unabhaengig vom Terminal, das der Kunde tatsaechlich vor sich hat. +# boot-autostart.sh prueft "[[ -t 1 ]]" deshalb VOR dem Aufbau dieser Pipe +# (an der Stelle noch zuverlaessig) und exportiert das Ergebnis als +# TUXFLOTTE_TTY_LIVE - hier nur noch auswerten, mit "-t 1" als Fallback +# fuer direkte, nicht ueber boot-autostart.sh gestartete Läufe (z.B. +# manuelles Testen von installer.sh per SSH). +_tuxflotte_console_is_live() { + if [[ -n "${TUXFLOTTE_TTY_LIVE:-}" ]]; then + [[ "${TUXFLOTTE_TTY_LIVE}" == true ]] + else + [[ -t 1 ]] + fi +} + # Klar abgesetzte Fortschrittsanzeige fuer die tty-Konsole des Boot-Mediums # (kein Desktop, kein Kiosk-Browser - die Terminal-Ausgabe selbst ist die # einzige UI, die eine Person vor dem Geraet sieht). Gilt fuer Dev- UND @@ -58,7 +78,7 @@ log_step() { # umgeleitet wird) - kein tput-Aufruf, ncurses-bin ist bewusst nicht Teil # des schlanken Paketsatzes, rohe ANSI-Codes reichen und sind ueberall # ohne Zusatzpaket verfuegbar. - if [[ -t 1 ]]; then + if _tuxflotte_console_is_live; then bold=$'\033[1m' reset=$'\033[0m' fi @@ -69,3 +89,57 @@ log_step() { printf '\n%s%s%s\n' "${bold}" "${title}" "${reset}" printf '%s\n\n' "$(printf '=%.0s' $(seq 1 ${#title}))" } + +# Kompakte Alternative zu log_step() fuer den unbeaufsichtigten +# Auto-Modus (echte Kunden-Installation, siehe run_module_quiet() in +# utils.sh). Live-Rueckmeldung des Nutzers (01.09.2026) nach dem ersten +# erfolgreichen Hardware-Test: die bisherige Fülle an [INFO]/[WARN]-Zeilen +# je Modul ist "nicht schön für das menschliche Auge" - Vorschlag: +# ein Kreisel waehrend ein Modul laeuft, ein gruener Haken wenn fertig, +# Details nur bei einem Fehlschlag. Ein einziges Ergebnis pro Modul statt +# einer ganzen Log-Wand ist genau das ("dann sind es nicht soviel +# Zeichen"). +# Reines ASCII statt Unicode-Braille/Haken-Zeichen (⠋⠙.../✓/✗): live gefunden +# (01.09.2026, QEMU-Regressionstest) - die vt-Konsolenschriftart des +# Boot-Mediums deckt diese Codepoints nicht ab, gerendert wurde nur ein +# generischer Ersatz-Kasten statt eines Haekchens. ASCII-Zeichen sind auf +# jeder Konsolenschriftart garantiert vorhanden, unabhaengig von Hardware/ +# Zeichensatz. +_TUXFLOTTE_SPINNER_FRAMES=(\| / - \\) + +# Setzt TUXFLOTTE_CURRENT_TITLE statt den Titel per "echo"+Command- +# Substitution zurueckzugeben - Command-Substitution laeuft in einer +# Subshell, deren Variablenaenderungen (hier: der TUXFLOTTE_STEP_COUNT- +# Zaehler) beim Verlassen verloren gehen. Live gefunden (01.09.2026, QEMU- +# Regressionstest): mit "title=\"\$(log_module_title ...)\"" blieb der +# Zaehler wegen genau dieser Subshell dauerhaft bei 1 stehen ("[1/12]" bei +# jedem Modul statt hochzuzaehlen). +log_module_title() { + local module_name="$1" + local label="${TUXFLOTTE_STEP_LABELS[$module_name]:-$module_name}" + local total="${#TUXFLOTTE_STEP_ORDER[@]}" + + TUXFLOTTE_STEP_COUNT=$((TUXFLOTTE_STEP_COUNT + 1)) + + TUXFLOTTE_CURRENT_TITLE="[${TUXFLOTTE_STEP_COUNT}/${total}] ${label}" +} + +log_module_ok() { + local title="$1" + + if _tuxflotte_console_is_live; then + printf '\r%s \033[1;32m[OK]\033[0m\n' "${title}" + else + printf '%s [OK]\n' "${title}" + fi +} + +log_module_failed() { + local title="$1" + + if _tuxflotte_console_is_live; then + printf '\r%s \033[1;31m[FEHLER]\033[0m\n' "${title}" + else + printf '%s [FEHLER]\n' "${title}" + fi +} diff --git a/boot-medium/config/includes.chroot/opt/tuxflotte/scripts/lib/utils.sh b/boot-medium/config/includes.chroot/opt/tuxflotte/scripts/lib/utils.sh index c87359a..09fea4e 100644 --- a/boot-medium/config/includes.chroot/opt/tuxflotte/scripts/lib/utils.sh +++ b/boot-medium/config/includes.chroot/opt/tuxflotte/scripts/lib/utils.sh @@ -12,24 +12,113 @@ load_config() { fi } +# Module, die auch im Auto-Modus verbose bleiben (keine Kreisel/Haken- +# Kompaktdarstellung, siehe run_module_quiet()): 40_backend.sh ist der mit +# Abstand langlaeufigste Schritt (Minuten statt Sekunden, Golden-Image- +# Download+Extraktion) - hier bleibt die eigene Schritt-fuer-Schritt- +# Ausgabe (Partitionieren/Formatieren/... + der Download-Fortschrittsbalken, +# siehe image_deploy_extract_image_from_url()) sichtbar, statt hinter einem +# einzelnen Kreisel zu verschwinden. +declare -a TUXFLOTTE_VERBOSE_MODULES=(40_backend.sh) + +_tuxflotte_module_is_verbose() { + local module_name="$1" + local candidate + + for candidate in "${TUXFLOTTE_VERBOSE_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}" +} + run_module() { local module="$1" local mode="${2:-normal}" + local module_name + module_name="$(basename "$module")" [[ -f "$module" ]] || error_exit "Modul nicht gefunden: $module" - log_step "$(basename "$module")" - log_info "Starte Modul: $(basename "$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" ]] && ! _tuxflotte_module_is_verbose "${module_name}"; then + run_module_quiet "$module" + return "$?" + fi + + log_step "${module_name}" + log_info "Starte Modul: ${module_name}" + # shellcheck disable=SC1090 "$module" - log_success "Modul abgeschlossen: $(basename "$module")" + log_success "Modul abgeschlossen: ${module_name}" } require_root() { diff --git a/scripts/boot-autostart.sh b/scripts/boot-autostart.sh index f30547a..3870e9f 100755 --- a/scripts/boot-autostart.sh +++ b/scripts/boot-autostart.sh @@ -23,6 +23,24 @@ if [[ -r "${BANNER_FILE}" ]]; then { cat "${BANNER_FILE}"; echo; } | tee -a "${LOG_FILE}" fi +# TUXFLOTTE_TTY_LIVE steuert, ob log_module_ok()/log_module_failed() +# (logging.sh) Kreisel/Haken mit ANSI-Fettschrift/Farbe zeigen oder einen +# reinen Klartext-Fallback. "-t 1" selbst ist hier IMMER falsch: das +# systemd-Unit setzt "StandardOutput=journal+console" (siehe +# tuxflotte-installer.service) - fd1 dieses Prozesses ist deshalb ein +# Journal-Socket, kein rohes tty-Zeichengeraet, ganz unabhaengig von der +# "installer.sh | tee"-Pipe weiter unten. journald spiegelt die Bytes +# trotzdem unveraendert (inkl. ANSI-Escapes) auf die echte Konsole - live +# gefunden (01.09.2026, QEMU-Regressionstest): mit "-t 1" als Kriterium +# blieb die geplante Fettschrift/Kreisel-Darstellung auf der echten Konsole +# deshalb IMMER inaktiv (Klartext-Fallback), obwohl ein Mensch am Geraet +# echte ANSI-Codes zu sehen bekommen haette. Da dieses Skript ausschliesslich +# ueber genau dieses systemd-Unit gestartet wird, ist "immer aktiv" hier die +# richtige, zuverlaessige Antwort - "-t 1" bleibt in logging.sh als Fallback +# fuer andere Aufrufkontexte (z.B. installer.sh manuell per SSH-Pty). +export TUXFLOTTE_TTY_LIVE=true +export TUXFLOTTE_LOG_FILE="${LOG_FILE}" + /opt/tuxflotte/scripts/installer.sh 2>&1 | tee -a "${LOG_FILE}" STATUS="${PIPESTATUS[0]}" diff --git a/scripts/lib/logging.sh b/scripts/lib/logging.sh index bd8bedc..2c20c46 100644 --- a/scripts/lib/logging.sh +++ b/scripts/lib/logging.sh @@ -16,6 +16,26 @@ log_success() { echo "[ OK ] $*" } +# Live gefunden (01.09.2026, echter Hardware-Test): "[[ -t 1 ]]" ist auf +# der echten Konsole IMMER falsch, weil boot-autostart.sh installer.sh +# grundsaetzlich durch "| tee -a logfile" schickt (fuer die persistente +# Logdatei, siehe Phase 2) - installer.sh selbst schreibt deshalb nie +# direkt auf ein tty, sondern immer in eine Pipe. Ergebnis: die geplante +# Fettschrift/Farb-Hervorhebung war auf dem echten Geraet nie aktiv, ganz +# unabhaengig vom Terminal, das der Kunde tatsaechlich vor sich hat. +# boot-autostart.sh prueft "[[ -t 1 ]]" deshalb VOR dem Aufbau dieser Pipe +# (an der Stelle noch zuverlaessig) und exportiert das Ergebnis als +# TUXFLOTTE_TTY_LIVE - hier nur noch auswerten, mit "-t 1" als Fallback +# fuer direkte, nicht ueber boot-autostart.sh gestartete Läufe (z.B. +# manuelles Testen von installer.sh per SSH). +_tuxflotte_console_is_live() { + if [[ -n "${TUXFLOTTE_TTY_LIVE:-}" ]]; then + [[ "${TUXFLOTTE_TTY_LIVE}" == true ]] + else + [[ -t 1 ]] + fi +} + # Klar abgesetzte Fortschrittsanzeige fuer die tty-Konsole des Boot-Mediums # (kein Desktop, kein Kiosk-Browser - die Terminal-Ausgabe selbst ist die # einzige UI, die eine Person vor dem Geraet sieht). Gilt fuer Dev- UND @@ -58,7 +78,7 @@ log_step() { # umgeleitet wird) - kein tput-Aufruf, ncurses-bin ist bewusst nicht Teil # des schlanken Paketsatzes, rohe ANSI-Codes reichen und sind ueberall # ohne Zusatzpaket verfuegbar. - if [[ -t 1 ]]; then + if _tuxflotte_console_is_live; then bold=$'\033[1m' reset=$'\033[0m' fi @@ -69,3 +89,57 @@ log_step() { printf '\n%s%s%s\n' "${bold}" "${title}" "${reset}" printf '%s\n\n' "$(printf '=%.0s' $(seq 1 ${#title}))" } + +# Kompakte Alternative zu log_step() fuer den unbeaufsichtigten +# Auto-Modus (echte Kunden-Installation, siehe run_module_quiet() in +# utils.sh). Live-Rueckmeldung des Nutzers (01.09.2026) nach dem ersten +# erfolgreichen Hardware-Test: die bisherige Fülle an [INFO]/[WARN]-Zeilen +# je Modul ist "nicht schön für das menschliche Auge" - Vorschlag: +# ein Kreisel waehrend ein Modul laeuft, ein gruener Haken wenn fertig, +# Details nur bei einem Fehlschlag. Ein einziges Ergebnis pro Modul statt +# einer ganzen Log-Wand ist genau das ("dann sind es nicht soviel +# Zeichen"). +# Reines ASCII statt Unicode-Braille/Haken-Zeichen (⠋⠙.../✓/✗): live gefunden +# (01.09.2026, QEMU-Regressionstest) - die vt-Konsolenschriftart des +# Boot-Mediums deckt diese Codepoints nicht ab, gerendert wurde nur ein +# generischer Ersatz-Kasten statt eines Haekchens. ASCII-Zeichen sind auf +# jeder Konsolenschriftart garantiert vorhanden, unabhaengig von Hardware/ +# Zeichensatz. +_TUXFLOTTE_SPINNER_FRAMES=(\| / - \\) + +# Setzt TUXFLOTTE_CURRENT_TITLE statt den Titel per "echo"+Command- +# Substitution zurueckzugeben - Command-Substitution laeuft in einer +# Subshell, deren Variablenaenderungen (hier: der TUXFLOTTE_STEP_COUNT- +# Zaehler) beim Verlassen verloren gehen. Live gefunden (01.09.2026, QEMU- +# Regressionstest): mit "title=\"\$(log_module_title ...)\"" blieb der +# Zaehler wegen genau dieser Subshell dauerhaft bei 1 stehen ("[1/12]" bei +# jedem Modul statt hochzuzaehlen). +log_module_title() { + local module_name="$1" + local label="${TUXFLOTTE_STEP_LABELS[$module_name]:-$module_name}" + local total="${#TUXFLOTTE_STEP_ORDER[@]}" + + TUXFLOTTE_STEP_COUNT=$((TUXFLOTTE_STEP_COUNT + 1)) + + TUXFLOTTE_CURRENT_TITLE="[${TUXFLOTTE_STEP_COUNT}/${total}] ${label}" +} + +log_module_ok() { + local title="$1" + + if _tuxflotte_console_is_live; then + printf '\r%s \033[1;32m[OK]\033[0m\n' "${title}" + else + printf '%s [OK]\n' "${title}" + fi +} + +log_module_failed() { + local title="$1" + + if _tuxflotte_console_is_live; then + printf '\r%s \033[1;31m[FEHLER]\033[0m\n' "${title}" + else + printf '%s [FEHLER]\n' "${title}" + fi +} diff --git a/scripts/lib/utils.sh b/scripts/lib/utils.sh index c87359a..09fea4e 100644 --- a/scripts/lib/utils.sh +++ b/scripts/lib/utils.sh @@ -12,24 +12,113 @@ load_config() { fi } +# Module, die auch im Auto-Modus verbose bleiben (keine Kreisel/Haken- +# Kompaktdarstellung, siehe run_module_quiet()): 40_backend.sh ist der mit +# Abstand langlaeufigste Schritt (Minuten statt Sekunden, Golden-Image- +# Download+Extraktion) - hier bleibt die eigene Schritt-fuer-Schritt- +# Ausgabe (Partitionieren/Formatieren/... + der Download-Fortschrittsbalken, +# siehe image_deploy_extract_image_from_url()) sichtbar, statt hinter einem +# einzelnen Kreisel zu verschwinden. +declare -a TUXFLOTTE_VERBOSE_MODULES=(40_backend.sh) + +_tuxflotte_module_is_verbose() { + local module_name="$1" + local candidate + + for candidate in "${TUXFLOTTE_VERBOSE_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}" +} + run_module() { local module="$1" local mode="${2:-normal}" + local module_name + module_name="$(basename "$module")" [[ -f "$module" ]] || error_exit "Modul nicht gefunden: $module" - log_step "$(basename "$module")" - log_info "Starte Modul: $(basename "$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" ]] && ! _tuxflotte_module_is_verbose "${module_name}"; then + run_module_quiet "$module" + return "$?" + fi + + log_step "${module_name}" + log_info "Starte Modul: ${module_name}" + # shellcheck disable=SC1090 "$module" - log_success "Modul abgeschlossen: $(basename "$module")" + log_success "Modul abgeschlossen: ${module_name}" } require_root() {