diff --git a/adr/0024-golden-image-deployment-statt-installer-automatisierung.md b/adr/0024-golden-image-deployment-statt-installer-automatisierung.md new file mode 100644 index 0000000..05d2e69 --- /dev/null +++ b/adr/0024-golden-image-deployment-statt-installer-automatisierung.md @@ -0,0 +1,125 @@ +# ADR-0024: Golden-Image-Deployment statt Distributions-Installer-Automatisierung + +**Status:** Beschlossen, Phase 0+1 live verifiziert +**Datum:** 29.08.2026 + +## Kontext + +Nach einem vollen Tag Fehlersuche an Linux Mints Ubiquity-Installer (siehe +[[project_e2e_flow_dogfooding_2026-08-28]] und ADR-0023-Nachtrag) blieb +trotz eines live verifizierten, zuverlässigen AT-SPI-Autoklickers (100+ +korrekte Klicks) ein tiefer, undokumentierter Blocker bestehen: Ubiquity +springt nach dem Klick auf "Jetzt installieren" wiederholt in eine +`ubiquity/partman-rebuild-cache`-Schleife zurück +(`/lib/partman/update.d/99signal_ubiquity`), ohne dass mehrere geprüfte +Hypothesen (Rezept-Flags, Timing) die Ursache klären konnten. + +Diese Schwierigkeit ist strukturell dieselbe wie das frühere WLAN-Problem +mit Fedora/Anaconda: interaktive Distributions-Installer (Ubiquity, +Anaconda, potenziell Subiquity) sind für menschliche Bedienung gebaut, +nicht für Automatisierung - jede Automatisierungslösung dagegen ist eine +fragile, distributionsspezifische Sonderkonstruktion. Zusätzlich würde +"jeden Installer einzeln automatisieren" das Projekt vom eigentlichen +Ziel wegbewegen, dass ein Kunde frei zwischen Distributionen wählen kann. + +Der User hat diese Einschätzung unabhängig mit einer separaten +Claude-Web-Session vertieft; nach kritischer Durchsicht dieses Gesprächs +wurde gemeinsam entschieden, die Richtung zu ändern. + +## Entscheidung + +Der eigentliche Installationsschritt wird durch das Muster ersetzt, das +curtin (Canonical/MAAS) und FAI (Debian) bereits lösen: das bestehende, +bereits distributionsunabhängige Boot-/Provisionierungs-Environment +(Tuxflotte-Module `00`-`40`: Hardware-Erkennung, Netzwerk/WLAN, +Registrierung, Blueprint-Abruf) partitioniert die Zielplatte direkt +(`parted`/`mkfs`), entpackt ein fertiges Root-Filesystem-Image und macht +chroot-Nacharbeiten (fstab, initramfs, machine-id, SSH-Hostkeys, +Bootloader). + +**Golden Image bewusst schlank, ohne Desktop-Umgebung:** bei Tuxflotte +ist die kundensichtbare Identität (Cinnamon, Theming) laut +Blueprint/Merkmal-Modell (ADR-0002) ohnehin ein Merkmal, das der +Provisioning Agent erst nach dem ersten Boot per Ansible ausrollt - das +Golden Image selbst muss nur überall booten und Netzwerk haben. Damit +entfällt Ubiquity/GTK/AT-SPI für den Image-Bau komplett: der Bau läuft +rein über `debootstrap`, CLI-only, ohne GUI-Installer. + +**Reines Debian statt Mints Ubuntu-Basis nachzubilden:** da die +kundensichtbare Identität komplett aus der Ansible-Schicht kommt, ist die +exakte Basis-Distribution des Images zweitrangig - ein Nebeneffekt ist, +dass dieselbe Debian-Basis später auch für ein mögliches Ubuntu-Angebot +wiederverwendbar wäre. + +**Selbst gebaut statt curtin/FAI zu adoptieren:** die Einzelschritte +(parted/mkfs, tar/squashfs-Extraktion, chroot-Fixup, grub-install) sind +Standard-Handwerk. Volle Kontrolle/Debugbarkeit wiegt schwerer als der +Wegfall von Ubiquity/Anacondas eingebauter Bootloader-/Hardware-Logik - +genau die Fremdcode-Undurchsichtigkeit war das heutige Kernproblem. + +**Architektonisch passend:** `scripts/modules/40_backend.sh` orchestriert +Backends bereits über eine Fünf-Funktionen-Lebenszyklus-Schnittstelle +(`backend_init`/`backend_validate`/`backend_generate_config`/ +`backend_launch`/`backend_postinstall`) - ein neues Backend fügt sich ein, +ohne Orchestrator oder Module `00`-`40` zu ändern. Der Agent-Bootstrap +(`backends/mint/postinstall.sh`) ist bereits ein reines, +distributionsunabhängiges Bash-Skript, wiederverwendbar durch einfaches +chroot-Ausführen statt über `ubiquity/success_command`. + +Die heutige Ubiquity/AT-SPI-Arbeit bleibt als dokumentierte Referenz +(ADR-0023) erhalten, hat aber keine aktive Rolle mehr in diesem Plan - +auch nicht als Image-Bau-Werkzeug. + +Vollständiger Phasenplan: `~/.claude/plans/inherited-forging-puffin.md` +(Phase 0: Golden Image bauen; Phase 1: Kernmechanik isoliert testen; +Phase 2: neues Backend `backends/mint-image/`; Phase 3: End-to-End über +den echten Self-Service-Flow; Phase 4: diese ADR + Memory). + +## Phase 0+1: live verifiziert (29.08.2026) + +`scripts/build_golden_image.sh` baut eine schlanke Debian-bookworm-Basis +(Kernel, breites `linux-firmware`, NetworkManager, openssh-server) - kein +Root-Passwort, keine SSH-Hostkeys im Ergebnis (reale Zugangsdaten +entstehen erst durch den Provisioning Agent pro Geraet). +`scripts/lib/image_deploy.sh` kapselt die Deployment-Mechanik +(partitionieren, formatieren, mounten, Image entpacken, fstab aus echten +UUIDs, chroot-Fixup, Bootloader-Installation UEFI+BIOS) als +wiederverwendbare Funktionsbibliothek; `scripts/image_deploy_test.sh` ist +der isolierte Testtreiber für Phase 1. + +Live auf der lenny-QEMU-VM getestet (frische 20-GB-Platte, UEFI/OVMF), +dabei drei reale Bugs gefunden und behoben: + +1. **`zstd` verweigerte das Überschreiben** der Ausgabedatei bei + wiederholten Baeulaeufen - `-f` ergänzt. +2. **`grub-install` konnte im Testkontext keinen NVRAM-Booteintrag + setzen** ("EFI variables are not supported on this system"), ohne + `--removable` blieb dann nur ein benannter Pfad übrig, den die + Firmware ohne NVRAM-Eintrag nie findet ("No bootable option or device + was found" beim ersten Boot-Test). Fix: zusätzlicher `grub-install`- + Lauf mit `--removable` schreibt auf den Standard-Fallback-Pfad + `EFI/BOOT/BOOTX64.EFI` - robuster generell für heterogene + Zielhardware, nicht nur für dieses Testszenario. +3. **Kritischster Fund:** das komplette Root-Dateisystem des Golden + Image hatte die Rechte `0700` statt `0755` - `mktemp -d` legt sein + Zielverzeichnis mit `0700` an, `debootstrap` ändert das nicht, und + `tar -p` übernahm diesen Modus beim Verpacken/Entpacken 1:1 als + Root-Verzeichnis-Rechte des gesamten ausgerollten Systems. Ergebnis: + jeder nicht-root-Prozess (dbus-daemon wechselt intern auf den + unprivilegierten "messagebus"-Benutzer) bekam "Permission denied" + schon beim Traversieren von "/" - eine komplette Boot-Fehlerkaskade + (dbus, systemd-logind, NetworkManager, wpa_supplicant, ModemManager + schlugen alle fehl, kein Netzwerk). Fix: `chmod 0755` direkt nach + `debootstrap` in `build_golden_image.sh`. + +Nach allen drei Fixes: sauberer, stiller Boot bis zum Login-Prompt, keine +einzige `[FAILED]`-Zeile, echte DHCP-Lease bestätigt +(`192.168.122.244`, Hostname `tuxflotte-image-test` korrekt gesetzt). Der +Erfolgsmaßstab für Phase 0+1 ("bootet überall, hat Netzwerk") ist damit +erreicht. + +## Nächste Schritte + +Phase 2 (Backend `backends/mint-image/`) und Phase 3 (End-to-End über den +echten Self-Service-Flow) sind noch offen - siehe Plandatei. Fedora/Ubuntu +folgen erst nach erfolgreichem Mint-Vollzyklus demselben Muster.