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.
Neue scripts/lib/reporting.sh (tuxflotte_report_installation_event())
meldet best-effort an POST /api/v1/devices/{device_id}/installation-events
(device_fingerprint-authentifiziert, siehe provisioning-server-Commit
51fbf0f) - ein Fehlschlag beim Melden selbst darf die eigentliche
Installation nie aufhalten.
Vier Meldepunkte:
- "activation_confirmed" direkt nach erfolgreichem Provisioning-Handshake
(15_server_handshake.sh)
- "installation_started" direkt nach bestaetigtem Commit Point
(installer.sh)
- "installation_completed" ganz am Ende von backend_postinstall(), vor dem
finalen Reboot (backend.sh)
- "installation_failed" zentral in boot-autostart.sh (einziger Ort, an dem
der echte Exit-Code von installer.sh bekannt ist, ohne jedes Modul
einzeln instrumentieren zu muessen) - Detail = letzte 40 Logzeilen,
enthalten bereits die eigentliche [FEHLER]-Meldung des gescheiterten
Moduls. Nur bei STATUS != 0, nicht bei einem kontrollierten Abbruch an
einem Commit-Gate (STATUS = 0).
Nutzer-Wunsch (01.09.2026, nach dem ersten echten Hardware-Test):
Fehlschlaege waehrend der Installation sichtbar machen, ohne am
Bildschirm mitschreiben zu muessen ("das ist kein Flow... fuer die
Weiterentwicklung eines irgendwann fehlerfreien Betriebs sind fuer uns
diese Meldungen Gold wert").
Live in QEMU end-to-end verifiziert: alle drei Erfolgs-Meilensteine
korrekt in device_installation_events angekommen (activation_confirmed,
installation_started, installation_completed), vollstaendiger Durchlauf
bis zum echten Mint-Cinnamon-Login-Bildschirm nach Reboot bestaetigt.
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).
Neue image_deploy_install_network_profile() kopiert das von
export_connection_profile() (05_network.sh) geschuetzt abgelegte
Verbindungsprofil nach /etc/NetworkManager/system-connections/ im
Zielsystem - backend_launch() ruft das nach dem Mounten auf.
Nutzer-Feedback (01.09.2026, echter Hardware-Test): "WLAN-Information sind
nicht konsistent. Nach Reboot muss PSK neu eingegeben werden." Root Cause:
export_connection_profile() legte das Profil zwar unter
/run/tuxflotte/network/connection.nmconnection ab, aber niemand holte es
von dort ab - das frisch installierte System stand beim ersten Boot ohne
gespeichertes Profil da.
_mint_image_boot_medium_disk() aus backend.sh nach scripts/lib/boot_medium.sh
verschoben (tuxflotte_boot_medium_disk()) - build_storage_devices_json()
(hardware_collectors.sh) braucht dieselbe Ausschluss-Logik jetzt ebenfalls.
Nutzer-Feedback (01.09.2026, echter Hardware-Test): der Installations-
USB-Stick selbst tauchte in der Kundenplattform unter Flotte -> Aktionen ->
Hardware-Info -> Datenträger auf - fuer den Kunden irrefuehrend, da dieser
Datentraeger nach der Installation gar nicht mehr existiert. Gleiche
Ursache wie der parted-Bug (Commit fa54461): lsblk liefert das Boot-Medium
auf echter USB-Stick-Hardware als normalen TYPE="disk" zurueck.
Live auf echter Hardware gefunden (01.09.2026): "Error: Partition(s) 1
on /dev/sda have been written, but we have been unable to inform the
Kernel of the change, probably because it/they are in use." - parted
schreibt die neue GPT-Tabelle zwar trotzdem, meldet aber einen Fehler,
wenn eine alte Partition (Swap, gemountetes Dateisystem vom vorherigen
Betriebssystem auf dieser Platte) noch belegt ist. In QEMU mit stets
frischen Testplatten nie aufgetreten - reale Kundenhardware hat aber
fast immer schon ein Vorleben auf der Platte.
Zwei neue Bausteine in image_deploy_partition():
- _image_deploy_release_disk(): unmountet/deaktiviert Swap auf allen
vorhandenen Partitionen der Zielplatte, bevor ueberhaupt mklabel
aufgerufen wird.
- _image_deploy_settle_partitions(): wiederholt partprobe/udevadm settle
bis zu 5x statt nach einem einzigen Versuch aufzugeben, sowohl nach
mklabel als auch nach dem Anlegen der eigentlichen Partitionen.
Zusaetzlich wird nach mklabel explizit verifiziert, dass wirklich ein
gueltiges GPT-Label vorliegt (parted print), statt parteds Exit-Code
fuer den Kernel-Info-Schritt blind als Gesamtfehlschlag zu werten.
Lokal verifiziert: einmal komplett durchinstalliert (frische Platte),
dann OHNE die Platte zurueckzusetzen ein zweites Mal auf dieselbe,
bereits mit einem echten System belegte Platte installiert - lief
sauber durch, keine Kernel-Fehlermeldung mehr.
Phase 3: Personalisierung (Aktivierungscode/WLAN) funktioniert jetzt ohne
Xorriso-Extraktion der ganzen ISO / Casper-Hook-Injection. /opt/tuxflotte/
liegt innerhalb von /live/filesystem.squashfs (read-only) - ein direktes
xorriso -update auf eine Datei darin traf live getestet ins Leere.
Stattdessen: Squashfs entpacken (unsquashfs), installer.conf ersetzen, neu
packen (mksquashfs -comp xz, ~1 Minute reine Kompression, kein
debootstrap/apt), als Ganzes per xorriso -update einspielen. Muss als root
laufen (Datei-Eigentuemer im Squashfs sonst falsch).
Beim ersten echten End-to-End-Testlauf mit dem vollen Golden-Image-Archiv
(vorher nie bis zum Ende gekommen - immer am Ubiquity-Bug oder an einem
Commit-Gate gestoppt) vier echte, bisher unentdeckte Bugs gefunden und
behoben:
1. Golden-Image-Download landete in /run/tuxflotte/backend/ (RAM-Tmpfs,
hier 392 MB) statt auf echtem Speicher - "curl: (23) Failure writing
output to destination" bei 2,3 GB Archiv, unabhaengig von RAM-Groesse.
Fix: image_deploy_extract_image_from_url() streamt Download direkt in
die Extraktion (curl | tar), kein Zwischenspeichern mehr noetig.
backend_launch() partitioniert/formatiert/mountet jetzt VOR dem
Download-Versuch statt danach.
2. /etc/resolv.conf im Zielbaum ist bei der echten Referenz-VM ein von
NetworkManager verwalteter Symlink - "cp" verweigerte das Schreiben
"through a dangling symlink". Fix: Ziel vor dem Kopieren explizit
entfernen.
3. mount --bind auf /dev, /proc, /sys schlug fehl, weil diese Verzeichnisse
nach dem Entpacken gar nicht existierten (package_golden_image.sh
schliesst sie bewusst aus) - und zwar SILENT, weil das bisherige
"cmd && stack_ref+=(...)"-Muster einen Fehlschlag unter "set -e" nicht
als Statement-Fehler wertet. Fiel dadurch erst beim naechsten
chroot-Aufruf auf ("ssh-keygen -A: Couldn't open /dev/null"), weit weg
von der eigentlichen Ursache. Fix: neue image_deploy_restore_excluded_dirs()
legt alle sechs von package_golden_image.sh ausgeschlossenen
Verzeichnisse (proc/sys/dev/run/tmp/var-tmp) direkt nach der Extraktion
wieder an; jeder Mount wird jetzt einzeln explizit geprueft statt auf
&&-Verkettung zu vertrauen.
4. package_golden_image.sh: "--exclude=dev" (ohne "./"-Praefix) matcht bei
GNU tar gegen JEDEN Verzeichnis-Basisnamen im ganzen Baum, nicht nur
den Top-Level-Eintrag - hat dadurch auch kernel/drivers/net/can/dev/
(ein zufaellig gleichnamiger, voellig unverwandter Kernelmodul-Ordner)
aus dem Archiv gerissen, update-initramfs scheiterte an fehlenden
can-dev.ko.zst-Abhaengigkeiten. Lokal mit einem Wegwerf-Testbaum
verifiziert (wie beim "run"-Fund vom selben Tag): "./"-Praefix
verankert das Muster auf den exakten Top-Level-Pfad, gleichnamige
verschachtelte Ordner bleiben erhalten. Betrifft das AKTUELL AUF ANODE
GEHOSTETE Archiv - muss mit dem korrigierten Skript auf der
Referenz-VM neu gepackt und hochgeladen werden (steht noch aus,
Nutzer verschlankt die Referenz-VM gerade zusaetzlich).
Live-Fortschritt in der enterprise-QEMU-VM: nach Fix 1-3 kam der
Deployment-Versuch bis kurz vor update-initramfs durch (Partitionierung,
Formatierung, Mounten, Download+Extraktion, chroot-Fixup bis machine-id +
SSH-Hostkeys liefen alle sauber) - Fund 4 (das defekte Archiv) ist der
letzte noch offene Blocker fuer einen vollstaendig erfolgreichen
End-to-End-Durchlauf.
Neuer Service tuxflotte-installer.service startet installer.sh beim Boot
direkt auf tty1 (Type=idle, Conflicts=getty@tty1.service) - kein manuelles
Anmelden/sudo mehr noetig, egal ob Auto-Modus oder interaktiver
Test-/Entwicklungslauf. Wrapper boot-autostart.sh spiegelt die Ausgabe
zusaetzlich nach /var/log/tuxflotte-installer.log.
log_step() (scripts/lib/logging.sh) gibt vor jedem Modul einen klar
abgesetzten "[n/12] <Label>"-Block aus - gilt fuer Dev- UND Produktiv-Build
gleichermassen (die tty-Konsole ist die einzige UI, die eine Person vor
dem Geraet sieht, kein Kiosk-Browser mehr).
scripts/build_boot_medium.sh buendelt lb clean/config/build (loeste die
bisherigen Hand-Aufrufe ab) und steuert per --dev-Flag einen SSH-
Debug-Zugang (tuxflotte/test123) - ohne --dev bleibt SSH deaktiviert,
keine gebackenen Zugangsdaten (Produktiv-Default).
Zwei echte, live gefundene Bugs unterwegs behoben:
- Debians trixie-sshd_config deaktiviert PasswordAuthentication per
Default - fuer den Dev-Testzugang explizit wieder aktiviert.
- Ein ExecStopPost, der getty@tty1.service nach Dienstende neu startet,
ist unzuverlaessig (Race mit dem eigenen TTY-Teardown, Job wurde
angestossen, blieb aber inactive/dead). Geloest durch einen
deterministischen Fallback in boot-autostart.sh selbst: die Konsole
faellt nach installer.sh in eine interaktive Shell statt auf einen
eventuell nie zurueckkehrenden getty zu warten.
Live verifiziert in der enterprise-QEMU-VM (zwei frische Enrollment-
Sessions, echte anode-Aktivierung, "Bekanntes Geraet erkannt"-Pfad):
Boot laeuft ohne jede manuelle Anmeldung direkt in installer.sh, alle
12 Fortschritts-Banner erscheinen korrekt nummeriert, Commit-Gate und
kontrollierter Abbruch funktionieren, SSH-Login mit Passwort
funktioniert, Fallback-Shell nach Programmende reagiert auf Eingaben.
scripts/ (installer.sh, lib/*, modules/00-99) und backends/mint-image/
(inkl. echtem postinstall.sh statt Symlink auf backends/mint/) werden ueber
config/includes.chroot/opt/tuxflotte/ ins Image kopiert - bewusst nur die
zur Laufzeit benoetigten Dateien, nicht die Build-Host-Werkzeuge
(build_customer_iso.sh, build_golden_image.sh, package_golden_image.sh,
lib/initrd.sh etc. bleiben aussen vor).
00_preflight.sh und backend_init() (backends/mint-image/backend.sh)
verlieren ihre Laufzeit-apt-get-Nachinstallation (jq, parted, dosfstools,
e2fsprogs, zstd, btrfs-progs, gettext-base, curl) - alles bereits in
Phase 0 vorinstalliert. Werden durch reine Assertions ersetzt, die frueh
und klar melden, falls die Paketliste doch mal luecken sollte.
backends/mint/postinstall.sh nach backends/mint-image/postinstall.sh als
echte Datei verschoben (war Symlink) - noetig, weil backends/mint/ in
Phase 4 komplett entfernt wird.
Live verifiziert in der enterprise-QEMU-VM: installer.sh von Hand
gestartet, Module 00/05/10/12/15/17 liefen sauber durch, inkl. echtem
Server-Kontakt zu anode und echter Geraeteregistrierung (Liebherr-Org),
Commit-Gate erschien interaktiv wie erwartet, kontrollierter Abbruch ohne
jede destruktive Aktion.