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.
Entfernt (Historie bleibt ueber Git-Log erhalten, siehe ADR-0025 in
platform-docs fuer die vollstaendige Begruendung/den Gesamtrueckblick):
- backends/mint/ (Ubiquity-Preseed-Backend, backend_launch()-Pfad nicht
mehr referenziert seit Phase 1, postinstall.sh dort bereits migriert)
- scripts/lib/initrd.sh, initrd-hooks/ (Casper-Bottom-Hook-Injection,
nur fuer das Patchen einer fremden fertigen Mint-ISO noetig)
- grub/mint-boot-grub.cfg, grub/mint-isolinux-live.cfg
- live-updates/ (Cinnamon-Kiosk, AT-SPI-Autoklicker)
scripts/build.sh (das alte Test-Build-Skript) bedient jetzt nur noch das
Fedora-Backend (Kickstart/Anaconda, unveraendert, ausserhalb dieses
Plans) - Mint-Zweig entfernt (bake_test_preseed(), patch_initrd(),
initrd.sh-Source, mint-spezifische GRUB-Pfade). Die unbedingte
live-updates/-Kopie in prepare_updates() entfiel ebenfalls - sie wurde
fuer Fedora nie inhaltlich gebraucht (Anaconda/Kickstart kennt kein
Cinnamon-Kiosk/keinen AT-SPI-Autoklicker), nur bisher blind mitkopiert.
README.md um einen Abschnitt zum neuen Boot-Medium-Bauweg ergaenzt
(build_boot_medium.sh/build_customer_iso.sh vs. weiterhin
Fedora-spezifisches build.sh).
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.
Real beim Testen entdeckt: grub-install konnte im Testkontext keinen
NVRAM-Booteintrag setzen ('EFI variables are not supported on this
system'), ohne --removable blieb dann nur der benannte
/EFI/tuxflotte/-Pfad uebrig, den die Firmware ohne NVRAM-Eintrag nie
findet - Ergebnis: 'No bootable option or device was found' beim
Testboot von der frisch beschriebenen Platte. Fix: zusaetzlicher
grub-install-Lauf mit --removable schreibt auf den Standard-Fallback-Pfad
EFI/BOOT/BOOTX64.EFI, den jede UEFI-Firmware ohne NVRAM-Eintrag
automatisch versucht - robuster generell fuer heterogene Zielhardware,
nicht nur fuer dieses Testszenario.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Neue Richtung nach ADR-0024-Diskussion: statt Distributions-Installer
(Ubiquity/Anaconda) zu automatisieren - strukturell fragil, siehe
ADR-0023-Nachtrag zum partman-rebuild-cache-Loop - wird das
curtin/FAI-Muster genutzt: Zieldatentraeger direkt partitionieren, ein
fertiges Root-Filesystem-Image entpacken, per chroot nacharbeiten.
- build_golden_image.sh: baut eine schlanke Debian-bookworm-Basis per
debootstrap (Kernel, breites linux-firmware, NetworkManager,
openssh-server) - KEINE Desktop-Umgebung, die kommt wie jedes andere
Merkmal per Ansible-Blueprint nach dem ersten Boot (ADR-0002). Keine
SSH-Hostkeys/kein Root-Passwort im Ergebnis - reale Zugangsdaten
entstehen erst durch den Provisioning Agent pro Geraet.
- scripts/lib/image_deploy.sh: Kernmechanik als wiederverwendbare
Funktionsbibliothek (partitionieren, formatieren, mounten, Image
entpacken, fstab aus echten UUIDs, chroot-Fixup fuer machine-id/SSH-
Hostkeys/initramfs, Bootloader-Installation UEFI+BIOS).
- scripts/image_deploy_test.sh: isolierter Testtreiber fuer Phase 1,
ruft dieselben Funktionen auf, die spaeter backends/mint-image/
backend.sh (Phase 2) nutzen wird.
Golden Image real gebaut und verifiziert (enterprise/LMDE 6, debootstrap
bookworm): 302 MB, Kernel vorhanden, keine SSH-Hostkeys, machine-id leer.
Deployment-Mechanik noch nicht live getestet - naechster Schritt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Casper merged /updates nie automatisch auf das gebootete Live-System -
eine seit Projektbeginn unverifizierte Annahme, die erst beim echten
QEMU-Boot (UEFI, kompletter GRUB->Live-Desktop-Pfad) einer personalisierten
Kunden-ISO aufgefallen ist: /opt/tuxflotte fehlte trotz korrekt auf dem
Medium liegendem /cdrom/updates vollständig.
Fix per casper-bottom-Hook, eingebettet via Initrd-Cpio-Konkatenation
(scripts/lib/initrd.sh, derselbe in Phase 1 verifizierte Mechanismus wie
beim Kexec-Preseed). Wichtig dabei: ein komplett neuer Hook-Skriptname wird
nie ausgeführt, weil mkinitramfs eine statische ORDER-Datei mit der
Aufrufliste ins Initrd backt - stattdessen wird der Inhalt des bereits
gelisteten, garantiert letzten Skripts (99casperboot) überschrieben.
start-kiosk.sh erkennt jetzt TUXFLOTTE_AUTO_MODE und startet den Installer
automatisch statt der Kiosk-Startseite. build_customer_iso.sh baut daraus
personalisierte Kunden-ISOs (WLAN-Zugangsdaten + Enrollment-Session-Code).
Nebenbei zwei vorbestehende Bugs behoben: xorriso -osirrox übernimmt
Original-ISO-Dateirechte (oft 444/555, kein Write-Bit), was cp/rm -rf in
build.sh/build_customer_iso.sh bisher unbemerkt kaputt gemacht hat.
Real per QEMU verifiziert (echter GRUB-Boot einer gebauten Kunden-ISO).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>