#!/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, 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" 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: ${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 }