Auto-Modus (TUXFLOTTE_AUTO_MODE=true, über config/installer.conf als
exportierte Env-Var vor 05_network.sh gesetzt) überspringt alle drei
interaktiven Gates, die bei genauerem Hinsehen existierten (nicht nur
das eine ursprünglich im Plan genannte):
- 05_network.sh: nicht-interaktiver WLAN-Pfad über TUXFLOTTE_WIFI_SSID/
TUXFLOTTE_WIFI_PSK, analog zum bestehenden TUXFLOTTE_ACTIVATION_CODE-
Muster in 12_enrollment_auth.sh (unverändert, unterstützte das schon).
- 17_device_status.sh: "Provisionierung fortsetzen?"-Prompt übersprungen.
- 20_profile_selection.sh: "Vorlage auswählen?"-Prompt übersprungen,
wählt automatisch die als is_default markierte Vorlage (echter
Server-Hinweis via Enrollment Session erst mit Phase 3 möglich).
- 25_installation_confirm.sh: eigentliches Commit-Gate übersprungen.
Alle drei Auto-Modus-Zweige lokal verifiziert (Skripte direkt mit
TUXFLOTTE_AUTO_MODE=true und präparierten Eingabedateien ausgeführt,
kein Hängenbleiben an read -p, korrekte state.env/template.json-Ausgabe).
Partitionierung: installation_directives.partitioning von einfachem
String auf strukturiertes Objekt umgestellt ({"scheme": "single"|
"custom", "root_filesystem", "extra_partitions": [{"mountpoint",
"filesystem", "percent"}]}) - Vertrag, an den sich provisioning-server
in Phase 3 halten muss. backend_generate_config() baut daraus ein
partman-auto/expert_recipe (ersetzt die bisherige choose_recipe-
Fallunterscheidung mit nur "default"/"atomic"), Prozentangaben werden
anhand der realen Zieldatenträgergröße (lsblk/blockdev, erst live auf
dem Zielgerät bekannt) in feste MB-Größen umgerechnet.
Auf UEFI-Systemen wird zusätzlich eine EFI-System-Partition ins Recipe
aufgenommen (sonst verweigert/warnt der Installer, "No EFI System
Partition was found") - exakte Stanza-Syntax nicht aus der Erinnerung
geraten, sondern aus /usr/lib/partman/recipes-amd64-efi/30atomic auf
dem echten Live-Medium ausgelesen ($reusemethod{ } war der fehlende
Teil in einem ersten, geparsten aber nicht erkannten Versuch).
backend_init() installiert jetzt auch jq/envsubst(gettext-base)/cpio
bei Bedarf nach (vorbestehende Lücke neben dem schon in Phase 1
behobenen kexec-tools).
Real per QEMU verifiziert: eigene Ein-Datenträger-Erkennung musste
gehärtet werden (nbd/zram-Geräte mit Größe 0 wurden fälschlich vor dem
echten Datenträger gewählt - auf einer sauberen VM allein wäre das nicht
aufgefallen). Custom-Recipe mit ext4-Root + ext4-/home (20%) +
btrfs-/var (10%) auf 40GB-Testplatte: vollständige unbeaufsichtigte
Installation inkl. Paketinstallation durchlaufen lassen, danach von der
Festplatte (nicht der Live-CD) gebootet - Login-Bildschirm mit korrektem
Hostname erscheint, System bootet einwandfrei per UEFI/ESP.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Startet die unbeaufsichtigte Ubiquity-Installation direkt aus dem
laufenden Live-System heraus per kexec - das personalisierte, erst
zur Laufzeit erzeugte Preseed (Hostname/Geräte-ID/Partitionierung
sind erst hier bekannt) wird dafür in eine zusätzliche Initrd-Schicht
eingebettet (aneinandergehängte cpio-Archive, vom Kernel nativ
unterstützt) statt per file=/cdrom/... (read-only Medium) oder
url=<lokaler Server> (Prozess-/Netzwerkzustand geht beim Kexec-Sprung
verloren).
backend_init() installiert kexec-tools jetzt bei Bedarf nach (auf dem
Live-Medium anders als im Zielsystem nicht vorinstalliert).
Real per QEMU verifiziert: kexec aus laufender Live-Sitzung heraus
funktioniert, automatic-ubiquity mit sowohl url= als auch
initrd-eingebettetem file= erreicht, komplette unbeaufsichtigte
Installation (Partitionierung, Paketinstallation, success_command)
bis zum funktionierenden Login-Bildschirm durchlaufen lassen. Danach
zusätzlich der tatsächliche, committete backend.sh-Code (nicht nur
die Spike-Annäherung) end-to-end über alle fünf Lifecycle-Funktionen
gegen ein reales runtime_blueprint.json/response.json bestätigt.
Bekannte Restlücke: jq/envsubst/base64 sind auf dem Live-Medium
ebenfalls nicht vorinstalliert (backend_init prüft nur, installiert
nicht nach) - vorbestehende Lücke, nicht Teil dieser Änderung.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fehlte bisher komplett - backends/mint/ enthielt nur handgepatchte
WLAN-Test-Artefakte, kein backend.sh, sodass 40_backend.sh mit
"Kein Backend für 'mint' gefunden" abbrach.
Baut auf dem bereits real erprobten wlan-test.seed-Muster auf (Ubiquity/
Preseed, nicht Subiquity/Autoinstall - siehe ADR-0009), generalisiert zu
einem echten Template mit denselben Platzhaltern wie Fedoras kickstart.tpl:
- backends/mint/backend.sh: 5-Funktionen-Contract 1:1 wie Fedora
(backend_init/validate/generate_config/launch/postinstall),
backend_launch() bewusst als Stub (echte Parität mit Fedoras
heutigem Stand, kein Vorgriff auf das noch nicht entschiedene
Self-Service-Portal-Modell).
- backends/mint/preseed.tpl + postinstall.sh: echter Agent-Bootstrap
(curl agent.py, Bootstrap-POST, Credentials, systemd enable) im
ubiquity/success_command, zweistufig envsubst+base64 gerendert
(Debconf-Fallstrick bei mehrzeiligen Preseed-Werten, real erprobt).
- scripts/build.sh: Backend-Argument (fedora|mint), Mint-Pfade real
gegen die vorhandene Test-ISO verifiziert (/boot/grub/grub.cfg,
/isolinux/live.cfg, /preseed/tuxflotte.seed - keine zweite ESP-Kopie
wie bei Fedora), Test-Preseed-Bake mit Platzhalterwerten.
- profiles/mint-desktop/profile.json: installer.type von "autoinstall"
auf "preseed" korrigiert (ADR-0009 hatte den alten Wert als vermutlich
falsch benannt markiert - jetzt bestätigt und korrigiert).
End-to-end auf echter QEMU-Hardware verifiziert: automatisierte
Installation, Reboot, Agent-Bootstrap, Check-in, ansible-pull-Zyklus
(PLAY RECAP failed=0) - kompletter Kreislauf funktioniert. Dabei
gefunden und gefixt: d-i pkgsel/include string ansible-core git fehlte
(Pendant zu Fedoras kickstart.tpl %packages) - ohne das lief der
Agent-Dienst in einer Restart-Fehlerschleife.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fetch the provisioning agent from git.tuxflotte.de, register it via
POST /api/v1/agent/bootstrap using the device id from the activation
response, write /etc/tuxflotte/agent.credentials, and enable the
tuxflotte-agent systemd service so it starts on first boot. Verified
end to end against a QEMU test VM and the real anode API.
The device id is now threaded through backend_generate_config() and
substituted into the kickstart template like the existing hostname
and blueprint values. %post drops the implicit chroot-wide set -e in
favor of per-step error handling, since localectl calls in this
section are known to fail best-effort without a running D-Bus.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Boot menus now default to "boot from local disk" instead of the
destructive auto-install entry -- the earlier version would have run
the destructive install automatically on a timeout with no action
taken, backwards from the intended safety gate.
early-command-test-FAILED.sh is kept as-is (not wired into the seed)
purely as a record of what was tried: d-i preseed/early_command never
executed at all under Ubiquity, see ADR-0009's 01.08.2026 update for
why (Ubiquity's own Python plugin architecture has no hook for it).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Manual test artifacts (like backends/fedora/*-test.cfg), not part of a
backend lifecycle yet -- Mint has no backend.sh implementation. These
are what actually proved on real hardware that WLAN works during
Ubiquity's install, live contact with anode during install works, and
a directly-written .nmconnection file survives into the installed
system and reconnects automatically.
wlan-test.seed: the deployed preseed (file=/cdrom/preseed/...seed,
automatic-ubiquity). success_command is base64-encoded -- the
human-readable source for that is wlan-test-post-install.sh; a
straightforward multi-line quoted success_command value silently never
ran at all, traced to debconf's own preseed line-continuation
handling, not a bash issue (see ADR-0009's 31.07.2026 updates).
wlan-test-boot-grub.cfg / wlan-test-isolinux-live.cfg: the patched
UEFI/BIOS boot menus, unlike Fedora's ISO this medium has no hidden
second FAT/ESP grub.cfg copy to patch separately.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Same offline-install idea as wlan-netinst-test.cfg but on a genuine
DVD/Everything-style medium instead of netinstall, to sidestep the
network dependency during %packages. Ended up hanging at
dracut-initqueue for a reason that turned out to be independent of the
network line entirely (confirmed by testing with no network directive
at all, then with a physical Ethernet cable plugged in) -- see the
30.07.2026 ADR-0009 update for the full account.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Not part of the backend lifecycle (40_backend.sh) -- run by hand during
the live/netinstall boot flow investigation documented in ADR-0009.
kexec-reboot-test.sh/.cfg: tests whether inst.ks= can trigger Anaconda
via kexec from within the running Fedora Cinnamon live session, without
a real firmware reboot. Conclusively fails: the live initrd has no
anaconda dracut module at all.
wlan-netinst-test.cfg: the kickstart used to validate inst.ks=cdrom:/ks.cfg
on a real Fedora netinstall ISO, including the failed WLAN activation
attempts (network --wpakey=, then %pre nmcli) that exposed the missing
iwlwifi driver in that image's initrd.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
These are run as standalone subprocesses via run_module()/source, which
requires the execute bit. Missing since their initial creation - only
noticed because manually chmod'd copies were used for testing on anode,
never the checked-in files. Would have failed on a fresh checkout.
30_runtime_blueprint.sh calls POST /templates/{id}/resolve with the
device_id from the server handshake and the template_id from the
Bereitstellungsvorlage selection, storing the resulting Runtime
Blueprint under /run/tuxflotte/runtime/.
40_backend.sh dispatches to backends/${backend_id}/backend.sh based on
the resolved backend_id and drives the backend_init/validate/
generate_config/launch/postinstall lifecycle from 06-backend-api.md.
backends/fedora/backend.sh implements that lifecycle for Fedora:
backend_generate_config() renders kickstart.tpl via envsubst using the
Runtime Blueprint's installation_directives and the device hostname,
embedding the resolved Merkmal blueprints as JSON for the (not yet
implemented) Provisioning Agent to apply later. Replaces the old
git-clone-based %post bootstrap. backend_launch()/backend_postinstall()
are Phase 1 stubs pending the live-ISO boot integration (see
platform-docs ADR-0003).