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

19 KiB

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=trueinstaller.sh40_backend.shbackend_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):

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.