Konsole: kompakte Kreisel/Haken-Anzeige statt Log-Wand + Kernel-Zeitstempel entfernt
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).
This commit is contained in:
parent
06ba89697b
commit
8615d9fde1
@ -8,8 +8,8 @@ Wants=NetworkManager.service
|
|||||||
Type=idle
|
Type=idle
|
||||||
ExecStart=/opt/tuxflotte/scripts/boot-autostart.sh
|
ExecStart=/opt/tuxflotte/scripts/boot-autostart.sh
|
||||||
StandardInput=tty-force
|
StandardInput=tty-force
|
||||||
StandardOutput=journal+console
|
StandardOutput=console
|
||||||
StandardError=journal+console
|
StandardError=console
|
||||||
TTYPath=/dev/tty1
|
TTYPath=/dev/tty1
|
||||||
TTYReset=yes
|
TTYReset=yes
|
||||||
TTYVHangup=yes
|
TTYVHangup=yes
|
||||||
@ -18,6 +18,22 @@ TTYVHangup=yes
|
|||||||
# TTY-Teardown). Geloest stattdessen in boot-autostart.sh selbst: die
|
# TTY-Teardown). Geloest stattdessen in boot-autostart.sh selbst: die
|
||||||
# Konsole faellt nach installer.sh deterministisch in eine interaktive
|
# Konsole faellt nach installer.sh deterministisch in eine interaktive
|
||||||
# Shell, kein getty-Neustart noetig.
|
# 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]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@ -23,6 +23,24 @@ if [[ -r "${BANNER_FILE}" ]]; then
|
|||||||
{ cat "${BANNER_FILE}"; echo; } | tee -a "${LOG_FILE}"
|
{ cat "${BANNER_FILE}"; echo; } | tee -a "${LOG_FILE}"
|
||||||
fi
|
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}"
|
/opt/tuxflotte/scripts/installer.sh 2>&1 | tee -a "${LOG_FILE}"
|
||||||
STATUS="${PIPESTATUS[0]}"
|
STATUS="${PIPESTATUS[0]}"
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,26 @@ log_success() {
|
|||||||
echo "[ OK ] $*"
|
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
|
# Klar abgesetzte Fortschrittsanzeige fuer die tty-Konsole des Boot-Mediums
|
||||||
# (kein Desktop, kein Kiosk-Browser - die Terminal-Ausgabe selbst ist die
|
# (kein Desktop, kein Kiosk-Browser - die Terminal-Ausgabe selbst ist die
|
||||||
# einzige UI, die eine Person vor dem Geraet sieht). Gilt fuer Dev- UND
|
# 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
|
# umgeleitet wird) - kein tput-Aufruf, ncurses-bin ist bewusst nicht Teil
|
||||||
# des schlanken Paketsatzes, rohe ANSI-Codes reichen und sind ueberall
|
# des schlanken Paketsatzes, rohe ANSI-Codes reichen und sind ueberall
|
||||||
# ohne Zusatzpaket verfuegbar.
|
# ohne Zusatzpaket verfuegbar.
|
||||||
if [[ -t 1 ]]; then
|
if _tuxflotte_console_is_live; then
|
||||||
bold=$'\033[1m'
|
bold=$'\033[1m'
|
||||||
reset=$'\033[0m'
|
reset=$'\033[0m'
|
||||||
fi
|
fi
|
||||||
@ -69,3 +89,57 @@ log_step() {
|
|||||||
printf '\n%s%s%s\n' "${bold}" "${title}" "${reset}"
|
printf '\n%s%s%s\n' "${bold}" "${title}" "${reset}"
|
||||||
printf '%s\n\n' "$(printf '=%.0s' $(seq 1 ${#title}))"
|
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
|
||||||
|
}
|
||||||
|
|||||||
@ -12,24 +12,113 @@ load_config() {
|
|||||||
fi
|
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() {
|
run_module() {
|
||||||
local module="$1"
|
local module="$1"
|
||||||
local mode="${2:-normal}"
|
local mode="${2:-normal}"
|
||||||
|
local module_name
|
||||||
|
module_name="$(basename "$module")"
|
||||||
|
|
||||||
[[ -f "$module" ]] || error_exit "Modul nicht gefunden: $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
|
if [[ "${DRY_RUN:-false}" == true && "$mode" != "always" ]]; then
|
||||||
|
log_step "${module_name}"
|
||||||
log_warn "Dry-Run: Modul übersprungen: $module"
|
log_warn "Dry-Run: Modul übersprungen: $module"
|
||||||
return 0
|
return 0
|
||||||
fi
|
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
|
# shellcheck disable=SC1090
|
||||||
"$module"
|
"$module"
|
||||||
|
|
||||||
log_success "Modul abgeschlossen: $(basename "$module")"
|
log_success "Modul abgeschlossen: ${module_name}"
|
||||||
}
|
}
|
||||||
|
|
||||||
require_root() {
|
require_root() {
|
||||||
|
|||||||
@ -23,6 +23,24 @@ if [[ -r "${BANNER_FILE}" ]]; then
|
|||||||
{ cat "${BANNER_FILE}"; echo; } | tee -a "${LOG_FILE}"
|
{ cat "${BANNER_FILE}"; echo; } | tee -a "${LOG_FILE}"
|
||||||
fi
|
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}"
|
/opt/tuxflotte/scripts/installer.sh 2>&1 | tee -a "${LOG_FILE}"
|
||||||
STATUS="${PIPESTATUS[0]}"
|
STATUS="${PIPESTATUS[0]}"
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,26 @@ log_success() {
|
|||||||
echo "[ OK ] $*"
|
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
|
# Klar abgesetzte Fortschrittsanzeige fuer die tty-Konsole des Boot-Mediums
|
||||||
# (kein Desktop, kein Kiosk-Browser - die Terminal-Ausgabe selbst ist die
|
# (kein Desktop, kein Kiosk-Browser - die Terminal-Ausgabe selbst ist die
|
||||||
# einzige UI, die eine Person vor dem Geraet sieht). Gilt fuer Dev- UND
|
# 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
|
# umgeleitet wird) - kein tput-Aufruf, ncurses-bin ist bewusst nicht Teil
|
||||||
# des schlanken Paketsatzes, rohe ANSI-Codes reichen und sind ueberall
|
# des schlanken Paketsatzes, rohe ANSI-Codes reichen und sind ueberall
|
||||||
# ohne Zusatzpaket verfuegbar.
|
# ohne Zusatzpaket verfuegbar.
|
||||||
if [[ -t 1 ]]; then
|
if _tuxflotte_console_is_live; then
|
||||||
bold=$'\033[1m'
|
bold=$'\033[1m'
|
||||||
reset=$'\033[0m'
|
reset=$'\033[0m'
|
||||||
fi
|
fi
|
||||||
@ -69,3 +89,57 @@ log_step() {
|
|||||||
printf '\n%s%s%s\n' "${bold}" "${title}" "${reset}"
|
printf '\n%s%s%s\n' "${bold}" "${title}" "${reset}"
|
||||||
printf '%s\n\n' "$(printf '=%.0s' $(seq 1 ${#title}))"
|
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
|
||||||
|
}
|
||||||
|
|||||||
@ -12,24 +12,113 @@ load_config() {
|
|||||||
fi
|
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() {
|
run_module() {
|
||||||
local module="$1"
|
local module="$1"
|
||||||
local mode="${2:-normal}"
|
local mode="${2:-normal}"
|
||||||
|
local module_name
|
||||||
|
module_name="$(basename "$module")"
|
||||||
|
|
||||||
[[ -f "$module" ]] || error_exit "Modul nicht gefunden: $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
|
if [[ "${DRY_RUN:-false}" == true && "$mode" != "always" ]]; then
|
||||||
|
log_step "${module_name}"
|
||||||
log_warn "Dry-Run: Modul übersprungen: $module"
|
log_warn "Dry-Run: Modul übersprungen: $module"
|
||||||
return 0
|
return 0
|
||||||
fi
|
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
|
# shellcheck disable=SC1090
|
||||||
"$module"
|
"$module"
|
||||||
|
|
||||||
log_success "Modul abgeschlossen: $(basename "$module")"
|
log_success "Modul abgeschlossen: ${module_name}"
|
||||||
}
|
}
|
||||||
|
|
||||||
require_root() {
|
require_root() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user