platform-docs/adr/0023-ubiquity-priority-critical-fuer-echte-stille.md
Thomas Stallinger 6769df27be docs: ADR-0023 Nachtrag - noninteractive verworfen, automatic-ubiquity+Autoklicker
Datei war bisher nie committed (Versehen aus einer frueheren Sitzung).
Enthaelt jetzt den vollstaendigen, bereits ausgearbeiteten Stand
inklusive des heutigen Nachtrags: noninteractive-Frontend endgueltig
verworfen (strukturelle PageNoninteractive-Stubs fuehren zur
Endlosschleife), Umstieg auf automatic-ubiquity + eigener Autoklicker,
drei real gefundene und behobene Bugs (fehlendes jq beim Kiosk-Auslauf,
Ubiquity-GTK-Absturz in ubi-prepare.py, choose_partition-select-finish-
Endlosschleife), Klarstellung dass der GRUB/isolinux-Sicherheits-Default
kein Bug ist (ADR-0009), und der noch offene automatisierte Klick auf
'Jetzt installieren'.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 15:17:32 +02:00

336 lines
19 KiB
Markdown

# ADR-0023: `priority=critical` fürs wirklich unbeaufsichtigte Mint-Install
**Status:** Beschlossen
**Datum:** 28.08.2026
## Kontext
Beim ersten echten Self-Service-Flow-Test auf physischer Hardware (Notebook,
Organisation "Liebherr", 28.08.2026) zeigte die Installation trotz
"Tuxflotte Auto-Install"-Bootmenüeintrag (`automatic-ubiquity noprompt` im
Kernel-Append, korrekter, vollständig aufgelöster Preseed mit allen
nötigen Werten — Netzwerk, Zeitzone, Partitionierung, Benutzer, Codecs)
**jede** Ubiquity-Seite interaktiv an: Zeitzone-Bestätigung,
Multimedia-Codecs-Frage, "Vorhandene Installation überschreiben?" und
Benutzeranlage.
Ausführliche Live-Fehlersuche (siehe [[project_e2e_flow_dogfooding_2026-08-28]]
für den vollständigen Verlauf) hat mehrere naheliegende Verdächtige
geprüft und ausgeschlossen, bevor die eigentliche Ursache gefunden wurde:
- Falsch gewählter Bootmenüeintrag — ausgeschlossen (User hat "Tuxflotte
Auto-Install" korrekt gewählt, bestätigt durch Bildschirm: kein
Cinnamon-Desktop sichtbar, nur Ubiquitys eigenes Vollbildfenster — Abbruch
legt den normalen Desktop darunter frei, das automatische Ubiquity läuft
also tatsächlich).
- Fehlende/kaputte WLAN-Zugangsdaten im Preseed — ausgeschlossen (`/opt/
tuxflotte/config/installer.conf` enthielt alle vier erwarteten Zeilen
korrekt; dasselbe Verhalten trat auch mit funktionierendem Ethernet auf).
- Dateiberechtigungen (`installer.conf`, `sudoers.d/90-tuxflotte`) —
ausgeschlossen, per `xorriso -lsdl` an der echten gebauten ISO
gegengeprüft, beide unauffällig (644 bzw. das für sudoers.d korrekte 440
root:root).
- Fehlende Codec-Preseed-Zeile — ausgeschlossen, `ubiquity ubiquity/
use_nonfree boolean true` war bereits korrekt gesetzt (die dokumentierte
Lösung für ein bekanntes Mint-21-Problem, siehe
https://github.com/linuxmint/mint21-beta/issues/34).
**Tatsächliche Ursache:** `automatic-ubiquity` allein bewirkt laut Ubiquity-
Dokumentation nur, dass Seiten übersprungen werden, deren Fragen *alle*
bereits beantwortet ("seen") sind — reicht in der Praxis oft nicht aus, um
wirklich jede Seite zu unterdrücken. Der fehlende Baustein ist die
Debconf-Priorität: ohne `priority=critical` zeigt der Installer weiterhin
Seiten an, auch wenn die zugehörigen Fragen vorbelegt sind. Durch mehrere
unabhängige Quellen bestätigt (siehe Recherche im Chat).
## Entscheidung
`priority=critical` zum Kernel-Append des "Tuxflotte Auto-Install"-
Menüeintrags ergänzt — in `grub/mint-boot-grub.cfg` und `grub/mint-
isolinux-live.cfg`, jeweils nur bei diesem einen Eintrag (die übrigen
Menüpunkte wie "Start Linux Mint"/"OEM install" bleiben bewusst
unverändert interaktiv). Beide Dateien werden sowohl vom echten
Kunden-ISO-Bau (`scripts/build_customer_iso.sh`) als auch vom lokalen/
QEMU-Testpfad (`scripts/build.sh`) verwendet — der Fix deckt also beide
Wege ab, ohne eine zweite Stelle anfassen zu müssen.
## Konsequenzen
Reine Boot-Parameter-Änderung, kein Preseed-/Server-/Agent-Code betroffen.
Noch **nicht live verifiziert** — die nächste ISO, die für "Liebherr" (oder
jede andere Organisation) gebaut wird, enthält den Fix automatisch, da
`build_customer_iso.sh` die Dateien bei jedem Bau frisch kopiert. Die
eigentliche Verifikation folgt beim nächsten Installationsversuch des
Users.
Offen, falls `priority=critical` allein nicht ausreicht: die
Zusammenfassungsseite (`ubiquity ubiquity/summary note`) müsste laut
Recherche ggf. auf einen leeren Wert gesetzt werden, um ebenfalls
übersprungen zu werden — nicht vorab geändert, da nicht durch eigene
Beobachtung bestätigt, nur in der Recherche als möglicher Zusatzpunkt
aufgetaucht.
## Nachtrag (28.08.2026): `priority=critical` war notwendig, aber nicht hinreichend — echte Ursache tiefer
Live-Verifikation in der QEMU-Test-VM (`tuxflotte-mint-autoinstall-test`,
siehe [[project_e2e_flow_dogfooding_2026-08-28]]) hat den in dieser ADR
angenommenen Rahmen korrigiert:
1. **Der "Tuxflotte Auto-Install"-Bootmenüeintrag selbst ist strukturell
kaputt und war nie der richtige Pfad.** Er referenziert
`file=/cdrom/preseed/tuxflotte.seed` — dieses Verzeichnis existiert auf
keiner gebauten ISO (`ls /cdrom/` bestätigt: kein `preseed/`-Ordner).
`build_customer_iso.sh` bäckt bewusst keinen Preseed auf die ISO (siehe
eigener Kommentar dort) — Hostname/Geräte-ID/Partitionierung werden
erst live aufgelöst.
2. **Der tatsächlich funktionierende Mechanismus existiert bereits seit
06.08.2026 (Commit `d6a0146`): `backend_launch()` in
`backends/mint/backend.sh`.** Er baut zur Laufzeit einen echten,
vollständig aufgelösten Preseed, hängt ihn als zusätzlichen
cpio-Layer an `/cdrom/casper/initrd.lz` an und bootet per `kexec` neu
mit `automatic-ubiquity noprompt file=/preseed.cfg …`. Erreicht wird
dieser Pfad aber nur über den **"Start Linux Mint"-Eintrag** (bzw.
jeden Nicht-`automatic-ubiquity`-Eintrag) → `start-kiosk.sh` erkennt
`TUXFLOTTE_AUTO_MODE=true` → `installer.sh` → `40_backend.sh` →
`backend_launch()`. Live bestätigt: `/sbin/init`-Cmdline im zweiten
Boot lautet `automatic-ubiquity noprompt splash`, `ubiquity --automatic
--only` und `debconf-communicate -fnoninteractive` laufen tatsächlich.
Der Nutzer hatte diesen Mechanismus korrekt in Erinnerung, meine
eigene Aussage in einer früheren Session, `backend_launch()` sei ein
Stub, war falsch (nicht ausreichend im Git-Log/in den ADRs
nachgeprüft).
3. **Trotz vollständig aufgelöstem Preseed und korrekt gesetztem
`priority=critical` bleibt Ubiquitys GTK-"Automatic"-Frontend auf
diesem Mint-22.3-Ubiquity-Build an mehreren Seiten hängen und wartet
auf einen manuellen Klick.** Live beobachtet: Multimedia-Codecs-Seite
blieb >60s ohne jede neue Zeile in `/var/log/installer/debug`
(`widget found for ubiquity/use_nonfree` war die letzte Zeile) —
erst ein per QMP `input-send-event` simulierter Mausklick auf
"Continue" brachte Fortschritt. Gleiches Muster danach bei
"Installation type" und beim "Änderungen auf Speichergerät
schreiben?"-Bestätigungsdialog — jede Seite pausiert bis zum Klick,
obwohl die zugrunde liegenden Debconf-Werte laut Preseed bereits
beantwortet sind. Das deckt sich exakt mit dem realen Befund auf der
physischen Hardware (Zeitzone/Codecs/Überschreiben/Benutzeranlage
alle interaktiv) — es lag nie an einem fehlenden Preseed-Wert oder an
`priority=critical`, sondern daran, dass Ubiquitys automatischer
GTK-Modus auf diesem Fork Werte vorbelegt, aber die
Seitennavigation selbst nicht automatisch durchläuft.
**Korrigierter Stand:** `priority=critical` bleibt eine sinnvolle, nicht
schädliche Ergänzung, löst das eigentliche Problem aber nicht. Die
offene Frage — GUI-Auto-Klick-Mechanismus (z. B. `xdotool`, von
`installer.sh` nach dem kexec-Sprung gestartet) vs. Ubiquity im
Backend-/Textmodus ohne GTK-Frontend ansteuern vs. bewusster Verzicht auf
volle Klick-Freiheit — ist mit dem User noch zu klären, siehe
[[project_e2e_flow_dogfooding_2026-08-28]] Fund 8.
## Zweiter Nachtrag (28.08.2026): Ursache endgültig gefunden und behoben — zwei unabhängige Bugs
Der Nutzer erinnerte sich korrekt, dass die kexec-Automatisierung schon
einmal (06.08., Commit `d6a0146`) bis zum Login-Bildschirm durchgelaufen
war. Live-Nachstellung in der QEMU-VM (frische Disk, sauberer Boot über
"Start Linux Mint") deckte zwei komplett unabhängige, bis dahin nie
bemerkte Bugs auf, die zusammen jede automatisierte Installation seit
langem verhindert haben:
**1. `start-kiosk.sh` hatte `/home/liveuser` hartkodiert** (`mkdir -p
/home/liveuser/...` und der Epiphany-Profilpfad). Der tatsächliche
Live-Benutzername auf dieser ISO ist überall `mint` (siehe
`grub/mint-*.cfg`, `username=mint`). `/home/liveuser` existiert nicht
und kann vom Live-User nicht angelegt werden (`/home` ist nicht
schreibbar) — mit `set -euo pipefail` brach das Skript dort sofort mit
"Permission denied" ab, **noch bevor** die `TUXFLOTTE_AUTO_MODE`-Prüfung
überhaupt erreicht wurde. `installer.sh` lief dadurch nie los, `NoDisplay=true`
im Autostart-Eintrag verschluckte den Fehler komplett lautlos — nach
außen sah es wie ein ganz normaler, nicht-automatisierter Live-Desktop
aus. **Fix:** `${HOME}` statt hartkodiertem Pfad.
**2. `backend_launch()`s kexec-Sprung nutzte nur `automatic-ubiquity`.**
Das lässt Casper weiterhin Ubiquitys GTK-Oberfläche starten
(`ubiquity-dm`), die zwar alle Preseed-Werte korrekt vorbelegt, aber pro
Seite trotzdem auf einen Klick wartet — live beobachtet: die
Multimedia-Codecs-Seite blieb ohne Klick über 60 Sekunden unverändert
stehen (kein neuer Eintrag in `/var/log/installer/debug`), ein per QMP
simulierter Mausklick brachte erst Fortschritt, dasselbe Muster
wiederholte sich bei "Installation type" und beim
"Änderungen schreiben?"-Bestätigungsdialog. Das erklärt exakt das auf
echter Hardware beobachtete Verhalten (Zeitzone/Codecs/Überschreiben/
Benutzeranlage alle interaktiv trotz "automatischem" Modus) — nie ein
fehlender Preseed-Wert, sondern eine grundsätzliche Eigenschaft von
Ubiquitys GTK-Automatic-Modus auf diesem Codestand.
**Fix:** Zusätzliches Boot-Keyword `noninteractive` im kexec-Append
(siehe `/usr/share/ubiquity/start-ubiquity-dm`: bei diesem Keyword ruft
Casper direkt `ubiquity noninteractive` auf, statt die GTK-Oberfläche zu
starten). Das ist Ubiquitys eigenes, mitgeliefertes Headless-Frontend
(`ubiquity/frontend/noninteractive.py`) — verarbeitet jede Seite mit
`auto_process=True` rein über Debconf, ohne je ein Fenster zu zeichnen;
`question_dialog()` ist absichtlich nicht implementiert (wirft
`NotImplementedError`) für alles, was sich nicht aus dem Preseed
beantworten lässt — sauberes Scheitern statt stillem Hängenbleiben.
**Live-Verifikation (QEMU, frische 40-GB-Disk):**
- Zweiter Boot nach kexec hat `noninteractive` korrekt im
`/proc/cmdline`.
- `pgrep -a ubiquity` zeigt keinen laufenden GTK-`ubiquity-dm`-Prozess.
- `/var/log/installer/debug` bestätigt den Frontend-Wechsel eindeutig
per Exception-Traceback: `ubiquity.frontend.noninteractive.Wizard
does not implement question_dialog`.
- **Verbleibende, jetzt exakt lokalisierte Lücke:** `ubi-partman.py`
(Zeile 3484) stellt beim Partitionieren eine Frage, die im aktuellen
Preseed noch nicht beantwortet ist — welche genau, ist noch offen
(nächster Schritt). Das ist ein erheblicher Fortschritt gegenüber
vorher: statt eines unklaren, seitenübergreifenden Hängenbleibens gibt
es jetzt einen einzigen, exakt benannten fehlenden Preseed-Wert.
Beide Fixes committed und gepusht (`backends/mint/backend.sh`,
`live-updates/opt/tuxflotte/kiosk/start-kiosk.sh`,
`live-updates/etc/sudoers.d/90-tuxflotte`), siehe
[[project_e2e_flow_dogfooding_2026-08-28]] für den vollständigen
Untersuchungsverlauf.
## Nachtrag (29.08.2026): `noninteractive` verworfen, Umstieg auf
## `automatic-ubiquity` + eigener Autoklicker, mehrere echte Bugs gefunden
Die "verbleibende Lücke" oben (eine unbeantwortete Preseed-Frage in
`ubi-partman.py`) erwies sich als der erste von mehreren Funden in einer
langen, sehr tief gehenden Sitzung. Kurzfassung des Ergebnisses vorab:
**`noninteractive` wurde komplett verworfen**, `automatic-ubiquity`
(echte GTK-Oberfläche) plus ein eigener Autoklicker sind jetzt der
Ansatz. Drei reale, unabhängige Bugs wurden gefunden und behoben. Ein
letzter Schritt (der Klick auf "Jetzt installieren" auf der
Partitionierungs-Übersichtsseite) ist noch nicht zuverlässig
automatisiert - siehe "Offen" am Ende.
### `noninteractive` selbst ist strukturell nicht tragfähig
Iteratives Beantworten einzelner fehlender Preseed-Werte (über 30 Stück,
per `config.dat`/`templates.dat`-Abgleich auf dem laufenden Live-System
diagnostiziert) brachte `ubi-partman.py` immer weiter, endete aber
zuverlässig in einer echten Endlosschleife im `choose_partition`-Zustand
(über 100.000 Debconf-Protokollzeilen in wenigen Sekunden, kein
Fortschritt). Ursache, per Quelltextanalyse gefunden: `choose_partition`
ist die Frage des MANUELLEN Partitionierers; deren Bearbeitung in
`ubi-partman.py` baut einen internen Cache auf und wartet danach auf
einen echten GTK-Button-Klick (`ok_handler()`), der über
`PageNoninteractive` nie kommt - `PageNoninteractive.get_autopartition_choice()`
und verwandte Methoden sind nur Stubs (`pass`/`None`). Das ist keine
fehlende Preseed-Zeile, sondern eine strukturelle Lücke im mitgelieferten
Headless-Frontend selbst.
**Entscheidung:** zurück zu `automatic-ubiquity` (echte GTK-Oberfläche,
`PageGtk` - der von Ubiquity selbst produktiv genutzte, echte
Code-Pfad), dafür ein eigener Autoklicker
(`live-updates/opt/tuxflotte/scripts/autoclicker.sh` + systemd-Service),
ausgelöst durch das eigene Boot-Keyword `tuxflotte-autoclick`.
### Bug 1: `jq` fehlt beim automatisierten Start über den Kiosk (real blockierend)
Der reale Self-Service-Auslöser (`start-kiosk.sh` im Auto-Modus:
`exec sudo installer.sh`, kein Terminal, keine sichtbare Ausgabe) blieb
sofort im allerersten Modul (`10_hardware.sh`) mit "Benötigtes Programm
nicht gefunden: jq" hängen - unsichtbar, nur in `~/.xsession-errors`
sichtbar, nicht in `journalctl` (kein systemd-Unit). Alle bisherigen
Testläufe in dieser Untersuchung sind daran nie gescheitert, weil `jq`
vor jedem manuellen `installer.sh`-Aufruf von Hand nachinstalliert wurde
(bekannte, bisher bewusst zurückgestellte Lücke, siehe
`backend_init()`-Kommentar in `backends/mint/backend.sh`) - der reale
Kiosk-Auslöser hat diesen manuellen Schritt naturgemäß nie bekommen.
`backend_init()` installiert `jq` zwar nach, aber erst in Modul 40
(`40_backend.sh`) - viel zu spät für Modul 10.
**Fix:** neues Modul `scripts/modules/00_preflight.sh` (lief bisher leer),
installiert `jq` als allererstes, vor jedem anderen Modul. Live über den
echten Kiosk-Auslöser (nicht manuell) verifiziert: `installer.sh` lief
danach vollständig automatisch bis zum `kexec`-Sprung durch.
### Bug 2: Ubiquity-GTK-Absturz in `ubi-prepare.py` (echter Ubiquity-Bug)
Mit `automatic-ubiquity` stürzte der Installer auf der "Vorbereiten"-Seite
reproduzierbar ab: `TypeError: Argument 1 does not allow None as a value`,
in `ubi-prepare.py::enable_download_updates()`,
`self.label_download_updates.set_label(self.controller.get_string(template))`.
Das Argument, nicht das Widget, ist None: `get_string('ubiquity/text/label_download_updates_na')`
liefert keinen Wert (fehlende Übersetzung/Vorlage für diesen Zustand),
GTK akzeptiert dafür kein `None`. Preseeden von
`ubiquity/download_updates` half nicht - der auslösende Callback
(`plugin_set_online_state`, an einen NetworkManager-Online-Status-Wechsel
gebunden) feuert unabhängig vom Preseed-Wert.
**Fix:** gezielter Sed-Patch statt Ersatz der kompletten
Drittanbieter-Datei, eingehängt im bestehenden
`initrd-hooks/casper-bottom/99casperboot`-Hook (läuft bei jedem
Casper-Boot, auch nach dem Kexec-Sprung):
```sh
sed -i "s/self\.controller\.get_string(template))/self.controller.get_string(template) or '')/" \
/root/usr/lib/ubiquity/plugins/ubi-prepare.py
```
Live verifiziert: derselbe Ablauf, der vorher exakt an dieser Stelle
abstürzte, lief danach sauber weiter bis zur Partitionierungsseite.
### Bug 3: `partman/choose_partition select finish` erzwingt denselben Endlosschleifen-Zustandsautomaten wie bei `noninteractive` - auch im GTK-Modus
Nach Fix 1+2 lief die Installation weiter, hing aber erneut in derselben
`choose_partition`-Endlosschleife wie beim verworfenen
`noninteractive`-Versuch (>100.000 Debconf-Zeilen in Sekunden) - diesmal
mit `automatic-ubiquity`. Ursache identisch zur strukturellen Analyse
oben: das direkte Preseeden von `partman/choose_partition select finish`
zwingt `ubi-partman.py` in den manuellen Partitionierer-Zustandsautomaten,
unabhängig vom Frontend - der ist für einen echten, interaktiv
aufgebauten Seitenwechsel gedacht, nicht für ein direkt vorausgefülltes
Ergebnis ohne echten Seitenaufbau.
**Fix:** die Zeile `d-i partman/choose_partition select finish` ersatzlos
aus `preseed.tpl` entfernt. `partman-auto/method` + `expert_recipe` +
`choose_recipe` (bereits vorhanden) genügen, um die geführte
Partitionierung auf dem dafür vorgesehenen Weg laufen zu lassen. Live
verifiziert: Endlosschleife verschwunden (Debug-Log-Länge sank von
>100.000 auf ~1.700 Zeilen für denselben Ablaufabschnitt), Installer
zeigt danach korrekt die echte Partitionierungs-Übersichtsseite mit dem
tatsächlich konfigurierten Layout (ESP + 42-GB-ext4-Root gemäß Rezept).
### Nebenfund: GRUB/isolinux-Standardeintrag "von lokaler Festplatte
### booten" ist ABSICHTLICH so, kein Bug
Während der Fehlersuche wirkte ein per QEMU/SeaBIOS beobachtetes
Boot-Hängenbleiben zunächst wie ein Infrastrukturproblem (ausführlich
mit Bisektion über mehrere xorriso-Neubauten eingegrenzt). Tatsächliche
Ursache: das ISO bootet per Voreinstellung "von lokaler Festplatte" (auf
der frischen Test-Disk naturgemäß leer/nicht bootfähig) - das ist eine
bewusste, bereits am 01.08.2026 getroffene Sicherheitsentscheidung
(siehe ADR-0009, Abschnitt "Bootmenü als eigentlicher Sicherheits-Gate"):
die destruktive Installation soll nur bei aktiver Menüauswahl starten,
nie automatisch beim bloßen Verstreichen des Countdowns. Kein Fix nötig
- für Tests (und für Kunden) muss der Eintrag "Start Linux Mint" (bzw.
in Produktion später ein reparierter "Tuxflotte Auto-Install"-Eintrag)
aktiv ausgewählt werden.
### Offen: automatisierter Klick auf "Jetzt installieren" noch nicht
### zuverlässig
Nach Fix 3 erreicht der Installer real die Partitionierungs-Übersichts-
seite korrekt und wartet dort auf einen Klick auf "Jetzt installieren".
`autoclicker.sh` (Enter-Taste an das Hauptfenster) hat auf dieser
speziellen Seite keinen Effekt - Enter aktiviert dort einen
Ausklapp-Pfeil eines Status-Panels ("Konfiguration der Installation wird
überprüft ..."), nicht den Installieren-Button. Mausklick-Versuche per
`xdotool`/QMP auf berechnete Fensterkoordinaten scheiterten an
unzuverlässiger Fenstererkennung (mehrere überlappende X11-Fenster
ähnlicher Größe durch Metacity-Fensterdekoration, "größtes sichtbares
Fenster"-Heuristik traf wiederholt das falsche Fenster) - bewusst NICHT
in den produktiven Autoklicker übernommen, um kein Risiko fehlgeleiteter
Klicks (z. B. versehentlich eine "Formatieren?"-Checkbox) einzugehen.
Zusätzlich wurde dabei ein eigener, unabhängiger Bug in der
Fenstersuche gefunden und behoben: `autoclicker.sh` suchte bisher nach
einem Fenster namens "ubiquity" - der tatsächliche Fenstertitel ("Installation
(as superuser)") enthält dieses Wort nie, die Suche fand also nie
etwas. Das ist jetzt korrigiert (Suche nach jedem betitelten sichtbaren
Fenster statt nach dem Namen "ubiquity"), der eigentliche Klick-Schritt
bleibt aber offen.
**Nächster Schritt, nicht mehr in dieser Sitzung verfolgt:** vermutlich
robusteste Lösung wäre AT-SPI (Accessibility-API) statt Pixel-/Fenster-
Heuristik - findet Buttons über ihre Rolle ("Push Button") und ihren
(übersetzten) Namen, unabhängig von X11-Fensterüberlappung. Nicht
recherchiert, da Zeitrahmen dieser Sitzung erschöpft.