platform-docs/architecture/13-live-provisioning-boot.md
Thomas Stallinger 8a7ea7192f docs: record first successful end-to-end live-ISO provisioning run
Replaces the stale "not yet implemented" note for installer.sh
autostart with the actual mechanism (dracut's official
20-apply-live-updates.sh pre-pivot hook via a top-level /updates/
directory, not squashfs/EROFS remastering - that image is EROFS
despite the filename, and hit a reproducible erofs-utils extraction
bug even freshly built from source). Adds the milestone entry for the
first clean end-to-end run through every module, live in Proxmox.
2026-07-20 15:01:23 +02:00

9.3 KiB

Live-Provisionierung und Boot-Modi

Status: Beschlossen Datum: 18.07.2026

Zweck dieses Dokuments

Dieses Dokument beschreibt, wie die Provisionierungs-ISO bootet, wie der automatisierte und der interaktive Ablauf sich unterscheiden, und wie der native Installer aus der Live-Umgebung heraus gestartet wird.

Es ergänzt 10-interactive-provisioning-flow.md (F-005), das den interaktiven Ablauf selbst beschreibt, um die Boot-Ebene davor.

Siehe ADR-0003 für die Entscheidung und ihre Begründung.


Ausgangslage

Die bisherige ISO basiert auf einer Fedora-DVD/Netinst-Struktur ohne Live-Umgebung. GRUB startet Anaconda direkt, mit einer über inst.ks= fest verdrahteten Kickstart-URL. Der gesamte in F-005 beschriebene Ablauf hat darauf keinen Einstiegspunkt.

Die neue ISO basiert stattdessen auf einem echten Live-Medium (erkennbar an /LiveOS/squashfs.img). scripts/installer.sh läuft als gewöhnliche Anwendung innerhalb dieser Live-Sitzung, mit vollem Zugriff auf Netzwerk (NetworkManager, WLAN), Bildschirm und Tastatur.


Boot-Ablauf

Boot
 ↓
GRUB-Menü (Countdown)
 ├── Zeitüberschreitung oder Standardeintrag
 │     ↓
 │   Live-Umgebung startet mit tuxflotte.mode=auto
 │
 └── manuelle Auswahl des zweiten Eintrags
       ↓
     Live-Umgebung startet mit tuxflotte.mode=interactive
 ↓
installer.sh liest tuxflotte.mode
 ↓
Netzwerk, Hardware, Aktivierung (wie bisher, "always"-Module)
 ↓
Moduswahl
 ├── auto
 │     ↓
 │   device.registration_status prüfen
 │     ├── existing    → Bereitstellungsvorlage automatisch wählen (is_default), Commit Point automatisch bestätigen
 │     └── registered  → Fail-Closed-Abbruch, Verweis auf interaktiven Ablauf
 │
 └── interactive
       ↓
     bisheriger F-005-Ablauf (Bereitstellungsvorlage-Auswahl, explizite Bestätigung)
 ↓
Runtime Blueprint erzeugen → Backend laden → backend_generate_config()
 ↓
backend_launch() startet den nativen Installer explizit aus der Live-Sitzung heraus

Beide Moduspfade laufen ab „Runtime Blueprint erzeugen" identisch weiter. Der Unterschied liegt ausschließlich davor: in der Frage, ob eine Bereitstellungsvorlage interaktiv gewählt und der Commit Point interaktiv bestätigt wird, oder ob beides automatisch anhand vorhandener Daten geschieht.


Auto-Modus-Gate

Der automatisierte Ablauf ersetzt keine Sicherheitsprüfung, sondern ersetzt nur, wer die Bestätigung gibt: statt einer Benutzereingabe entscheidet ein bereits bestehender, geprüfter Zustand.

Voraussetzung für den automatisierten Ablauf ist ausschließlich:

device.registration_status == "existing" in der Antwort von POST /api/v1/activate.

Ein unbekanntes Gerät (registration_status == "registered") durchläuft niemals den automatisierten Ablauf, unabhängig vom gewählten Bootmenüeintrag. Die Geräteaufnahme bleibt gemäß 11-device-enrollment.md an eine explizite, interaktive Bestätigung gebunden.

Das Fail-Closed-Prinzip aus 10-interactive-provisioning-flow.md gilt unverändert: Fehlt eine gültige Grundlage für die automatische Bestätigung (zum Beispiel eine unerwartete oder unlesbare Serverantwort), bricht der Ablauf ab, statt ersatzweise eine Bestätigung anzunehmen.


Konsequenz für die Geräteregistrierung

Wer ein Gerät registriert, akzeptiert damit, dass dieses Gerät künftig ohne erneute interaktive Rückfrage automatisiert neu installiert werden kann, solange es über seinen Hardware-Fingerprint als bereits registriert erkannt wird.

Dies wird bei der Geräteregistrierung ausdrücklich kommuniziert (siehe 11-device-enrollment.md).


Nativer Installer aus der Live-Sitzung

Der native Installer wird nicht mehr über einen boot-zeitlichen Parameter gestartet.

Stattdessen ruft backend_launch() (siehe 06-backend-api.md) den nativen Installer explizit auf, mit der zuvor von backend_generate_config() erzeugten, lokal vorliegenden Konfiguration.

Die statische Kickstart-Datei sowie ihr Server-Endpoint (GET /installers/fedora-workstation/ks.cfg) entfallen damit.


WLAN-Zugangsdaten

Zwei getrennte Anwendungsfälle:

WLAN für die Live-Provisionierungsumgebung. Ohne Netzwerk ist der Provisioning-Server nicht erreichbar. Zugangsdaten für dieses Netzwerk müssen deshalb bereits im ISO-Build hinterlegt sein (zum Beispiel als NetworkManager-Verbindungsprofil in einem organisationsspezifischen ISO-Build), nicht dynamisch vom Server geladen werden.

WLAN für das installierte Zielsystem. Dies ist eine dauerhafte, organisationsweite Vorgabe und gehört zum noch unspezifizierten Network Profile-Modell der Organization (siehe 09-data-model-v1.md). Die Anwendung erfolgt wie andere organisationsweite Vorgaben, nicht als Teil der Provisionierungs-Bootphase.


Konkrete Umsetzung (Stand 18.07.2026)

Als konkrete Basis wird eine Fedora-Cinnamon-Live-ISO verwendet (Volume-Label Fedora-Cinn-Live-44), nicht Fedora Workstation Live. Für die Zwecke dieses Dokuments ist das austauschbar — entscheidend ist ausschließlich das Vorhandensein von /LiveOS/squashfs.img, nicht die konkrete Desktop-Umgebung.

Das in der Boot-Ablauf-Grafik oben genannte Kernel-Cmdline-Flag heißt konkret tuxflotte.mode und wird als tuxflotte.mode=auto beziehungsweise tuxflotte.mode=interactive an den Kernel übergeben, zusätzlich zu den vom Live-Medium ohnehin benötigten Parametern (root=live:CDLABEL=Fedora-Cinn-Live-44 rd.live.image) sowie vconsole.keymap=de. installer.sh soll den gewählten Modus zur Laufzeit aus /proc/cmdline lesen (siehe „Noch nicht umgesetzt" unten) — aktuell durchläuft es unabhängig vom Flag immer den vollständigen interaktiven Ablauf.

Das GRUB-Menü verwendet einen Countdown von 10 Sekunden; der Auto-Eintrag ist Index 0 und damit Standardauswahl. Ein dritter Menüpunkt zum Booten des bereits installierten lokalen Systems bleibt erhalten (vormals in 01-layered-provisioning.md als Anforderung an das Bootmenü genannt).

scripts/build.sh und scripts/extract.sh extrahieren die Quell-ISO über xorriso -osirrox statt über einen Loop-Mount und benötigen dadurch keine Root-Rechte mehr für den Build selbst.

Das Menü verwendet ein Farbschema in Markenblau (color_normal=blue/white, color_highlight=white/blue, angelehnt an rgb(52,101,164) aus pics/tuxflotte-beschriftet-schatten.svg). Das Logo selbst lässt sich darin nicht darstellen: Klassisches gfxterm malt bei jeder Zeichenzelle einen deckenden Hintergrund, wodurch ein background_image vollständig verdeckt wird — geprüft durch tatsächliches Booten der Variante mit Logo in QEMU. Ein sichtbares Logo bräuchte die GRUB-Theme-Engine (gfxmenu/theme.txt), die diese Live-ISO nicht mitbringt (leeres /boot/grub2/themes, kein x86_64-efi-Modulverzeichnis). Das Logo ist deshalb für den Plymouth-Bootsplash oder den Live-Desktop-Hintergrund vorgesehen, nicht für das GRUB-Menü.

Autostart von installer.sh

Das Installer-Payload wird nicht in /LiveOS/squashfs.img integriert — dieses Image ist trotz des Namens EROFS statt SquashFS, und die einzige verfügbare erofs-utils-Tooling-Version (auch frisch aus dem Quellcode gebaut) extrahiert das gepackte/fragmentierte Inode dieses konkreten Images fehlerhaft.

Stattdessen nutzt der Build den offiziellen Dracut-Hook 20-apply-live-updates.sh (var/lib/dracut/hooks/pre-pivot/): Ein updates/-Verzeichnis direkt auf dem Boot-Medium (nicht im komprimierten Image) wird von Dracut automatisch vollständig in das Live-Root kopiert, bevor die Live-Sitzung startet — ganz ohne Image-Remastering.

scripts/build.sh (prepare_updates()) baut dieses Verzeichnis zur Build-Zeit aus scripts/, backends/, config/ (unter /opt/tuxflotte) sowie live-updates/etc/ zusammen:

  • etc/xdg/autostart/tuxflotte-installer.desktop — startet beim Anmelden von liveuser automatisch ein Terminal mit installer.sh als root.
  • etc/sudoers.d/90-tuxflotteliveuser erhält passwortloses sudo (angemessen für diese Wegwerf-Live-Umgebung).

xorriso übernimmt beim -map die Berechtigungen der lokalen Quelldateien in die ISO. Da liveusers uid (1000) sonst mitkopiert würde und sudo root-fremde sudoers.d-Dateien verweigert, setzt der Build -chown_r 0 /updates -- -chgrp_r 0 /updates -- explizit auf das gesamte updates/-Verzeichnis — ganz ohne lokales root beim Bauen.

Verifiziert per vollständigem Live-Boot in Proxmox: Autostart-Terminal öffnet sich zuverlässig, installer.sh durchläuft alle Module bis zum sauberen Exit (siehe roadmap/milestones.md, 2026-07-20).

Noch nicht umgesetzt: installer.sh liest tuxflotte.mode noch nicht aus und durchläuft deshalb immer den vollständigen interaktiven Ablauf, unabhängig vom gewählten Bootmenüeintrag. backend_launch()/backend_postinstall() bleiben Phase-1-Stubs — der native Installer wird noch nicht tatsächlich gestartet.


Zusammenfassung

Die Live-ISO ersetzt das direkte Booten in Anaconda durch eine vorgeschaltete, frei gestaltbare Live-Sitzung, in der installer.sh läuft.

Ein Bootmenü mit Countdown unterscheidet zwischen automatisiertem und interaktivem Ablauf; beide münden ab der Runtime-Blueprint-Erzeugung in denselben Codepfad.

Automatisierung ersetzt keine Sicherheitsprüfung, sondern bindet die Bestätigung an eine bereits bestehende, geprüfte Gerätezuordnung statt an eine Benutzereingabe.