47 Commits

Author SHA1 Message Date
124594e2ae chore: erneut versehentlich mitgestagete SOURCE_ISO.sha256 entfernen
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 16:03:03 +02:00
2669252703 fix: username=/hostname=mint auch im kexec-Append fuer den zweiten Boot
Real beim Testen entdeckt: ohne diese beiden Parameter (im Gegensatz zum
ersten Boot, dessen grub.cfg-Eintrag sie explizit setzt) verlangt der
Konsolenlogin auf dem zweiten (kexec-)Boot ein echtes, unbekanntes
Passwort statt des sonst leeren Live-Session-Passworts - erschwerte die
Fehlersuche via tty2-Konsole unnoetig. Fuer den GTK-Assistenten selbst
(kein Konsolenlogin noetig) folgenlos, aber Konsistenz zwischen beiden
Boots ist fuer kuenftige Diagnosen wertvoll.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 16:02:57 +02:00
97bdbae58c chore: unbeabsichtigt mitgestagete Build-Artefakte entfernen, __pycache__ ignorieren
SOURCE_ISO.sha256 (Fedora-Testrest) und der lokale pyc-Cache aus dem
letzten Commit landeten versehentlich per 'git add -A' im Repo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 15:43:04 +02:00
6e99b3bf3a fix: atspi_click.py sprachunabhaengig statt reine deutsche Werteliste
Real beim Testen entdeckt: die Mint-eigene 'Multimedia-Codecs'-Seite zeigt
trotz debian-installer/language=de englische Buttons ('Quit'/'Back'/
'Continue') - vermutlich derselbe fehlende .mo-Uebersetzungskatalog wie
beim bereits gepatchten ubi-prepare.py-None-Bug. Die deutsche
FORWARD_LABELS-Werteliste haette hier fuer immer haengen bleiben.

Neue Strategie in select_target(): bekannte rueckwaerts-/abbrechende
Beschriftungen (zweisprachig) werden ausgeschlossen, danach wird bevorzugt
wer eine bekannte vorwaerts-Beschriftung traegt, sonst der einzige
verbleibende Kandidat (Sole-Survivor) - deckt auch unbekannte/nicht
uebersetzte Labels ab. Bei echter Mehrdeutigkeit (mehrere unbekannte
Kandidaten gleichzeitig) wird bewusst NICHT geklickt statt zu raten.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 15:42:55 +02:00
a415de1eaa feat: Autoklicker auf AT-SPI umgestellt statt Bildschirmkoordinaten
xdotool/Enter-Taste-Ansatz war nicht zuverlaessig genug (Metacity erzeugt
mehrere ueberlappende X11-Fenster aehnlicher Groesse, 'groesstes Fenster'-
Heuristik traf wiederholt das falsche; Enter aktiviert auf der
Partitionierungs-Uebersicht einen Ausklapp-Pfeil statt 'Jetzt
installieren' - siehe ADR-0023-Nachtrag).

- live-updates/usr/share/ubiquity/tuxflotte-atspi-env.sh (neu): aktiviert
  GTK_MODULES=gail:atk-bridge + Session-/A11y-Bus VOR dem GTK-Start von
  Ubiquity - muss vor dem Init passieren, eine Bruecke wird von einer
  bereits laufenden GTK-App nicht nachgeladen.
- initrd-hooks/casper-bottom/99casperboot: bindet obige Datei per
  Ein-Zeilen-Sed-Patch in start-ubiquity-dm ein (dry-run gegen den echten
  Datei-Inhalt verifiziert).
- live-updates/opt/tuxflotte/scripts/atspi_click.py (neu): findet+klickt
  den passenden 'Weiter'-Button ueber Rolle+Name im Accessibility-Baum,
  feste deutsche Werteliste (Sprache per Preseed fest de_DE), niemals
  Zurueck/Abbrechen/Beenden.
- autoclicker.sh: ruft atspi_click.py in Schleife statt xdotool/Enter auf,
  wartet auf den ubiquity-Prozess statt auf den X-Socket.

Noch nicht live verifiziert - naechster Schritt: QEMU-Testlauf auf lenny.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 15:34:28 +02:00
941a58535d fix: noninteractive verworfen, automatic-ubiquity+Autoklicker, drei echte Bugs behoben
- noninteractive-Frontend endgueltig verworfen: PageNoninteractive-Stubs
  fuehren strukturell zur Endlosschleife im choose_partition-Zustands-
  automaten von ubi-partman.py, unabhaengig vom Preseed-Stand.
- Umstieg auf automatic-ubiquity (echte GTK-Oberflaeche) + eigener
  Autoklicker (live-updates/opt/tuxflotte/scripts/autoclicker.sh +
  systemd-Service), ausgeloest per Boot-Keyword tuxflotte-autoclick.
- Bug 1: jq fehlte beim echten Kiosk-Auslauf (kein manueller Vorab-
  Installationsschritt wie in Testlaeufen) - neues Modul
  00_preflight.sh installiert es als allererstes.
- Bug 2: echter Ubiquity-Crash in ubi-prepare.py (TypeError: Argument 1
  does not allow None as a value) - gezielter Sed-Patch im bestehenden
  99casperboot-Hook.
- Bug 3: 'd-i partman/choose_partition select finish' zwang denselben
  Endlosschleifen-Zustandsautomaten wie bei noninteractive, auch im
  GTK-Modus - Zeile ersatzlos entfernt, partman-auto/method+recipe
  genuegen.
- autoclicker.sh: Fenstersuche nach 'ubiquity' korrigiert (Fenstertitel
  ist tatsaechlich 'Installation (as superuser)', enthaelt das Wort nie).
- Alle vier Fixes live per QEMU verifiziert (jeweils frische Disk, realer
  Kiosk-Ausloeser/kexec-Pfad, nicht nur manuelle Nachstellung).

Offen: automatisierter Klick auf 'Jetzt installieren' auf der
Partitionierungs-Uebersichtsseite noch nicht zuverlaessig (Enter trifft
dort einen Ausklapp-Pfeil statt den Button). Siehe ADR-0023-Nachtrag.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 15:16:41 +02:00
6087243c82 fix: echte unbeaufsichtigte Mint-Installation (noninteractive-Frontend + Live-User-Bug)
Zwei unabhängige, live in der QEMU-Test-VM gefundene und verifizierte
Bugs, die zusammen jede automatisierte Installation verhindert haben:

1. start-kiosk.sh hatte /home/liveuser hartkodiert (mkdir + Epiphany-
   Profilpfad). Der tatsächliche Live-Benutzername auf dieser ISO ist
   'mint' (siehe grub/mint-*.cfg, username=mint überall) - /home/liveuser
   existiert nie und ist für den Live-User nicht anlegbar. Mit
   'set -euo pipefail' brach das Skript an dieser Stelle sofort ab,
   TUXFLOTTE_AUTO_MODE wurde nie erreicht, installer.sh lief nie los.
   Fix: $HOME statt hartkodiertem Pfad. Passend dazu die sudoers.d/
   90-tuxflotte-Regel von 'liveuser' auf 'mint' korrigiert (war zwar
   nicht der eigentliche Blocker, da Casper dem Live-User ohnehin
   bereits passwortloses sudo gibt, aber inhaltlich falsch/irreführend).

2. backend_launch()s kexec-Sprung nutzte 'automatic-ubiquity' allein -
   das startet weiterhin Ubiquitys GTK-Oberfläche (ubiquity-dm), die
   Werte aus dem Preseed zwar vorbelegt, aber pro Seite trotzdem auf
   einen Klick wartet (live verifiziert: Multimedia-Codecs-Seite blieb
   ohne Klick >60s unverändert stehen). Das erklärt die auf echter
   Hardware beobachteten "automatischen" Installationen, die dennoch
   jede Seite einzeln abfragten. Fix: zusätzliches Boot-Keyword
   'noninteractive' (siehe /usr/share/ubiquity/start-ubiquity-dm) lässt
   Casper stattdessen 'ubiquity noninteractive' direkt aufrufen -
   Ubiquitys eigenes, mitgeliefertes Headless-Frontend
   (frontend/noninteractive.py), das jede Seite mit auto_process=True
   rein über Debconf abarbeitet, ohne je ein Fenster zu zeichnen.

Live-verifiziert (QEMU, frische Disk): zweiter Boot nach kexec hat
'noninteractive' korrekt im Kernel-Cmdline, ps aux zeigt keinen
GTK-ubiquity-dm-Prozess mehr. /var/log/installer/debug bestätigt den
Frontend-Wechsel eindeutig per Exception-Traceback
(ubiquity.frontend.noninteractive.Wizard.question_dialog wirft
absichtlich NotImplementedError statt zu warten) - zugleich der
nächste, noch offene Befund: ubi-partman.py (Zeile 3484) stellt eine
Frage, die im aktuellen Preseed noch nicht beantwortet ist. Das ist
die einzige verbleibende Lücke zur echten Stille, siehe ADR-0023-
Nachtrag und project_e2e_flow_dogfooding_2026-08-28 (Memory).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-28 20:12:45 +02:00
c6489bb661 priority=critical fuer wirklich unbeaufsichtigtes Mint-Auto-Install
Siehe ADR-0023 (platform-docs) fuer die volle Fehlersuche. automatic-
ubiquity+noprompt allein reicht nicht, um jede Ubiquity-Seite zu
unterdruecken (live gefunden: Zeitzone/Codecs/Ueberschreiben/Benutzer-
anlage kamen trotz vollstaendigem Preseed interaktiv). priority=critical
ergaenzt, nur beim Tuxflotte-Auto-Install-Menuepunkt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 12:11:18 +02:00
18738be01d Merge: Volume-ID-Feature (anderer Session-Strang) + device_fingerprint-Lokalablage zusammenführen 2026-08-28 10:36:19 +02:00
385a42034a device_fingerprint zusaetzlich lokal auf dem Geraet hinterlegen
Siehe ADR-0022 (platform-docs). Beide Backends lesen den bereits waehrend
des Live-Boots berechneten Fingerprint aus hardware.json und schreiben ihn
nach /etc/tuxflotte/device_fingerprint - ermoeglicht beidseitige
Identifikation (Geraeteliste <-> Geraet selbst), vorher nur einseitig
moeglich.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 10:36:07 +02:00
d5010f5c7b feat: Volume-ID der Kunden-ISO per Parameter statt fest 'TUXFLOTTE'
Sechster, optionaler Parameter (volid) - provisioning-server berechnet ihn
jetzt aus Organisationsname + Bau-Datum (siehe compute_iso_volid() in
app.py) und reicht ihn durch. Fallback 'TUXFLOTTE' fuer Aufrufe ohne
sechsten Parameter (z.B. manuelle Tests). Keine Aenderung an den
GRUB-/isolinux-Boot-Configs noetig - iso-scan/filename=${iso_path} bzw.
boot=casper referenzieren die Volume-ID nicht direkt, anders als ein
frueherer Notiz-Stand vermuten liess.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 09:04:38 +02:00
517c2de919 fix: unsicheren GRUB-Standard-Boot-Eintrag aufräumen (Mint + Fedora)
mint-boot-grub.cfg: der nicht-EFI-Zweig ('grub_platform != efi') hatte
keinen 'lokale Festplatte booten'-Eintrag und defaultete via 'set
default="0"' auf den ersten Menüeintrag (normaler Live-Boot). Vermutlich
unerreichbar (BIOS läuft laut scripts/build.sh über isolinux, nicht über
diese grub.cfg), aber sicherer, den Zweig genauso abzusichern wie den
EFI-Zweig statt sich auf die Nichterreichbarkeit zu verlassen.

EFI-BOOT-grub.cfg + boot-grub2-grub.cfg (Fedora): echter, nicht nur
theoretischer Fund - 'set default="0"' zeigte dort direkt auf
'Tuxflotte Provisioning (automatisch)', den unbeaufsichtigten
Install-Eintrag. Exakt die unsichere Standardauswahl, die für Mint
bereits am 01.08.2026 korrigiert wurde (siehe ADR-0009), hier aber nie
nachgezogen - das Fedora-Backend bleibt laut ADR-0009 bewusst im Code
für eine mögliche künftige Wiederaufnahme, diese Dateien wären also im
Ernstfall tatsächlich die verwendeten Configs. Jetzt defaulten beide auf
den jeweiligen 'lokal booten'-Eintrag, wie bei Mint.

Alle vier Dateien mit grub2-script-check syntaktisch verifiziert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-12 21:59:24 +02:00
683cf70af5 fix: /updates auf dem Live-System deployen + Kunden-ISO-Build (Phase 4)
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>
2026-08-06 22:18:04 +02:00
108444ecf7 feat: Auto-Modus + prozentuale Partitionierung für Mint (Phase 2)
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>
2026-08-06 16:12:56 +02:00
d6a01462ef feat: backend_launch() für Mint real implementieren (Phase 1)
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>
2026-08-06 14:35:11 +02:00
15965551ec feat: Mint-Backend fuer den Installer (backend.sh + preseed.tpl)
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>
2026-08-04 19:00:16 +02:00
715658893c feat: implement backend_postinstall() for the Fedora backend
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>
2026-08-01 19:58:29 +02:00
05dfacab4a test: fix boot menu default direction, record the early_command dead end
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>
2026-08-01 11:59:47 +02:00
c990283676 test: add Mint/Ubiquity preseed artifacts that validated ADR-0009 end to end
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>
2026-07-31 16:29:16 +02:00
e2886c1efe test: add DVD kickstart used for the Fedora Server DVD dead end
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>
2026-07-30 16:08:13 +02:00
223bbd7c24 test: add manual kexec/kickstart-on-cdrom test scripts for ADR-0009
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>
2026-07-30 13:28:19 +02:00
50e41e2230 feat: switch kiosk autostart from terminal installer to Epiphany browser kiosk
Replaces the gnome-terminal-launched installer.sh session with a
browser-based kiosk (opt/tuxflotte/kiosk/start-kiosk.sh launching
Epiphany with --profile). Sets German keyboard layout for the
graphical session (vconsole.keymap only covers the text console),
suppresses Epiphany's default-browser prompt, hides desktop icons,
and reduces the panel to a window list + power applet. Also disables
the SELinux troubleshooter desktop notification, and copies the full
live-updates tree (not just etc/) so opt/ payload ships too.

Several Epiphany invocation modes were tried and discarded before
landing on plain --profile=<dir> (see ADR-0004/0006 and platform-docs
history for the rejected --application-mode/--private-instance paths).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 12:12:37 +02:00
1e83a27a57 fix: match GRUB search label to the TUXFLOTTE ISO volume ID
The GRUB config searched for the volume by the original Fedora label
(Fedora-Cinn-Live-44), which no longer matches once the ISO is built
with its own Tuxflotte volume ID.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 12:12:23 +02:00
cd91a6b393 feat: run installer.sh automatically inside the live session
Uses dracut's official 20-apply-live-updates.sh pre-pivot hook: any
/updates/ directory tree present at the top level of the boot media
gets copied into the live root filesystem before pivoting, verbatim,
no initrd or squashfs/EROFS modification needed. build.sh assembles
this tree from scripts/, backends/, config/ (mapped under
/opt/tuxflotte) plus live-updates/etc/ (an XDG autostart entry that
opens a terminal running installer.sh as root, and a sudoers.d drop-in
granting liveuser passwordless sudo).

xorriso preserves the ownership/permissions recorded at map time, so
-chown_r/-chgrp_r 0 on /updates is enough to make sudoers accept the
drop-in as root-owned without needing local root to build the ISO.

This was tried first as a direct EROFS unpack/repack of
/LiveOS/squashfs.img (that file is actually EROFS despite the name on
current Fedora), but a fresh self-built erofs-utils (Debian's
packaged 1.5-1 can't even read this image's on-disk format) hit a
reproducible bug extracting the packed/fragmented inode into a single
corrupt file instead of a directory tree. The dracut hook sidesteps
that path entirely.

Verified end-to-end: booting either Tuxflotte entry reaches the
Cinnamon live desktop, autostarts a terminal, and installer.sh runs
through every module (network, hardware, enrollment, handshake,
device status, Bereitstellungsvorlage selection, commit point, Runtime
Blueprint resolution against the real server, full Fedora backend
lifecycle, storage detection) to a clean exit.
2026-07-20 14:52:05 +02:00
a8cd66af94 feat: set German console keyboard layout on boot
Adds vconsole.keymap=de to both Tuxflotte GRUB entries.
2026-07-20 14:51:41 +02:00
dd7147aee0 fix: make 20_storage.sh self-contained like every other module
It called log_info/log_warn/error_exit/list_install_disks without
sourcing anything - leftover from before modules were run as
standalone subprocesses via run_module() rather than sourced into
installer.sh. Never noticed because the pipeline never reached this
module in a live run until now. Behavior unchanged: still just lists
disks and warns that partitioning is disabled (Phase 1).
2026-07-20 14:51:28 +02:00
6a48a7c929 fix: tolerate nmcli connection.filename failure for in-memory live connections
export_connection_profile() crashed the whole installer under set -e/
pipefail when the active NetworkManager connection has no backing
keyfile (common for ephemeral live-boot DHCP connections) - nmcli
returned a non-zero exit status even though the guard below already
handles an empty result gracefully. Every other nmcli call in this
function already has this || true safety net; this one was missing it.

Found via a live end-to-end boot test in Proxmox.
2026-07-20 14:51:22 +02:00
1a38f8ef3c fix: set execute bit on Fedora backend and runtime-blueprint/backend modules
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.
2026-07-20 14:51:12 +02:00
c4f6079077 feat: apply Tuxflotte color scheme to GRUB boot menu
Blue-on-white (matching pics/tuxflotte-beschriftet-schatten.svg's
brand color rgb(52,101,164)) instead of GRUB's default white-on-black.

The logo image itself doesn't work here: classic gfxterm always paints
an opaque per-character cell background, so a background_image gets
fully covered by color_normal's background and never becomes visible -
confirmed by booting the composited variant in QEMU before dropping it
again. Showing the actual logo needs the GRUB theme/gfxmenu engine,
which this live ISO doesn't ship (empty /boot/grub2/themes, no
x86_64-efi module directory) - not attempted here. The logo fits more
naturally on the Plymouth splash or live-desktop wallpaper instead,
both already confirmed to render correctly.
2026-07-18 17:08:40 +02:00
804827c5a9 feat: switch provisioning ISO to a live medium with auto/interactive boot entries
Replaces the Fedora DVD/netinst base with a live-ISO boot chain
(root=live:CDLABEL=Fedora-Cinn-Live-44 rd.live.image instead of
inst.stage2=/inst.ks=), implementing ADR-0003. The GRUB menu now
offers two entries booting the same live image with a
tuxflotte.mode=auto/interactive kernel cmdline flag instead of a
boot-time kickstart URL - installer.sh will read this flag once it
runs inside the live session.

scripts/build.sh and scripts/extract.sh now extract the source ISO via
`xorriso -osirrox` instead of a loop mount, removing the sudo
dependency for local builds.

Verified end-to-end in QEMU/KVM: GRUB menu renders both entries,
kernel/initrd load correctly, boot proceeds to the live session.
2026-07-18 17:08:12 +02:00
086917deec feat: resolve Runtime Blueprint and add Fedora backend for kickstart generation
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).
2026-07-18 10:49:50 +02:00
3a7549adf1 fix: align profile selection and installation confirm with Bereitstellungsvorlage model
20_profile_selection.sh and 25_installation_confirm.sh still spoke the
old flat profile model (.profiles[], .profile.distribution,
.profile.installer.type) that the provisioning server no longer
returns - it now returns .templates[] with workspace/backend objects
(see provisioning-server's Merkmal/Blueprint/Bereitstellungsvorlage
migration). Both modules now read/write
/run/tuxflotte/assignment/template.json against the current
Bereitstellungsvorlage schema, matching 10-interactive-provisioning-flow.md.
2026-07-18 10:49:42 +02:00
f7f8e93c30 feat: prompt for bootstrap enrollment authorization 2026-07-14 13:44:31 +02:00
262fa88057 refactor: isolate enrollment authorization from handshake 2026-07-14 13:39:56 +02:00
b11fa1cb76 feat: add device status interaction and early abort 2026-07-14 13:26:48 +02:00
f1cb04bd24 feat: add interactive provisioning flow and commit point 2026-07-14 12:41:01 +02:00
1d3262d69f feat: integrate network and server handshake into installer flow 2026-07-14 10:57:59 +02:00
57ece79693 feat: add local boot entries and bump ISO to 0.2 2026-07-13 10:46:33 +02:00
0116e4b905 feat: implement provisioning server handshake 2026-07-13 09:25:10 +02:00
dc8a2df9d2 feat: initialize provisioning network 2026-07-13 09:15:37 +02:00
74a6e181ce feat: collect hardware and device identity 2026-07-13 09:15:00 +02:00
b1f35a5ef4 Refactor installer into modular orchestration framework 2026-07-07 10:27:32 +02:00
c7b660df9a Build first bootable Tuxflotte Provisioning ISO 2026-07-06 20:48:44 +02:00
655da9d431 Add unified installer build script 2026-07-06 14:43:24 +02:00
bdba09b3e1 Add ISO extraction script 2026-07-06 14:30:26 +02:00
b009d3abb6 Import upstream Fedora GRUB configuration 2026-07-03 14:22:34 +02:00
05a51e137d Initial installer repository structure 2026-07-03 14:21:22 +02:00