9 Commits

Author SHA1 Message Date
8b47751b31 boot-medium: Konsolen-Rauschen bei 40_backend.sh verbergen, toram, neues Banner
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.
2026-09-01 19:11:59 +02:00
d496adad09 installer: Installations-Meilensteine/Fehlschlaege an anode melden
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.
2026-09-01 16:52:15 +02:00
8615d9fde1 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).
2026-09-01 15:46:18 +02:00
3f17885d55 mint-image: WLAN-/Netzwerkverbindungsprofil ins Zielsystem uebernehmen
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.
2026-09-01 15:45:31 +02:00
3739da37dc mint-image/hardware: Boot-Medium-Platte in gemeinsame lib ausgelagert
_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.
2026-09-01 15:45:25 +02:00
5b9d3fdf6a fix(installer): Zielplatte vor dem Partitionieren freigeben + Kernel-Neueinlesen mit Wiederholung
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.
2026-09-01 12:00:55 +02:00
27d6fa0f47 feat(boot-medium): build_customer_iso.sh ans neue Struktur anpassen (Phase 3) + vier echte Deployment-Bugs behoben
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.
2026-08-31 16:36:35 +02:00
bc13169418 feat(boot-medium): systemd-Autostart, Fortschrittsanzeige, SSH-Dev-Modus (Phase 2)
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.
2026-08-31 14:40:39 +02:00
2190d6f403 feat(boot-medium): Tuxflotte-Nutzlast ins Boot-Medium einbauen (Phase 1)
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.
2026-08-31 13:52:38 +02:00