platform-docs/adr/0005-kiosk-ui-chromium.md
Thomas Stallinger 2f1300940c docs: record kiosk-UI journey, WLAN autoprovisioning model, and TUXFLOTTE ISO label
Kiosk UI: Chromium was evaluated as an Epiphany alternative (ADR-0005)
after ADR-0004's application-mode approach turned out unusable
end-to-end, then abandoned after four distinct real-boot failures in a
row (ADR-0006) in favor of a hardened plain --profile Epiphany launch.
ADR-0004 amended with the actual fix history (profile directory
creation, application-mode's undocumented web-app requirement,
--private-instance/--profile conflict on the target's Epiphany 50.1
vs. the 43.1 used for local testing). ADR-0007 resolves ADR-0004's
open question: the kiosk web UI and installer.sh never talk directly,
only via the provisioning server.

WLAN autoprovisioning: customer profile gets an "Autoprovisionierung"
flag plus WLAN credentials, driving self-service generation of a
personalized ISO with the credentials baked in as a NetworkManager
profile — works from device one, no persistent on-stick state needed.
Personalizing the build this way also motivated giving the ISO its
own volume label (TUXFLOTTE) instead of the source Fedora label.

Also folds in the EROFS root-cause writeup and the Ubuntu-live-medium
alternative noted for a future ISO rework, and brings
roadmap/installer-roadmap.md's checkboxes in line with actual status.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 12:16:25 +02:00

8.0 KiB

ADR-0005: Chromium statt Epiphany für den Kiosk-Modus

Status: Verworfen durch ADR-0006 (21.07.2026) — vier reale Boot-Fehlschläge in Folge, siehe dort. Bleibt als historischer Datensatz stehen: die hier dokumentierten Techniken (Isolation unter /opt, Loader-Relokation, SquashFS-Verpackung) funktionierten einzeln nachweislich, nur in Summe erwies sich der Ansatz als zu fragil. Datum: 20.07.2026

Kontext

ADR-0004 wählte Epiphany im Application-Mode (--application-mode) für die Kiosk-Oberfläche, unter anderem mit der Begründung, dieser Modus liefere "ein chromeloses Fenster ohne Adressleiste, Tabs oder Menüs".

Der tatsächliche Test auf dem Live-System widerlegt das für den hier vorgesehenen Einsatzzweck: Epiphany im Application-Mode benötigt explizite Session-/Profildaten (den --profile=<Verzeichnis>-Aufbau, wie ihn die bisherige tuxflotte-installer.desktop verwendet hat) und liefert trotzdem ein Fenster mit sichtbarer Adresszeile und Fenstermenü — keinen echten Kiosk-Modus. Für eine gebrandete, eingabefreie Provisionierungsoberfläche ist das ungeeignet.

Entscheidung

Statt Epiphany wird Chromium im echten Kiosk-Modus (--kiosk) verwendet.

Chromiums --kiosk-Flag liefert ein vollständig chromeloses Fenster ohne Adressleiste und Menü, ohne dass vorab ein Profil oder eine Session angelegt werden muss — das Flag reicht für sich allein.

Chromium ist auf dem verwendeten Fedora-Cinnamon-Live-Image nicht vorhanden (siehe ADR-0004) und muss daher zur Build-Zeit ins Live-Payload aufgenommen werden.

Ursprünglich war geplant, das dadurch wachsende ISO im Gegenzug durch Entfernen großer, nicht benötigter Pakete (z.B. LibreOffice) auszugleichen. Das ist inzwischen verworfen (21.07.2026): Das würde eine Änderung an /LiveOS/squashfs.img selbst erfordern, und genau das ist der Bereich, der laut dem in 13-live-provisioning-boot.md dokumentierten erofs-utils-Bug nachweislich destruktiv fehlschlägt. Stattdessen wird die durch Chromium entstehende Größe bewusst in Kauf genommen — siehe Konsequenzen.

Konsequenzen

ADR-0004 wird in diesem einen Punkt korrigiert: der Browser für den Kiosk ist Chromium statt Epiphany. Die übrigen Entscheidungen aus ADR-0004 — Web-App statt native GTK-Anwendung, fachliche Logik bleibt in den bestehenden Bash-Modulen, die Web-Oberfläche ist ausschließlich Präsentationsschicht — bleiben unverändert gültig.

Umgesetzt (21.07.2026), in zwei Anläufen:

Erster Anlauf (verworfen): dnf --installroot in ein Wegwerf-Verzeichnis, danach usr/ und etc/chromium/ ins reale updates/-Payload kopiert (also in das echte /usr des Live-Systems gemergt). Das vermied zwar das /etc/passwd-Problem des allerersten Versuchs, übersah aber, dass usr/ selbst alle ~350 transitiven Basis-Pakete enthält — systemd, bash, glibc, coreutils, dbus, pam, util-linux. Der reale Testboot in Proxmox endete in einem Kernel Panic ("Attempted to kill init! exitcode=0x00007f00", dekodiert als Exit-Status 127) — die frisch heruntergeladenen Versionen dieser Kerndateien haben die des Live-Systems überschrieben und PID 1 zerschossen.

Zweiter Anlauf (aktuell): Vollständige Isolation statt Blockliste. Chromium landet nicht mehr in /usr, sondern komplett unter /opt/tuxflotte/chromium/usr — ein Pfad, der mit nichts auf dem Live-System kollidieren kann. Gestartet wird über launch.sh, das den mitgelieferten eigenen Loader (ld-linux-x86-64.so.2 --library-path ...) explizit aufruft, statt sich auf den Loader des Live-Systems zu verlassen (ein einfacher exec mit nur LD_LIBRARY_PATH gesetzt schlägt mit undefined symbol ... GLIBC_PRIVATE fehl, sobald Loader und libc aus unterschiedlichen Builds stammen — lokal reproduziert und verifiziert). Der Such-Suchpfad für Bibliotheken wird beim Start dynamisch durch Scannen aller Unterverzeichnisse unter lib64/lib ermittelt (nicht hartkodiert), weil Chromium auch private Paket-Unterverzeichnisse braucht (gefunden: usr/lib64/samba/) — lokal gegen die echte installierte Chromium-Binary getestet (chromium-browser --version liefert korrekt Chromium 146.0.7680.164).

Dritter Anlauf (aktuell): Auslieferung als SquashFS-Image statt loser Dateien. Der zweite Anlauf löste die Sicherheits-/Korrektheitsprobleme, aber nicht die Performance: Der Dracut-Hook kopiert /updates vor dem Pivot Datei für Datei, und ~350 Pakete bedeuten hunderttausende kleine Dateien — auf echter Hardware dauerte allein dieser Kopiervorgang mehrere Minuten, obwohl die Gesamtgröße (~1,2 GB) dafür nicht groß genug wäre (dateianzahl-, nicht größengebunden). Zusätzlich verschärfte das erneut das RAM-Thema (bei 2 GB VM-RAM ~80% Auslastung während des Kopierens). Fix: usr/ wird zur Build-Zeit mit mksquashfs (Standard-Tool, mit dem erofs-utils-Bug nicht verwandt) zu einer einzelnen komprimierten Datei gepackt (lokal getestet: 434 MB statt 1,2 GB, Setuid-Bit auf chrome-sandbox bleibt erhalten). launch.sh mountet diese Datei beim ersten Start per Loop-Mount nach /opt/tuxflotte/chromium/usr (nahezu verzögerungsfrei, keine RAM-Duplizierung, Daten bleiben komprimiert auf dem Medium und werden bei Bedarf eingelesen) — das räumt das RAM-Thema strukturell aus, nicht nur durch mehr RAM in der Test-VM.

Vierter Anlauf (aktuell): /proc/self/exe-Fix für die ICU-Ressourcenauflösung. Der reale Testboot nach Anlauf 3 startete zwar (schnell, dank SquashFS), aber Chromium erschien nicht (ps aux | grep chromium fand nichts). launch.sh manuell ausgeführt lieferte Invalid file descriptor to ICU data received. Per strace lokal reproduziert und ursächlich geklärt: Chromium bestimmt sein eigenes Ressourcenverzeichnis über dirname(readlink(/proc/self/exe)). Weil launch.sh den Loader aus usr/lib64/ld-linux-x86-64.so.2 direkt aufruft, zeigt /proc/self/exe auf den Loader selbst (in usr/lib64/), nicht auf chromium-browser (eine Ebene tiefer in usr/lib64/chromium-browser/) — Chromium sucht icudtl.dat deshalb am falschen Ort. Fix: eine Kopie des Loaders wird zur Build-Zeit direkt neben chromium-browser gelegt (usr/lib64/chromium-browser/ld-linux-x86-64.so.2) und von dort aus gestartet — /proc/self/exe zeigt dann korrekt ins richtige Verzeichnis. Lokal verifiziert: der ICU-Fehler verschwindet vollständig.

Beim Weitertesten (lokal, ohne echten Fedora-Live-Boot) trat danach ein zweiter Fehler auf: chrome_crashpad_handler (Absturzbericht-Hilfsprozess, von Chromium selbst per execve() mit eigenem, nicht von uns kontrolliertem Pfad gestartet) scheiterte an fehlenden GLIBC_2.38/GLIBC_2.39-Symbolen im System-Loader. Sehr wahrscheinlich ein Artefakt der lokalen Testumgebung (Debian Bookworm, glibc von 2022) und kein Problem auf dem eigentlichen Zielsystem (Fedora Cinnamon Live 44, deutlich näher an der dnf-heruntergeladenen Version) — aber ohne echten Boot nicht abschließend auszuschließen. Als nächster Schritt bei erneutem Scheitern: chrome_crashpad_handler per denselben Loader-Trick abfangen, oder Absturzberichterstattung ganz deaktivieren.

Details siehe 13-live-provisioning-boot.md, Abschnitt „Autostart von installer.sh". Akzeptierter Nebeneffekt unverändert: dnf löst den vollen Abhängigkeitsbaum auf (351 Pakete), nicht nur Chromium plus tatsächlich fehlende Bibliotheken — eine gezielte Verschlankung ist mangels Lesezugriff auf die squashfs.img nicht verifizierbar.

Neue Build-Voraussetzung: build.sh braucht jetzt Root-Rechte (dnf --installroot verlangt das) sowie Internetzugriff zu Fedora-Repos. Bewusster Sicherheits-Trade-off: chrome-sandbox (Setuid-Root-Helfer) wird zwar unverändert mitkopiert, aber ob er von dem neuen, isolierten Pfad aus funktioniert, ist ungeprüft — launch.sh startet vorerst mit --no-sandbox, vertretbar für eine Wegwerf-Live-Session ohne sensible Daten, aber keine Nebensächlichkeit. Noch nicht per echtem grafischem Live-Boot verifiziert.

Die in ADR-0004 offen gelassene Frage, wie die Web-Oberfläche mit den bestehenden Bash-Modulen kommuniziert (Zustand lesen, Aktionen auslösen), bleibt unverändert offen und ist von der Browserwahl unabhängig.