100 Commits
Author SHA1 Message Date
adminandClaude Opus 5.5 fbfc394747 Fingerprint-Datei nur für root, Bootstrap mit Fingerprint als Nachweis
Credentials und Fingerprint mit umask 077 angelegt (kein kurzes
Lesefenster vor dem chmod). platform-docs roadmap/agent-zugang-haertung.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 21:17:28 +01:00
adminandClaude Opus 5.5 eaa6bce003 Installer: Setup Mode und Drittanbieter-CA erfassen, Abbruch wenn Vorlage Secure Boot verlangt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 18:47:06 +01:00
adminandClaude Opus 5.5 3f841f0801 Installer: GRUB_DISTRIBUTOR=Tuxflotte vor grub-install, Firmware-Eintrag heißt Tuxflotte
Damit landen spätere shim-/GRUB-Updates in EFI/tuxflotte, das die
Firmware startet (vorher EFI/ubuntu bzw. EFI/debian).
roadmap/secure-boot-verschluesselung.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 18:05:43 +01:00
adminandClaude Opus 5.5 f5f14888c3 postinstall: Mint-Systembericht (mintreport) im Autostart abschalten
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 09:25:02 +01:00
adminandClaude Opus 5.5 26bc65f6ff postinstall: Agent nach dem Bootstrap von anode laden (ADR-0046 Schritt 3), Gitea als Rückfall
Fassung "freigegeben" der Ausrollstufe, Secret per curl --header @datei
(0600, per trap gelöscht) statt auf der Kommandozeile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 09:52:50 +02:00
adminandClaude Opus 5.5 4929a37175 Fedora-Installer-Versuche archivieren (Tag archiv/fedora-versuche) und aus main entfernen
Nicht mehr genutzt seit dem eigenen Boot-Medium (ADR-0025). Die Testdateien
enthielten u. a. ein WLAN-Passwort im Klartext; es bleibt in der Historie,
die Abhilfe ist ein Passwortwechsel, nicht dieses Entfernen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 17:58:42 +02:00
adminandClaude Opus 5.5 cee4fe58ad Golden Image und Installer: xattrs inkl. security.* (Datei-Capabilities)
GNU tar uebernimmt beim Auspacken ohne --xattrs-include nur user.*;
security.capability (cap_net_raw an ping u.a.) ging beim Staging-Auspacken
in package_golden_image.sh verloren, image_deploy.sh entpackte zudem ganz
ohne --xattrs. Befund Liebherr-83 15.10.2026 (ping fuer Benutzer kaputt).
Rundlauf mit setcap/tar im User-Namespace geprueft. Wirkt erst mit neu
gepackten Golden Images und neuem Boot-Medium; bestehende Geraete repariert
ansible-content grundsystem.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 14:05:40 +02:00
adminandClaude Opus 5.5 e7edef06b6 Org-WLAN vom Medium immer systemweit ins Zielsystem schreiben
Bisher kam das Org-WLAN (TUXFLOTTE_WIFI_SSID/-PSK) nur aufs Geraet, wenn
ueber genau dieses WLAN installiert wurde - export_connection_profile()
uebernimmt nur das aktive Profil. Per Kabel installierte Geraete hatten
kein WLAN (Liebherr-83, 14.10.2026). Jetzt immer
tuxflotte-installations-wlan.nmconnection per nmcli --offline, ohne
permissions, PSK in der Datei; Doppel mit dem exportierten Profil wird
entfernt. Eigener Dateiname, damit der absent-Zweig der Rolle org-wlan
ihn nicht loescht.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 18:30:30 +02:00
adminandClaude Opus 5.5 decc7404a8 image_deploy: resolv.conf des Golden Image nach der chroot-Phase wiederherstellen
Der Symlink wurde fuer die chroot-Phase durch eine Kopie der resolv.conf
des Installationsnetzes ersetzt und nie zurueckgesetzt. Installierte
Geraete verloren dadurch nach einem Ortswechsel die Namensaufloesung
(Liebherr-83, 14.10.2026: Agent "Name or service not known"). Jetzt
Symlink-Ziel bzw. Datei sichern und in image_deploy_unbind_mounts()
zurueckspielen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 18:01:17 +02:00
adminandClaude Opus 5.5 5857a6b939 image_deploy: 127.0.1.1-Zeile des Golden Image ersetzen statt eine zweite anzuhängen
Im installierten System stand neben dem vergebenen Namen noch der der
Referenz-VM in /etc/hosts (Befund 13.10.2026, VM 107).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:16:15 +02:00
adminandClaude Opus 5.5 703d8c6c9f build_customer_iso: Kundendaten als eigene Squashfs-Schicht, ohne root
Statt filesystem.squashfs als root zu entpacken und neu zu packen, kommt
installer.conf in eine kleine Schicht /live/tuxflotte-kunde.squashfs
(live-boot legt alle /live/*.squashfs alphabetisch uebereinander).
mksquashfs -all-root braucht kein root; Bau in Sekunden statt ~1 Minute,
kein GB-Arbeitsplatz mehr. installer.conf (WLAN-PSK) im Live-System jetzt
600 statt 644. Lokal-Test-Pruefung ueber die Dateiliste. Behebt nebenbei
einen set -e-Abbruch, wenn weder Diagnose-Hash noch WLAN gesetzt waren.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 16:19:42 +02:00
adminandClaude Opus 5.5 12f4de3bf1 Geraete-Fingerabdruck: feste Hardware-MAC (permaddr) statt aktueller - WLAN-MAC-Randomisierung im Live-System erzeugte neue Geraeteeintraege
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 13:54:09 +02:00
adminandClaude Opus 5.5 f804db8a33 isolinux: langen Vorlagennamen sauber kuerzen
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 13:21:15 +02:00
adminandClaude Opus 5.5 437bdc79df Abbruch sauber (kein ERR-Trap im Auto-Modus), statt root-Shell Neustart per ENTER (Produktiv), isolinux-Menue deutsch (VM-Tests T3/T4)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 13:13:45 +02:00
adminandClaude Opus 5.5 e494b5835b Postinstall: gnome-initial-setup global maskieren + Erledigt-Marker in /etc/skel (Ubuntu, VM-Test T2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 12:58:36 +02:00
adminandClaude Opus 5.5 29adae9591 Installer-Konsole: Info-/Warnzeilen im Auto-Modus nur ins Log, GRUB-Fusszeile deutsch, Abschlusskasten wie frueher Hinweis (VM-Test T1)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 12:45:01 +02:00
adminandClaude Opus 5.5 580a075224 Hybrid-Grafik: nouveau abschalten + NVIDIA-Energiesparen bei der Installation (B11)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 12:23:11 +02:00
adminandClaude Opus 5.5 38ca3ab5ab Medium-Endstand: Publish-Schritt mit Versionskennung, Vorabpruefung, USB-Ausschluss bei der Zielplatte, Offline-Medium, Neuinstallation ohne Rueckfrage, toram-Reserve, Platzpruefung
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 12:17:31 +02:00
adminandClaude Opus 5.5 030401f800 build_customer_iso.sh: Arbeitsverzeichnis auf anodes Datenplatte (B5)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 12:06:46 +02:00
adminandClaude Opus 5.5 b6151172b8 Fruehzeitiger Hinweis: Installationsmedium kann direkt nach dem Start zum naechsten Geraet (toram)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 11:23:51 +02:00
adminandClaude Opus 5.5 b118ede089 Serielle Konsole nur in Testbuilds, Abzieh-Hinweis als Kasten, Willkommensfenster deaktiviert (Kunden-ISO-Test R11/R12/R15)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 10:24:42 +02:00
adminandClaude Opus 5.5 f073db76c1 Installationsablauf: GRUB-Logo/-Menue, toram-Fortschritt, sichtbare Teilschritte, Abzieh-Hinweis, Erststart-Anzeige (Kunden-ISO-Test R1-R6, R10)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 09:42:52 +02:00
adminandClaude Opus 5.5 995895fbc1 Diagnosezugang pro Organisation + Geheimnisse per stdin an build_customer_iso.sh (ADR-0035)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 14:18:26 +02:00
adminandClaude Sonnet 5 9296e54407 Fix: Ethernet-Interface-Namensfix wurde faelschlich auch fuer WLAN angewendet
Bare-Metal-Fund (21.09.2026) - das war die eigentliche, finale Ursache der
WLAN-Persistenz-Bugkette von heute: image_deploy_fix_network_interface_name()
war urspruenglich nur fuer den ens18(Referenz-VM)-vs-echte-Hardware-Namen-
Mismatch gedacht, prüfte aber nicht, ob das tatsaechliche Provisionierungs-
interface ueberhaupt Ethernet war. Bei einer WLAN-Provisionierung ersetzte
die Funktion den hartcodierten Ethernet-Namen in /etc/network/interfaces
durch den WLAN-Interface-Namen (z.B. wlp9s0) - mit zwei Folgen: (1)
ifupdowns simples "iface X inet dhcp" kann WPA/WPA2 gar nicht aushandeln,
(2) NetworkManagers ifupdown-Plugin (managed=false) markierte das WLAN-
Interface dadurch dauerhaft als "unmanaged", wodurch das eigentlich korrekt
exportierte/kopierte WLAN-Profil (05_network.sh) nie zum Einsatz kam.

Live auf betroffener Bare-Metal-Hardware verifiziert: Entfernen der
fehlerhaften ifupdown-Zeile + NetworkManager-Neustart aktivierte das
gespeicherte WLAN-Profil sofort, Agent-Checkin lief direkt danach durch.

Jetzt per TUXFLOTTE_NETWORK_TYPE-Pruefung auf Ethernet beschraenkt - WLAN
wird bereits vollstaendig ueber das NetworkManager-Keyfile-Profil abgedeckt,
braucht diesen Fix nicht.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
2026-09-21 19:25:14 +02:00
adminandClaude Sonnet 5 4cffaf4753 Temporaerer root-SSH-Zugang im installierten System fuer Lokal-Test-Deployments
Bare-Metal-WLAN-Debugging (21.09.2026): das installierte Zielsystem hat nach
ADR-0026 kein Benutzerkonto und kein bekanntes Passwort - Fehlersuche direkt
nach dem ersten Boot war deshalb nur per Offline-Mount der Zielplatte
moeglich. Analog zum --dev-Mechanismus des Boot-Mediums jetzt root/12345 per
SSH erreichbar, aber NUR wenn ANODE_URL auf einen Lokal-Test-Build hindeutet
(http://, nicht https:// wie im Produktivpfad) - der Produktivpfad bleibt
unveraendert ohne jeden bekannten Zugang.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
2026-09-21 19:00:03 +02:00
adminandClaude Sonnet 5 c158961388 Fix (2. Anlauf): WLAN-Profil-Export - FILENAME ist eine Listen-, keine Detail-Spalte
Der erste Fix (cb2cc3b, "GENERAL.FILENAME") war ebenfalls falsch - empirisch
mit echtem nmcli auf VM 107 geprueft: nmcli lehnt "GENERAL.FILENAME" fuer
die Detailansicht ("connection show <name>") explizit als ungueltiges Feld
ab, genau wie zuvor "connection.filename". FILENAME existiert nur als
Spalte der LISTEN-Ansicht ("nmcli connection show" ohne Namensargument,
alle Verbindungen) - jetzt korrekt darueber gefiltert statt ein
nicht-existentes Detail-Feld abzufragen.

Empirisch verifiziert (VM 107, echtes nmcli):
- Testweise angelegtes WLAN-Profil: FILENAME zeigt korrekt auf
  /etc/NetworkManager/system-connections/test-wifi.nmconnection
- Echte aktive Ethernet-Verbindung: FILENAME zeigt auf
  /run/NetworkManager/system-connections/... (nicht persistent, harmlos -
  bestaetigt gleichzeitig, dass die bisherige Warnung fuer
  automatisch erzeugte Ethernet-Profile OHNE explizites Speichern korrekt
  und erwartet ist, nur WLAN-Profile muessen tatsaechlich exportiert werden)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
2026-09-21 17:53:46 +02:00
adminandClaude Sonnet 5 cb2cc3b221 Fix: WLAN-Persistenz war seit Einfuehrung nie funktionsfaehig (falsches nmcli-Feld)
Bare-Metal-Fund (21.09.2026, Mint+Ubuntu): frisch installierte Geraete
hatten nach dem ersten Reboot keine WLAN-Verbindung mehr - Agent konnte sich
dadurch nie melden (bestaetigt: agent/bootstrap lief, aber niemals ein
agent/checkin danach). Ursache: export_connection_profile() fragte
"connection.filename" ab - das ist kein gueltiges nmcli-Feld (gehoert zur
connection.*-Eigenschaftsgruppe, die den Dateipfad nicht kennt), lieferte
deshalb IMMER eine leere Zeile. Der tatsaechliche Pfad steht im
laufzeitbezogenen GENERAL-Abschnitt (GENERAL.FILENAME). Die "WARNUNG:
NetworkManager-Profil konnte nicht exportiert werden."-Zeile erschien
seitdem (01.09.2026) bei JEDEM Testlauf, wurde aber bisher als harmlos
abgetan statt als eigentliche Ursache erkannt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
2026-09-21 17:09:39 +02:00
adminandClaude Sonnet 5 7922a77a3b Regressionsfix: serielle Installer-Konsole faelschlich an --local-test-anode-url gekoppelt
Bare-Metal-Fund (21.09.2026, unmittelbar nach dem letzten Fix): die
ttyS0-Umleitung aus Commit 23edd3a war an --local-test-anode-url gebunden -
aber dieses Flag steht sowohl fuer die serielle Proxmox-Testumgebung (VM 107,
kein Bildschirm) als auch fuer Bare-Metal-Tests mit echtem Monitor. Auf
echter Hardware blieb dadurch tty1 von tuxflotte-installer.service
unbeeinflusst (Conflicts zeigte jetzt auf serial-getty@ttyS0 statt
getty@tty1) - der Anwender sah nur noch live-configs Standard-Autologin-
Loop auf dem Bildschirm, waehrend der eigentliche Installer unbeobachtet
auf ttyS0 lief. Neues eigenstaendiges Flag --serial-installer-console
entkoppelt das sauber - NUR fuer die VM-107-Testumgebung gedacht, Bare-Metal-
Tests bleiben wie vorgesehen auf tty1.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
2026-09-21 13:53:35 +02:00
adminandClaude Sonnet 5 4252db20fd Lokal-Test-Builds: SSH+root/12345 automatisch aktivieren (kein separates --dev noetig)
Bare-Metal-Runde 21.09.2026: haendisches ssh.service-Unmasking+root-Passwort-
Setzen live an der Konsole hat die Fehlersuche direkt beschleunigt (SSH statt
serieller/lokaler Konsole mit US-Layout auf physischer Hardware). Jetzt fest
im Dev-Build-Hook: root/12345 zusaetzlich zu tuxflotte/test123, PermitRootLogin
aktiviert. --local-test-anode-url impliziert automatisch --dev, da diese
Builds per Definition reine Testartefakte sind (build_customer_iso.sh bricht
ohnehin ab, falls lokale Test-Spuren im Quell-Image gefunden werden) - kein
Risiko, dass das in eine echte Kunden-ISO durchsickert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
2026-09-21 13:32:03 +02:00
adminandClaude Sonnet 5 9a40236df3 Fix: Ethernet-Kabel wird ignoriert, wenn Link-Verhandlung noch laeuft
Bare-Metal-Fund (21.09.2026): get_ethernet_devices() filtert Interfaces mit
NM-Status "unavailable" heraus - direkt nach dem Boot kann das noch bis zu
ein paar Sekunden dauern, bis die Link-Verhandlung mit Switch/Router
abgeschlossen ist. Da establish_network_connection() sofort erfolgreich
zurueckkehrt, sobald der Anwender WLAN-Zugangsdaten eingibt, bekam Ethernet
nie eine zweite Chance. try_ethernet() bekommt jetzt ein kurzes,
eigenstaendiges Nachfass-Fenster (4 Versuche a 2s) bevor auf die
interaktive WLAN-Abfrage zurueckgefallen wird.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
2026-09-21 13:21:40 +02:00
adminandClaude Sonnet 5 16a0494f44 Fix: verwirrende Doppel-Fehlermeldung + unklarer WLAN-PSK-Prompt
Bare-Metal-Test (21.09.2026, Debian) fand zwei echte UX-Bugs:

- run_module() im normalen (nicht-Auto-)Modus rief das Modul nackt auf
  ("$module" ohne ||-Absicherung) - ein sauberer, bereits klar gemeldeter
  fatal()-Fehlschlag im Modul loeste zusaetzlich den generischen ERR-Trap
  aus errors.sh aus ("Unerwarteter Fehler in Zeile 199"), obwohl der
  eigentliche Grund eine Zeile darueber schon klar stand. Jetzt wird der
  Exit-Code abgefangen und sauber weitergereicht, kein zweiter,
  verwirrender Fehler mehr.
- connect_wifi() nutzte "nmcli --ask", dessen generischer "Password:"-
  Prompt keinen Bezug zur gewaehlten SSID hatte - fuer den Anwender nicht
  eindeutig, was genau erwartet wird. Eigener Prompt mit SSID-Bezug und
  Doppelpunkt, Passwort direkt per "password" statt "--ask" uebergeben.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
2026-09-21 13:00:10 +02:00
adminandClaude Sonnet 5 23edd3a6db Serielle Konsole fuer Proxmox-Testumgebung: GRUB dauerhaft, Installer-Phase nur im Lokal-Test-Build
Golden Image bekommt permanent GRUB_TERMINAL=serial (harmlos ohne
seriellen Port, Voraussetzung fuer qm-terminal-Verifikation ohne
Passwort-Reset-Umweg). Die tty1-gebundene Installer-Phase wird nur bei
--local-test-anode-url auf ttyS0 umgebogen, ueber einen Trap immer wieder
auf den Produktivstand zurueckgesetzt, damit ein Produktiv-Build nie
versehentlich die Testvariante ausliefert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
2026-09-21 11:55:44 +02:00
adminandClaude Sonnet 5 7e21f45fb7 Fix: fehlendes flatpak im Golden Image blockierte mehrere App-Merkmale
Live gefunden (19.09.2026, direkt im Anschluss an den git-Fix, gleicher
QEMU-Testlauf): "Executable 'flatpak' was not found on the system" -
sechs Rollen (brave/onlyoffice/libreoffice/gdevelop/turbowarp/auto-update)
nutzen das community.general.flatpak-Modul, ohne selbst sicherzustellen,
dass flatpak ueberhaupt installiert ist. Auf Mint/Ubuntu bisher
unauffaellig (dort vermutlich schon im Golden Image vorhanden), auf dem
neuen schlanken Debian-Backend fehlte es komplett - ein fataler
Task-Fehler blockierte wieder den gesamten restlichen ansible-pull-Lauf.

flatpak zur bestehenden jq/curl/python3/ansible/git-Absicherung in
backend_postinstall() ergaenzt (alle drei Backends).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
2026-09-19 19:28:45 +02:00
adminandClaude Sonnet 5 891d5d16c3 Fix: fehlendes git im Golden Image blockierte jeden ansible-pull-Lauf
Live gefunden (19.09.2026, direkt nach dem Netzwerk-Interface-Fix - erster
Testlauf mit tatsaechlich erfolgreichem Agent-Checkin): "Failed to find
required executable 'git' in paths: ...". Netzwerk und Checkin liefen
korrekt, aber OHNE git konnte ansible-pull nie ein einziges Merkmal
anwenden - das ansible-Debian-Paket zieht git nicht zwingend als
Abhaengigkeit, und package_golden_image.sh's Bereinigung hatte es aus dem
Golden Image entfernt.

git zur bestehenden jq/curl/python3/ansible-Nachinstallations-Pruefung in
backend_postinstall() ergaenzt (alle drei Backends).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
2026-09-19 18:48:48 +02:00
adminandClaude Sonnet 5 c2c553b94e Fix: hartcodierten Netzwerk-Interface-Namen im Golden Image beim Deployment korrigieren
Live gefunden (19.09.2026, erster QEMU-E2E-Testlauf, Debian): Der Agent
checkte nach dem Reboot nie ein, weil das Golden Image ein statisches
/etc/network/interfaces (ifupdown) mit dem Interface-Namen der Proxmox-
Referenz-VM ("ens18") mitbringt - auf der QEMU-Testhardware heisst das
Interface "ens3", auf echten Rechnern waere es z.B. "enp2s0"/"eno1". Das
Zielsystem bekam dadurch nie eine IP-Adresse.

image_deploy_fix_network_interface_name() ersetzt den hartcodierten Namen
durch den tatsaechlich erkannten (aus /run/tuxflotte/network/state.env,
von 05_network.sh bereits zuverlaessig ermittelt - Live-Medium und
Zielsystem laufen zwangslaeufig auf derselben Hardware, der Name ist
deterministisch identisch, kein Raten noetig). Bewusst konservativ: nur
wenn genau ein Ethernet-Interface-Name im Golden Image gefunden wird,
sonst wird nichts angefasst. Kein Fatal-Fehler, falls die Datei fehlt
(NetworkManager-basierte Golden Images sind unbetroffen).

Reales Risiko auch fuer Bare-Metal-Rollouts (nicht nur QEMU-Tests) -
betrifft potenziell jede Zielhardware, deren Interface-Name von der
Proxmox-Referenz-VM abweicht.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
2026-09-19 17:31:28 +02:00
adminandClaude Sonnet 5 44f089a95b build_boot_medium.sh: scripts/backends automatisch ins Boot-Medium synchronisieren
Behebt die Ursache des vorherigen Fixes (25f6987) strukturell: statt zwei
Baumkopien manuell in Sync zu halten, kopiert der Build sie jetzt selbst
per rsync (mit Ausschlussliste fuer die bewusst host-seitigen Build-
Skripte und das nicht ausgelieferte Fedora-Backend). Jede kuenftige
Aenderung an scripts/lib/backends landet dadurch automatisch im naechsten
Boot-Medium-Build, die Drift-Klasse aus 25f6987 kann strukturell nicht
mehr auftreten.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
2026-09-19 16:30:21 +02:00
adminandClaude Sonnet 5 25f6987948 Fix: image_deploy.sh Boot-Medium-Kopie nicht mit Phase-3-Aenderungen synchronisiert
Live in QEMU gefunden (19.09.2026, erster Testlauf der neuen Lokal-Test-ISO
mit custom-Partitionierung): "image_deploy_partition_custom: command not
found" - die Custom-Partitionierungsfunktionen (Commit 020aa66) wurden nur
in scripts/lib/image_deploy.sh ergaenzt, die zweite, tatsaechlich ins
Boot-Medium gepackte Kopie unter boot-medium/config/includes.chroot/...
blieb auf dem Phase-1/2-Stand stehen. Genau die Sync-Falle, die im Roadmap-
Dokument als Risiko benannt wurde.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
2026-09-19 16:29:20 +02:00
adminandClaude Sonnet 5 020aa66bfa Custom-Partitionierungsschema (extra_partitions) im Golden-Image-Deployment
image_deploy_partition_custom()/_format_custom()/_mount_custom() sowie eine
um extra_partitions erweiterte image_deploy_write_fstab() ergaenzen das
bisherige starre ESP+Root-Layout um eine variable Anzahl zusaetzlicher
Partitionen (Mountpoint/Prozentanteil-der-Gesamtplatte/Dateisystem), ohne
das bestehende scheme:"single" in irgendeiner Weise zu veraendern (eigene
Funktionen statt Erweiterung der bestehenden).

Alle drei Backends (mint/debian/ubuntu-image) verzweigen in backend_launch()
auf das Schema aus der Bereitstellungsvorlage und validieren extra_partitions
zusaetzlich defensiv in backend_validate() (Prozentsumme, doppelte
Mountpoints, Dateisystem-Whitelist ext4/btrfs - zfs/Fedora bewusst nicht).

Gegenstueck (API+GUI+DB) ist in provisioning-server/kundenplattform bereits
committet. Teil von platform-docs/roadmap/e2e-testrunde-lokale-
adressierung.md Phase 3.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
2026-09-19 14:57:59 +02:00
adminandClaude Sonnet 5 5bc8d108a6 Lokal-Test-Adressierung + Golden-Image-Embedding fuer LAN-E2E-Tests
--local-test-anode-url an build_boot_medium.sh macht anode per Klartext-
HTTP direkt im LAN erreichbar statt ueber Pangolin/Internet (anode hat
kein LAN-gueltiges TLS-Zertifikat, Split-Horizon-DNS auf https://
anode.tuxflotte.de wuerde daher an Zertifikatsfehlern scheitern).
--embed-golden-image backt das Golden-Image-Archiv direkt auf die ISO
(includes.binary, ausserhalb des squashfs), damit auch das beim
Deployment kein Netzwerktransfer mehr ist. Beide Flags sind rein additiv
und beeinflussen den Produktivpfad (kein Flag) nicht.

Betrifft beide Skriptbaum-Kopien (scripts/backends und boot-medium/
config/includes.chroot/...), da es dafuer kein Sync-Tooling gibt.

Siehe platform-docs/roadmap/e2e-testrunde-lokale-adressierung.md fuer
den vollstaendigen Plan inkl. offener Verifikationspunkte (toram-
Verhalten bei includes.binary, exakter Live-Medium-Mountpunkt).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
2026-09-19 14:43:29 +02:00
adminandClaude Sonnet 5 d3daed475a boot-medium: enable proposed-updates flag + add dracut-live chroot hook
- config/chroot: LB_PROPOSED_UPDATES="false" (explicit default alongside
  the existing backports/updates flags)
- new hooks/normal/5050-dracut.hook.chroot: adapts the live medium for
  dracut-live instead of initramfs-tools (removes initramfs-tools/live-boot
  packages, fixes hardcoded /run/live/medium path for Calamares)

Both files were live-build-generated config left uncommitted in the
working tree, found while checking for unfixed work before shutting
down idle sessions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmjSLwQhrnVK3FX2VX9Tbw
2026-09-12 16:11:07 +02:00
adminandClaude Sonnet 5 4bb04cc8c9 golden-image: apt-get purge braucht eigene Retry-Variante (Paket-nicht-gefunden-Folgefehler)
Der generische apt_chroot_with_retry() aus dem vorherigen Commit war fuer
apt-get purge falsch: ein echter Testlauf zeigte, dass der erste Versuch
beim Transaktionsende-Absturz laut dpkg.log fast immer schon fast alle
Pakete entfernt hat - ein zweiter Versuch mit der IDENTISCHEN,
vollstaendigen TRIM_PACKAGES-Liste scheiterte dann an 'Paket X kann nicht
gefunden werden' fuer jedes bereits entfernte Paket (apt-get bricht bei
einem einzigen unbekannten Namen die gesamte Kommandozeile ab). Neue
apt_purge_with_retry() prueft vor jedem Versuch per dpkg-query neu, was
von TRIM_PACKAGES wirklich noch installiert ist, und purgt nur das.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011HDFX6o1ZMxKVFLYiMjERR
2026-09-12 15:10:00 +02:00
adminandClaude Sonnet 5 66a6067528 golden-image: Retry fuer apt-get purge/autoremove im chroot (Absturz am Transaktionsende)
apt-get purge/autoremove scheitert im chroot reproduzierbar (4x live
beobachtet, mit jeweils voellig unterschiedlichen Paketen/Triggern) am
Ende der jeweiligen dpkg-Transaktion mit einem knappen, unuebersetzten
'E: Sub-process returned an error code' (exit 100) - kein paketspezifisches
Problem, sondern etwas Generisches am Transaktionsende. Root Cause trotz
intensiver Diagnose (3 volle Testlaeufe gegen golden-linux-mint/103 +
interaktive chroot-Session) nicht gefunden - ausgeschlossen: OOM-Kill,
AppArmor-DENIED, kaputte dpkg-Datenbank, devpts-Rechte-Varianten.

Laut dpkg.log ist die eigentliche Paketarbeit beim Absturz jedes Mal schon
vollstaendig fertig, ein 'dpkg --configure -a' danach ist immer sofort
sauber. Pragmatischer Workaround statt weiterer Root-Cause-Suche:
apt_chroot_with_retry() versucht den jeweiligen chroot-Aufruf bis zu
dreimal - der zweite Versuch sieht dann 'nichts mehr zu tun' und liefert
exit 0.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011HDFX6o1ZMxKVFLYiMjERR
2026-09-12 15:06:31 +02:00
adminandClaude Sonnet 5 8196166c90 golden-image: Trimming-Mounts fixen (Incident 11.09.2026), Trimming-Feature committen
Zwei Bugs behoben, die den Mount-Incident vom 11.09.2026 verursacht haben
(rm -rf gegen einen noch teilweise gemounteten Pfad hat echte
Geraetedateien auf dem Build-Host geloescht, u.a. /dev/null):

1. mount --rbind /dev -> normaler --bind + eigene, frische devpts-Instanz
   nur fuer dev/pts. --rbind hat die STAGING_DIR-Devpts-Instanz 1:1 mit der
   des eigenen Terminals geteilt - beim Aufraeumen war der Sub-Mount
   dadurch 'busy', was zu einem manuellen Lazy-Unmount (umount -l)
   verleitet hat.

2. unmount_chroot_binds() nutzt jetzt nirgends mehr umount -l/-R (Lazy-
   /rekursiver Unmount) - stattdessen normaler umount mit begrenztem Retry
   je Mount. cleanup() prueft zusaetzlich UNABHAENGIG per mountpoint -q
   nach, bevor rm -rf auf STAGING_DIR laeuft, und verweigert das Loeschen,
   falls doch noch etwas eingehaengt ist, statt stillschweigend
   weiterzumachen.

Gleichzeitig wird damit das inhaltlich bereits fertige, bisher nur
uncommitted auf controller liegende Trimming-Feature (echter Testlauf
11.09.2026, 37 Pakete/910MB) mit committed - siehe Kommentar im Skript fuer
die vollstaendige Paketauswahl-Analyse.

Noch offen: naechster echter Testlauf des reparierten Mount-/Unmount-
Zyklus gegen golden-linux-mint/103 (bisher nur syntaktisch/statisch
geprueft, nicht real gegen chroot+apt getestet).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011HDFX6o1ZMxKVFLYiMjERR
2026-09-12 13:38:23 +02:00
adminandClaude Sonnet 5 7c52e5fb90 Kritischer Fix: ansible-core fehlte in allen drei Golden-Images
Live gefunden (09.09.2026, beim Vorbereiten eines Kolibri/Veyon-Tests
auf golden-linux-mint): ansible ist auf KEINEM der drei Golden-Images
(Mint/Debian/Ubuntu) tatsaechlich installiert - nur zufaellige
bash-completion-Stub-Dateien vom bash-completion-Paket vorhanden
(taeuschen bei einer oberflaechlichen Pruefung echte Installation vor),
keine echten Binaries. Der Provisioning-Agent ruft aber ansible-pull
bei JEDEM Checkin auf.

Bisher durch den fruehen 'nichts zu tun'-Ausstieg in agent.py
maskiert (kein ansible-pull-Aufruf ohne zugewiesene
Blueprints/Auftraege) - seit der heutigen Webapp-Aenderung
(webapp-shortcuts-Rolle immer getaggt, siehe admin/provisioning-agent)
haette das ab sofort auf JEDEM Geraet fehlgeschlagen.

Fix in backend_postinstall() aller drei Backends (mint-image/
debian-image/ubuntu-image): ansible-pull-Verfuegbarkeit zusaetzlich zu
jq/curl/python3 sichergestellt, Paket 'ansible' (nicht nur
'ansible-core') gewaehlt, weil es die community.general-Collection
gleich mitbringt (von brave/onlyoffice/libreoffice/gdevelop/turbowarp
gebraucht - sonst waere ein zusaetzlicher ansible-galaxy-Schritt
noetig). Boot-Medium-Payload-Kopie synchronisiert.

Noch zu tun: Boot-Medium neu bauen+deployen (wie beim GRUB-Timeout-Fix
heute frueher), dann echten Neu-Deploy-Test fahren, um den Fix
tatsaechlich zu beweisen statt nur den Code zu lesen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLk93dhDMrkPXefVdknMV9
2026-09-09 18:27:32 +02:00
adminandClaude Sonnet 5 b5cc14e469 Boot-Medium: GRUB/Isolinux-Timeout setzen (10s statt unendlich wartend)
Bei Phase 1 (Debian-E2E-Test, 08.09.2026) gefunden: live-builds
Standardvorlagen setzen weder fuer GRUB (UEFI-Pfad) noch fuer
Isolinux (BIOS-Pfad) einen Timeout - GRUB-Default ist -1 (wartet
unendlich auf Tastendruck), Isolinux' 'timeout 0' bedeutet ebenfalls
'Timeout deaktiviert', nicht 'kein Timeout'. Fuer echte
unbeaufsichtigte 'Stick rein, warten'-Installationen ohne
anwesenden Techniker waere das ein Show-Stopper.

Fix per live-build-Standard-Override-Mechanismus
(config/bootloaders/<name>/, gleiches Muster wie schon beim
Splash-Bild): beide Bootloader auf 10s gesetzt, danach automatischer
Start des Standard-Eintrags (default=0 bzw. 'menu default' sind
bereits gesetzt).

Verifiziert: Timeout-Werte im tatsaechlich gebauten ISO per
xorriso-Extraktion bestaetigt (set timeout=10 / timeout 100). QEMU-
Boot mit unveraendertem Menue lief 100+s mit durchgehend >100% CPU
(kein Idle-Warten am Menue) - Bildschirm-Screendump zur visuellen
Bestaetigung blieb in dieser Sandbox-Umgebung technisch unzuverlaessig
(bekanntes Problem, siehe Ubuntu-E2E-Debugging vom selben Tag),
statische Config-Verifikation + CPU-Aktivitaets-Nachweis reichen als
Ersatz.

Noch offen: neues Boot-Medium muss noch auf anode deployed werden
(gebaute ISO liegt lokal, altes Basis-Image auf anode ist noch ohne
diesen Fix) - reines 'git pull' reicht dafuer nicht, siehe bestehende
Lehre in project_independent_boot_medium.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLk93dhDMrkPXefVdknMV9
2026-09-09 11:56:42 +02:00
admin 4f34d80777 Boot-Medium-Payload: ubuntu-image-Backend synchronisieren 2026-09-09 08:10:35 +02:00
admin 4f3ea1b1aa Phase 1: neues backends/ubuntu-image/ (dritte Referenz-Distribution) 2026-09-09 07:26:25 +02:00
admin 2eef840287 build_customer_iso.sh: Ausgabe-ISO zurueck an provisioning-server chownen 2026-09-08 18:06:01 +02:00
admin d20328ed80 debian-image: headless ist Absicht, nicht offene Frage (User-Entscheidung)
Desktop kommt bei Debian per Ansible-Blueprint nach dem ersten Boot -
Debian erlaubt das grosszuegiger als Mint/Ubuntu. Reiner
Kommentar-Update, keine Verhaltensaenderung (Boot-Medium-ISO muss dafuer
nicht neu gebaut werden).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpNs8yZeQkHgMWx6WNT1QH
2026-09-08 17:07:23 +02:00
admin 63df40d920 Phase 1: neues backends/debian-image/ (zweite Referenz-Distribution)
Strukturell identisch zu backends/mint-image/backend.sh (image_deploy.sh
ist bereits komplett distributionsunabhaengig, postinstall.sh ist per
Symlink geteilt - beides beim Anlegen bestaetigt, keine Mint-spezifische
Annahme gefunden). Referenz-VM ist "golden-debian" (VM 104 auf
tuxflotte-pve).

WICHTIG, noch offen: golden-debian ist aktuell ein schlankes, headless
Debian-13-Basissystem OHNE Desktop-Umgebung - anders als golden-linux-mint
(volle Cinnamon-Desktop). Ob das Absicht ist (Desktop kommt per
Ansible-Blueprint nach dem ersten Boot, urspruengliche ADR-0024-Idee) oder
noch unvollstaendig, ist NICHT entschieden - GOLDEN_IMAGE_URL zeigt
deshalb bewusst auf ein als "-base" benanntes Archiv statt den Stand als
fertiges Desktop-Image zu behaupten.

Ausserdem gefunden: boot-medium/config/includes.chroot/opt/tuxflotte/ ist
eine manuell gepflegte Kopie von backends/+scripts/+config/, kein
automatischer Sync aus dem Top-Level-Repo - die vorherige
target_disk_rank-Aenderung an backends/mint-image/backend.sh fehlte hier
deshalb zunaechst und wird mit diesem Commit nachgezogen.

Siehe platform-docs/roadmap/multi-distro-merkmal-workspace-creator.md,
Phase 1 (zweite Referenz-Distribution).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpNs8yZeQkHgMWx6WNT1QH
2026-09-08 16:01:42 +02:00
admin ed5911a28a Mehrplatten-Heuristik: Zieldatentraeger nach Groessen-Rang statt lsblk-Reihenfolge
_mint_image_detect_target_disk() nimmt jetzt einen Rang-Parameter
(Default 1) statt blind die erste Platte in lsblk-Erkennungsreihenfolge
zu waehlen - die war nicht deterministisch (abhaengig von
Bus-Typ/Anschluss/Erkennungszufall), riskant bei mehreren internen
Datentraegern. Neue Logik: nach Plattengroesse absteigend sortieren
(deterministischer Tiebreak per Geraetepfad bei Gleichstand), dann den
angefragten Rang herausgreifen. Rang kommt aus der neuen
installation_directives.partitioning.target_disk_rank der
Bereitstellungsvorlage (backend_validate() prueft auf positive
Ganzzahl, backend_generate_config() reicht sie durch), Default 1 =
groesste Platte.

Unit-getestet mit gemocktem lsblk-Output (Normalfall, Gleichstand-
Tiebreak, Rang > verfuegbare Plattenzahl, Default ohne Parameter) - alle
Faelle wie erwartet. Kein echter Multi-Disk-QEMU/Hardware-Boot-Test in
dieser Session.

Siehe platform-docs/roadmap/multi-distro-merkmal-workspace-creator.md,
Phase 0 (Mehrplatten-Heuristik), 08.09.2026 mit dem Nutzer entschieden.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpNs8yZeQkHgMWx6WNT1QH
2026-09-08 15:33:11 +02:00
admin 823694369f Golden-Image-Archiverstellung mit niedrigster CPU-/IO-Prioritaet
package_golden_image.sh und build_golden_image.sh renicen sich beim Start
selbst (renice 19, ionice idle-Klasse) - vererbt an alle Kindprozesse
(ssh/tar/zstd/chroot). Der SSH-Tar-Pull und vor allem die zstd-19-
Kompression sind sehr rechenintensiv und laufen ueber
golden-image-refresh.sh direkt auf dem Proxmox-Host, nicht in einer VM -
andere dort laufende VMs sollen darunter nicht leiden. Laufzeit ist dabei
bewusst egal (User-Vorgabe 08.09.2026).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpNs8yZeQkHgMWx6WNT1QH
2026-09-08 14:58:57 +02:00
adminandClaude Sonnet 5 ee7041d94e build_customer_iso.sh: WORK_DIR fest auf /var/tmp statt mktemp-Standard
Beim anode-VM-Umzug auf tuxflotte-pve gefunden: dort ist /tmp systemd-
typisch tmpfs (RAM-begrenzt, ~1.9GB) - reicht fuer das entpackte
Squashfs nicht (>3GB). sudo's env_keep fuer TMPDIR wirkt trotz
Sudoers-Eintrag nicht zuverlaessig durch die run_iso_build()-sudo-
Eskalation in provisioning-server (De-Root-Umzug), deshalb hart auf
/var/tmp verdrahtet statt auf ererbte Umgebung zu vertrauen. Echter
End-to-End-Test (reales Golden Image, ueber systemd-run im selben
Namespace wie der Produktionsdienst) bestaetigt funktionierend.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KMczXJkjyv59Ds3TsDw8H3
2026-09-07 16:09:05 +02:00
admin aca60f91e0 fix(image_deploy): BIOS-Partitionierung lieferte leeren Root-Partitionspfad
Echter Bug, live gefunden (02.09.2026, Phase 0 des Roadmap-Plans - erster
tatsaechlicher BIOS-Boot-Test ueberhaupt, bisher ausschliesslich
UEFI/OVMF getestet):

image_deploy_partition() gab im BIOS-Zweig "echo \" ${part2}\"" zurueck
(fuehrendes Leerzeichen, um ein "leeres erstes Feld" zu signalisieren).
Die Gegenseite ("read -r boot_part root_part <<<...") scheiterte daran:
bashs Standard-IFS-Wortzerlegung ueberspringt FUEHRENDE Trennzeichen vor
dem ersten Feld - es entsteht also gerade KEIN leeres erstes Feld,
sondern der gesamte Wert landet in "boot_part", "root_part" bleibt leer.

Symptom: mkfs.vfat lief faelschlich auf der eigentlichen Root-Partition,
mke2fs bekam einen leeren Pfad ("The file  does not exist and no size
was specified"), backend_launch() schlug fehl.

Fix: das tatsaechlich vorhandene Feld (root) ZUERST ausgeben, das
optionale (boot, nur bei UEFI vorhanden) ZULETZT - "read" laesst
ueberzaehlige Variablen bei zu WENIGEN Eingabefeldern zuverlaessig leer,
nur das ist robust, nicht das Ueberspringen fuehrender Trennzeichen.
backend.sh entsprechend auf "read -r root_part boot_part" angepasst.

Verifiziert per echtem QEMU-Boot ohne OVMF (reines SeaBIOS,
pc-i440fx-Maschine, kein pflash-Loader): kompletter Self-Service-Flow
lief danach voll durch - Partitionierung/Formatierung (BIOS-Grub-Partition
+ ext4-Root), Golden-Image-Download+Extraktion, grub-install
(--target=i386-pc), Postinstall, Agent-Bootstrap (agent_secret_issued_at
in der DB bestaetigt), Reboot - bis zum echten Linux-Mint-Cinnamon-
Login-Bildschirm.

Dabei nebenbei einen unabhaengigen, zweiten echten Bug gefunden+behoben
(Datenbank, nicht Code): zwei Bereitstellungsvorlagen ("Schulcomputer
(Mint)" in den Orgs "Default Lab" und "WLAN-Test") zeigten noch auf den
am 01.09.2026 bewusst entfernten "mint"-Backend (backends/mint/, per
Phase 4 des Boot-Medium-Umbaus geloescht) statt auf das aktuelle
"mint-image" - jede Installation ueber diese Vorlagen waere an Modul 10
("Kein Backend fuer 'mint' gefunden") gescheitert. Per direktem
UPDATE auf beide Vorlagen korrigiert (backend_id auf mint-image
umgebogen). Fuenf verwaiste Merkmal/Blueprint-Eintraege, die ebenfalls
noch am toten "mint"-Backend haengen, bewusst NICHT angefasst (Feature/
Blueprint-Modell, separates Thema, dem Nutzer gemeldet statt unilateral
entschieden).
2026-09-02 12:40:10 +02:00
admin 47444f8837 fix: PIPESTATUS-Verlust bei fehlschlagenden Pipelines unter set -e beheben
Zwei echte Bugs, beide live gefunden beim Testen des frisch verschlankten
Golden Images (02.09.2026), beide dieselbe Fehlerklasse:

- image_deploy_extract_image_from_url() (curl | tar): eine fehlschlagende
  Pipeline direkt gefolgt von PIPESTATUS-Auswertung wurde durch drei
  aufeinanderfolgende Bugs verdeckt (`|| true` loescht PIPESTATUS; eine
  Pipeline als "if"-Bedingung erhaelt PIPESTATUS nicht vollstaendig; zwei
  getrennte "local"-Anweisungen setzen PIPESTATUS je Anweisung zurueck).
  Symptom: eine erfolgreiche Entpackung wurde faelschlich als Fehlschlag
  gemeldet. Fix: "set +e" / nackte Pipeline-Anweisung / EINE "local
  pipe_status=(...)"-Zeile / "set -e" - empirisch verifiziert fuer Erfolg
  und Fehlschlag.

- boot-autostart.sh (installer.sh | tee): dieselbe Pipeline-unter-"set -e"-
  Falle, aber ohne die drei Verdeckungs-Bugs - "errexit" brach das ganze
  Skript SOFORT an der Pipeline-Zeile ab, sobald installer.sh tatsaechlich
  fehlschlug, noch bevor "STATUS=..." je erreicht wurde. Folge: die
  installation_failed-Meldung an anode lief seit ihrer Einfuehrung nie ein
  einziges Mal, trotz mehrerer echter Fehlschlaege beim heutigen Testen
  (per Datenbankabfrage bestaetigt: durchgehend null Eintraege). Gleicher
  Fix wie oben. Verifiziert: QEMU zeigt nach einem gezielten Fehlschlag
  jetzt korrekt "Tuxflotte-Installer beendet (Exit-Code: 1)."; die
  Meldefunktion selbst (reporting.sh -> anode) wurde zusaetzlich isoliert
  mit echtem device_fingerprint/device_id durchgetestet und liefert
  korrekt einen device_installation_events-Eintrag.

Dazu, aus demselben Testlauf:

- utils.sh: Re-Install-Schutz (25_installation_confirm.sh) darf nicht durch
  run_module_quiet()'s Hintergrund-Wrapper laufen, wenn der Server
  .device.previously_installed=true meldet - dessen "read" bekaeme sonst
  sofort EOF statt echter Eingabe. Neue Praeflight-Pruefung
  _tuxflotte_device_previously_installed() entscheidet vor Modulstart, ob
  der Vordergrund-Pfad noetig ist. Verifiziert per QEMU (echter j/N-Prompt
  erscheint und laesst sich beantworten).

- package_golden_image.sh: komplette Neufassung - Bereinigung laeuft jetzt
  auf einer per SSH gezogenen KOPIE (auf enterprise), nie mehr auf der
  laufenden Referenz-VM selbst (vorher: Skript loeschte SSH-Hostkeys etc.
  live auf der VM, machte sie temporaer unerreichbar). Zusaetzlich
  --one-file-system (verhinderte, dass eine versehentlich eingehaengte
  Installer-ISO mitarchiviert wurde) und STAGING_BASE_DIR (mktemp -d -p
  statt Default-/tmp, verhindert ENOSPC bei grossen Golden Images).
2026-09-02 10:46:09 +02:00
admin 4f00d1a6e1 25_installation_confirm: Re-Install-Schutz - echte Rueckfrage bei bereits installiertem Geraet
Auto-Modus-Abkuerzung greift nicht mehr, wenn der Server
.device.previously_installed=true meldet (siehe provisioning-server-Commit
b88a934) - stattdessen echte Rueckfrage ("Installation jetzt starten?
[j/N]"), ohne Timeout (kein "Ja" ohne jemanden vor Ort). Deutliche
Warnung in der Installationsplan-Anzeige.

Nutzer-Wunsch (02.09.2026): "Was ist eigentlich, wenn der Stick bei einem
bereits installierten System erneut ausgeführt wird?" - bisher haette ein
erneut gestecktes Boot-Medium die Zielplatte im Auto-Modus stillschweigend
komplett neu bespielt, ohne jede Rueckfrage.
2026-09-02 08:04:56 +02:00
admin 8b47751b31 boot-medium: Konsolen-Rauschen bei 40_backend.sh verbergen, toram, neues Banner
Drei zusammenhaengende Punkte aus dem zweiten echten Hardware-Test
(02.09.2026):

1. "Das backend40-Script/Partitionierung zeigt viele Zeilen Ausgaben...
   Nach dem Entpacken kommen wieder sehr viele Zeilen Ausgaben" - neue
   run_module_backend() (utils.sh) faengt jetzt auch 40_backend.sh ab
   (Partitionieren/Formatieren/chroot-Fixup/Bootloader/Postinstall
   verborgen wie jedes andere Modul), OHNE animierten Kreisel (statischer
   Titel, da das Modul seinen eigenen Fortschritt zeigt). Der Download-
   Fortschrittsbalken selbst bleibt sichtbar: curl schreibt ihn bei
   aktivem TUXFLOTTE_TTY_LIVE direkt auf /dev/tty1, umgeht damit gezielt
   die stdout/stderr-Umleitung des Moduls (image_deploy.sh).

2. "Wenn ich... mit Enter den Neustart auslösen möchte, kommt es zu
   zahlreichen squashfs-Fehlern, weil das Dateisystem nicht mehr da ist."
   - "toram" im Bootappend (build_boot_medium.sh) kopiert das gesamte
   Boot-Medium beim Start einmalig in eine Tmpfs; danach ist der Stick fuer
   den laufenden Betrieb komplett irrelevant, ein Ziehen jederzeit
   gefahrlos moeglich - vorher blieb das laufende System per Squashfs+
   Loop-Mount direkt vom physischen Medium abhaengig.

3. Neues Boot-Banner (pics/tuxflotte-terminal-80neu.txt).

Beim eigenen Testen von Punkt 1 zwei echte Bugs gefunden+behoben (siehe
Kommentare in image_deploy.sh): "pipeline || true" ueberschreibt
PIPESTATUS mit dem einelementigen Ergebnis von "true", sobald die
Pipeline fehlschlaegt - traf live bei einer echten Netzwerkunterbrechung
waehrend des Downloads auf ("pipe_status[1]: unbound variable" unter
"set -u"). Der Wechsel auf eine "if"-Bedingung (set -e-Ausnahme ohne ein
zweites Kommando) reichte allein nicht, PIPESTATUS blieb bei einem
echten, mitten im Transfer abgebrochenen curl|tar manchmal trotzdem
unvollstaendig - jetzt zusaetzlich robust mit ":-1"-Fallback direkt auf
den einzelnen Indizes statt einer vorausgesetzten vollstaendigen Kopie.

Live in QEMU verifiziert: neues Banner + verborgenes Partitionier-Rauschen
+ sichtbarer Fortschrittsbalken bestaetigt (Screenshot). Eine echte,
waehrend des Testens aufgetretene Netzwerk-Durchsatzverschlechterung
(anode nur noch ~4,6 MB/s, unabhaengig von diesem Code) verhinderte einen
weiteren vollstaendigen Erfolgsdurchlauf in dieser Session - der
pipe_status-Fix selbst wurde aber genau durch diese Unterbrechung bestaetigt
(sauberer [FEHLER]-Abbruch mit klarer Meldung statt Bash-Crash). toram
selbst (Boot bis zum Auto-Modus-Start, Konfiguration/Partitionierung liefen
durch) und die Rauschen-Unterdrueckung sind bestaetigt; die volle
Stick-waehrend-Reboot-Sequenz bleibt fuer den naechsten echten
Hardware-Test zu bestaetigen.
2026-09-01 19:11:59 +02:00
admin d496adad09 installer: Installations-Meilensteine/Fehlschlaege an anode melden
Neue scripts/lib/reporting.sh (tuxflotte_report_installation_event())
meldet best-effort an POST /api/v1/devices/{device_id}/installation-events
(device_fingerprint-authentifiziert, siehe provisioning-server-Commit
51fbf0f) - ein Fehlschlag beim Melden selbst darf die eigentliche
Installation nie aufhalten.

Vier Meldepunkte:
- "activation_confirmed" direkt nach erfolgreichem Provisioning-Handshake
  (15_server_handshake.sh)
- "installation_started" direkt nach bestaetigtem Commit Point
  (installer.sh)
- "installation_completed" ganz am Ende von backend_postinstall(), vor dem
  finalen Reboot (backend.sh)
- "installation_failed" zentral in boot-autostart.sh (einziger Ort, an dem
  der echte Exit-Code von installer.sh bekannt ist, ohne jedes Modul
  einzeln instrumentieren zu muessen) - Detail = letzte 40 Logzeilen,
  enthalten bereits die eigentliche [FEHLER]-Meldung des gescheiterten
  Moduls. Nur bei STATUS != 0, nicht bei einem kontrollierten Abbruch an
  einem Commit-Gate (STATUS = 0).

Nutzer-Wunsch (01.09.2026, nach dem ersten echten Hardware-Test):
Fehlschlaege waehrend der Installation sichtbar machen, ohne am
Bildschirm mitschreiben zu muessen ("das ist kein Flow... fuer die
Weiterentwicklung eines irgendwann fehlerfreien Betriebs sind fuer uns
diese Meldungen Gold wert").

Live in QEMU end-to-end verifiziert: alle drei Erfolgs-Meilensteine
korrekt in device_installation_events angekommen (activation_confirmed,
installation_started, installation_completed), vollstaendiger Durchlauf
bis zum echten Mint-Cinnamon-Login-Bildschirm nach Reboot bestaetigt.
2026-09-01 16:52:15 +02:00
admin 43a18074e0 boot-medium: eigenen GRUB/isolinux-Boot-Splash statt live-build-Standard
Neue config/bootloaders/syslinux_common/splash.svg ersetzt live-builds
generische Boot-Grafik (Bauhelm-Symbol + Paketversionen + Baudatum/Uhrzeit
- /usr/share/live/build/bootloaders/syslinux_common/splash.svg) komplett:
live-build kopiert config/bootloaders/${_BOOTLOADER}/ und
config/bootloaders/syslinux_common/ als Nutzer-Override ueber die eigenen
Standard-Assets (siehe binary_syslinux: _SOURCE_USER_COMMON), rsvg-convert
rastert automatisch zu splash.png/splash800x600.png, GRUB uebernimmt
dieselbe Grafik (theme.txt "desktop-image").

Nutzer-Feedback (01.09.2026, echter Hardware-Test): "Gestaltung des
Bootmenüs ist sehr trixiehaft. Geht da auch eines unserer svg's?" - das
echte Tuxflotte-Logo (kundenplattform/static/tuxflotte-logo.svg) als
PNG eingebettet (statt der komplexen LibreOffice-Original-SVG direkt, um
rsvg-convert keine verschachtelten clipPath/defs-Strukturen zuzumuten),
auf schwarzem 800x600-Hintergrund, oberes Drittel - der Bereich ab y=312
(52% von 600, siehe boot_menu.top in theme.cfg) bleibt leer fuer
Bootmenue/Fusszeile/Timeout-Balken.

Live in QEMU boot-getestet: sauberer Boot bis zum Menue, Logo korrekt
gerendert (identisch zur lokalen rsvg-convert-Vorschau), kein
Versions-/Zeitstempeltext mehr sichtbar.
2026-09-01 15:46:34 +02:00
admin 8615d9fde1 Konsole: kompakte Kreisel/Haken-Anzeige statt Log-Wand + Kernel-Zeitstempel entfernt
Nutzer-Feedback (01.09.2026, echter Hardware-Test) mit mehreren
zusammenhaengenden Konsolen-UX-Punkten:

- "Die Darstellung des Abarbeitens der Skripte und Module ist noch nicht
  schön... Modul XY läuft (kreiselnde Symbole)... gründer Haken als
  erledigt" - neue run_module_quiet() (utils.sh) fuehrt ein Modul im
  Hintergrund aus, zeigt waehrenddessen einen Kreisel auf derselben Zeile,
  am Ende [OK] (gruen) oder [FEHLER] (rot) + volle mitgeschnittene Ausgabe
  bei einem Fehlschlag. Nur im echten Auto-Modus aktiv (dort fragt kein
  Modul interaktiv nach) - 40_backend.sh bleibt bewusst verbose
  (TUXFLOTTE_VERBOSE_MODULES), da dort der neue Download-Fortschrittsbalken
  sichtbar bleiben soll.
- "Bei Entpacken und schreiben des Archivs, kann man das einen
  Fortschrittsbalken... anzeigen lassen?" - curl "--silent" durch
  "--progress-bar" ersetzt (image_deploy.sh).
- "Der Kernel Zeitstempel ist für den Kunden nicht interessant, sondern
  nur verwirrend." - eigentliche Ursache war nicht der GRUB-Splash
  (separater Commit), sondern StandardOutput=journal+console im
  systemd-Unit: journald spiegelt Konsolenausgaben im kmsg-Stil mit
  monotonem "[  12.345678]"-Zeitstempel, sah aus wie ein Kernel-Log.
  Jetzt "StandardOutput/Error=console" (direkt an /dev/tty1, kein
  journald) - journalctl zeigt dadurch nur noch Dienst-Lebenszyklus-
  Meldungen, die volle Ausgabe bleibt vollstaendig in
  /var/log/tuxflotte-installer.log (bereits der dokumentierte Weg).

Zwei echte Bugs beim eigenen Boot-Test dieser Aenderung gefunden+behoben:
(1) log_module_title() gab den Titel per Command-Substitution zurueck -
lief dadurch in einer Subshell, der TUXFLOTTE_STEP_COUNT-Zaehler blieb
immer bei 1 stehen ("[1/12]" bei jedem Modul). Jetzt ueber eine globale
TUXFLOTTE_CURRENT_TITLE-Variable statt Command-Substitution.
(2) Unicode-Kreisel (⠋⠙...) und Haken (✓/✗) wurden von der
vt-Konsolenschriftart nicht abgedeckt, zeigten nur einen generischen
Ersatz-Kasten - auf reines ASCII (|/-\, "[OK]"/"[FEHLER]") umgestellt,
garantiert auf jeder Konsolenschriftart lesbar.

Ausserdem: Beep + "Stick jetzt entfernen"-Hinweis + ENTER-Bestaetigung
(oder automatischer Neustart nach 5 Minuten) direkt vor dem finalen
Reboot in backend.sh (separater Commit, siehe backend_postinstall()).

Live in QEMU boot-getestet (Zaehler/Farben/Kreisel im Rohlog verifiziert,
kompletter Auto-Modus-Durchlauf inkl. Fehlerfall-Dump getestet, voller
End-to-End-Durchlauf bis zum echten Mint-Cinnamon-Login-Bildschirm nach
Reboot bestaetigt).
2026-09-01 15:46:18 +02:00
admin 06ba89697b mint-image: device_fingerprint ohne sudo lesbar machen
/etc/tuxflotte auf 0755 gelockert (war 0700) + device_fingerprint
explizit chmod 0644 - andere Dateien darin (agent.credentials) bleiben
per eigenem chmod 0600 individuell geschuetzt, wie /etc/shadow trotz
durchsuchbarem /etc selbst.

Nutzer-Feedback (01.09.2026, echter Hardware-Test): "/etc/tuxflotte/
device_fingerprint sollte für User lesbar ohne sudo sein" - war trotz der
schon vorhandenen Absicht (Klartext, kein Secret, siehe Kommentar dort)
nicht moeglich, weil das umschliessende Verzeichnis 0700 blieb.
2026-09-01 15:45:57 +02:00
admin 3f17885d55 mint-image: WLAN-/Netzwerkverbindungsprofil ins Zielsystem uebernehmen
Neue image_deploy_install_network_profile() kopiert das von
export_connection_profile() (05_network.sh) geschuetzt abgelegte
Verbindungsprofil nach /etc/NetworkManager/system-connections/ im
Zielsystem - backend_launch() ruft das nach dem Mounten auf.

Nutzer-Feedback (01.09.2026, echter Hardware-Test): "WLAN-Information sind
nicht konsistent. Nach Reboot muss PSK neu eingegeben werden." Root Cause:
export_connection_profile() legte das Profil zwar unter
/run/tuxflotte/network/connection.nmconnection ab, aber niemand holte es
von dort ab - das frisch installierte System stand beim ersten Boot ohne
gespeichertes Profil da.
2026-09-01 15:45:31 +02:00
admin 3739da37dc mint-image/hardware: Boot-Medium-Platte in gemeinsame lib ausgelagert
_mint_image_boot_medium_disk() aus backend.sh nach scripts/lib/boot_medium.sh
verschoben (tuxflotte_boot_medium_disk()) - build_storage_devices_json()
(hardware_collectors.sh) braucht dieselbe Ausschluss-Logik jetzt ebenfalls.

Nutzer-Feedback (01.09.2026, echter Hardware-Test): der Installations-
USB-Stick selbst tauchte in der Kundenplattform unter Flotte -> Aktionen ->
Hardware-Info -> Datenträger auf - fuer den Kunden irrefuehrend, da dieser
Datentraeger nach der Installation gar nicht mehr existiert. Gleiche
Ursache wie der parted-Bug (Commit fa54461): lsblk liefert das Boot-Medium
auf echter USB-Stick-Hardware als normalen TYPE="disk" zurueck.
2026-09-01 15:45:25 +02:00
admin fa54461cae mint-image: Boot-Medium-Platte von Zielplatten-Erkennung ausschliessen
Auf echter USB-Stick-Hardware (anders als in bisherigen QEMU-Tests mit
CD-ROM-Boot-Medium) enumeriert das Boot-Medium selbst als "disk"-Typ,
genau wie die interne Zielplatte - _mint_image_detect_target_disk()
konnte deshalb den eigenen Stick waehlen, dessen Partitionierung dann
immer mit dem "unable to inform the Kernel of the change"-Fehler
scheitert (man kann die Platte nicht partitionieren, von der man lebt).

_mint_image_boot_medium_disk() findet das Boot-Medium ueber
findmnt/lsblk (dem Live-Mountpoint /run/live/medium bis zur
Elternplatte folgend) und schliesst es aus der Kandidatenliste aus.

Verifiziert in QEMU: Boot-Medium-ISO absichtlich als device='disk' auf
hda (vor dem eigentlichen Ziel-qcow2 auf hdb) angehaengt, um die reale
Aufzaehlungsreihenfolge einer USB-Stick-Installation nachzustellen -
ohne diesen Fix waere hda (das Boot-Medium) gewaehlt worden. Mit dem
Fix: "Zieldatentraeger: /dev/sdb", Partitionierung/Formatierung ohne
Fehler, komplette Golden-Image-Bereitstellung durchgelaufen, Reboot in
den echten Linux-Mint-Cinnamon-Login-Bildschirm bestaetigt (Hostname
"debian", Login "tuxflotte", deutsches Tastaturlayout).
2026-09-01 13:29:45 +02:00
admin 5b9d3fdf6a fix(installer): Zielplatte vor dem Partitionieren freigeben + Kernel-Neueinlesen mit Wiederholung
Live auf echter Hardware gefunden (01.09.2026): "Error: Partition(s) 1
on /dev/sda have been written, but we have been unable to inform the
Kernel of the change, probably because it/they are in use." - parted
schreibt die neue GPT-Tabelle zwar trotzdem, meldet aber einen Fehler,
wenn eine alte Partition (Swap, gemountetes Dateisystem vom vorherigen
Betriebssystem auf dieser Platte) noch belegt ist. In QEMU mit stets
frischen Testplatten nie aufgetreten - reale Kundenhardware hat aber
fast immer schon ein Vorleben auf der Platte.

Zwei neue Bausteine in image_deploy_partition():
- _image_deploy_release_disk(): unmountet/deaktiviert Swap auf allen
  vorhandenen Partitionen der Zielplatte, bevor ueberhaupt mklabel
  aufgerufen wird.
- _image_deploy_settle_partitions(): wiederholt partprobe/udevadm settle
  bis zu 5x statt nach einem einzigen Versuch aufzugeben, sowohl nach
  mklabel als auch nach dem Anlegen der eigentlichen Partitionen.
  Zusaetzlich wird nach mklabel explizit verifiziert, dass wirklich ein
  gueltiges GPT-Label vorliegt (parted print), statt parteds Exit-Code
  fuer den Kernel-Info-Schritt blind als Gesamtfehlschlag zu werten.

Lokal verifiziert: einmal komplett durchinstalliert (frische Platte),
dann OHNE die Platte zurueckzusetzen ein zweites Mal auf dieselbe,
bereits mit einem echten System belegte Platte installiert - lief
sauber durch, keine Kernel-Fehlermeldung mehr.
2026-09-01 12:00:55 +02:00
admin ebd827ee2f feat(installer): Netzwerkverbindung mit Wiederholungsversuchen statt Sofortabbruch
Live auf echter Hardware gefunden (01.09.2026): eine vorkonfigurierte SSID
war im Moment des Scans nicht sichtbar (Kunde stand ungluenstig, das
eigene Handy war im selben WLAN aber verbunden) - bisher brach
05_network.sh beim ersten Fehlschlag sofort fatal ab, ohne dem Kunden
eine Chance zu geben, den Standort zu wechseln oder ein Netzwerkkabel
einzustecken.

Neue establish_network_connection()-Schleife (Default: 10 Versuche,
15s Pause, beides per TUXFLOTTE_NETWORK_MAX_ATTEMPTS/
TUXFLOTTE_NETWORK_RETRY_DELAY konfigurierbar) wiederholt bei jedem
Versuch die KOMPLETTE Erkennung von vorne (nicht nur WLAN erneut) -
damit wird auch ein waehrend der Wartezeit eingestecktes Netzwerkkabel
erkannt, nicht nur ein erneuter WLAN-Versuch.

Lokal in der enterprise-QEMU-VM verifiziert: Netzwerk-Link waehrend des
Boots per virsh domif-setlink kurzzeitig deaktiviert - Retry-Meldung
"Verbindungsversuch 1/10 fehlgeschlagen..." erschien korrekt, nach
Wiederherstellen des Links lief der Installer beim naechsten Versuch
automatisch weiter bis zur Golden-Image-Installation.
2026-09-01 10:52:25 +02:00
admin 0874c2fd0f fix(boot-medium): /dev als leeres Verzeichnis wiederherstellen (Kernel-Panic beim echten Boot)
Live auf echter Hardware gefunden (01.09.2026), direkt nachdem der
vorige LXC-Fix (Commit f6bb3db) deployed wurde: "-excludes dev" entfernt
nicht nur die Geraetedateien, sondern das gesamte /dev-Verzeichnis.
live-boots eigenes Initramfs-Skript braucht /dev aber als reinen
Mountpunkt (bindet dort sein eigenes Devtmpfs ein, kurz vor
switch_root) und scheiterte deshalb sofort beim Booten mit "mount:
/root/dev: mount point does not exist", gefolgt von einem Kernel-Panic.

Fix: mkdir -p nach dem Entpacken stellt /dev als leeres Verzeichnis
wieder her - devtmpfs bindet sich selbst darueber, die eigentlichen
Geraetedateien werden nie aus dem Squashfs gebraucht. Dasselbe Muster
wie image_deploy_restore_excluded_dirs() beim Golden Image, nur hier
fuers Boot-Medium selbst.

Diesmal VOR dem Deploy lokal in der enterprise-QEMU-VM boot-getestet
(der vorige Fix wurde ungetestet deployed, was genau zu diesem Bug
fuehrte) - sauberer Boot bestaetigt, kein Kernel-Panic, Auto-Modus laeuft
bis zur Golden-Image-Installation durch.
2026-09-01 10:26:00 +02:00
admin f6bb3db9b9 fix(boot-medium): unsquashfs auf anode - /dev von Extraktion ausschliessen
Live gefunden (01.09.2026, erster echter Produktionslauf ueber die reale
Kundenplattform-API): anode laeuft in einem LXC-Container
(systemd-detect-virt: lxc), der CAP_MKNOD grundsaetzlich blockiert - auch
fuer root. unsquashfs scheiterte beim Wiederherstellen der wenigen
Geraetedateien im Boot-Medium-Squashfs (/dev/null, /dev/console, ...) mit
"Operation not permitted", ISO-Bau brach ab.

"-excludes ... dev" schliesst /dev komplett von der Extraktion aus -
anders als beim Golden Image (package_golden_image.sh) ist das hier
unkritisch: das Boot-Medium ist nur der Installations-Vermittler, nicht
das ausgelieferte System - devtmpfs erzeugt /dev beim tatsaechlichen Boot
ohnehin automatisch neu.

Zugehoerige Produktions-Deployment-Schritte (nicht im Diff sichtbar):
main auf anode gepullt (war noch auf dem alten bc9cefa-Stand vor dem
gesamten Boot-Medium-Umbau), squashfs-tools installiert (fehlte), neues
Basis-ISO nach data/upstream/tuxflotte-mint-boot-medium.iso hochgeladen,
TUXFLOTTE_MINT_ISO_PATH in provisioning-server.env gesetzt, Dienst neu
gestartet.
2026-09-01 09:50:42 +02:00
admin d179f9c2f5 chore(boot-medium): Phase 4 - alte Ubiquity-Ära-Dateien entfernen, build.sh auf Fedora reduzieren
Entfernt (Historie bleibt ueber Git-Log erhalten, siehe ADR-0025 in
platform-docs fuer die vollstaendige Begruendung/den Gesamtrueckblick):
- backends/mint/ (Ubiquity-Preseed-Backend, backend_launch()-Pfad nicht
  mehr referenziert seit Phase 1, postinstall.sh dort bereits migriert)
- scripts/lib/initrd.sh, initrd-hooks/ (Casper-Bottom-Hook-Injection,
  nur fuer das Patchen einer fremden fertigen Mint-ISO noetig)
- grub/mint-boot-grub.cfg, grub/mint-isolinux-live.cfg
- live-updates/ (Cinnamon-Kiosk, AT-SPI-Autoklicker)

scripts/build.sh (das alte Test-Build-Skript) bedient jetzt nur noch das
Fedora-Backend (Kickstart/Anaconda, unveraendert, ausserhalb dieses
Plans) - Mint-Zweig entfernt (bake_test_preseed(), patch_initrd(),
initrd.sh-Source, mint-spezifische GRUB-Pfade). Die unbedingte
live-updates/-Kopie in prepare_updates() entfiel ebenfalls - sie wurde
fuer Fedora nie inhaltlich gebraucht (Anaconda/Kickstart kennt kein
Cinnamon-Kiosk/keinen AT-SPI-Autoklicker), nur bisher blind mitkopiert.

README.md um einen Abschnitt zum neuen Boot-Medium-Bauweg ergaenzt
(build_boot_medium.sh/build_customer_iso.sh vs. weiterhin
Fedora-spezifisches build.sh).
2026-09-01 09:22:19 +02:00
admin b9ccae6e85 fix(boot-medium): jq/curl/python3 im Zielsystem vor postinstall.sh sicherstellen
Fuenfter und letzter live gefundener Bug auf dem Weg zum ersten
vollstaendig erfolgreichen End-to-End-Deployment: die echte
Mint-Referenz-VM bringt jq nicht mit (anders als das Boot-Medium selbst,
das hilft dem chroot-Zielsystem aber nicht - komplett eigener Kontext).
postinstall.sh scheiterte deshalb an "jq: command not found". curl/python3
gleich mit abgesichert (python3 wird vom heruntergeladenen agent.py nach
dem naechsten Boot gebraucht), um nicht noch einen ganzen
Referenz-VM-Neupack-Zyklus wegen eines weiteren fehlenden Pakets zu
riskieren. apt-get update noetig, da package_golden_image.sh
/var/lib/apt/lists als Teil der Bereinigung leert.

Damit lief der komplette Self-Service-Flow zum ersten Mal vollstaendig
durch: Enrollment-Session -> personalisiertes ISO -> Boot -> Partition/
Format/Mount -> Golden-Image-Stream-Download+Extraktion -> chroot-Fixup
-> Bootloader -> Postinstall/Agent-Bootstrap -> Reboot -> echter
Linux-Mint-Cinnamon-Login-Bildschirm (Hostname "debian", deutsches
Tastaturlayout aktiv). agent_secret_issued_at in der Datenbank bestaetigt
die erfolgreiche Agent-Registrierung bei anode.

Damit sind alle vier Phasen des Boot-Medium-Plans live end-to-end
verifiziert. Voraussetzung dafuer: das golden-image-Archiv auf anode
wurde mit dem korrigierten package_golden_image.sh (vorheriger Commit)
neu gepackt (4,8 GB statt 2,3 GB, jetzt mit den vorher fehlenden
Kernelmodulen) und live ersetzt - alte Version als
linux-mint-22.3-cinnamon.tar.zst.defekt-31.08.bak gesichert.
2026-08-31 18:25:24 +02:00
admin 27d6fa0f47 feat(boot-medium): build_customer_iso.sh ans neue Struktur anpassen (Phase 3) + vier echte Deployment-Bugs behoben
Phase 3: Personalisierung (Aktivierungscode/WLAN) funktioniert jetzt ohne
Xorriso-Extraktion der ganzen ISO / Casper-Hook-Injection. /opt/tuxflotte/
liegt innerhalb von /live/filesystem.squashfs (read-only) - ein direktes
xorriso -update auf eine Datei darin traf live getestet ins Leere.
Stattdessen: Squashfs entpacken (unsquashfs), installer.conf ersetzen, neu
packen (mksquashfs -comp xz, ~1 Minute reine Kompression, kein
debootstrap/apt), als Ganzes per xorriso -update einspielen. Muss als root
laufen (Datei-Eigentuemer im Squashfs sonst falsch).

Beim ersten echten End-to-End-Testlauf mit dem vollen Golden-Image-Archiv
(vorher nie bis zum Ende gekommen - immer am Ubiquity-Bug oder an einem
Commit-Gate gestoppt) vier echte, bisher unentdeckte Bugs gefunden und
behoben:

1. Golden-Image-Download landete in /run/tuxflotte/backend/ (RAM-Tmpfs,
   hier 392 MB) statt auf echtem Speicher - "curl: (23) Failure writing
   output to destination" bei 2,3 GB Archiv, unabhaengig von RAM-Groesse.
   Fix: image_deploy_extract_image_from_url() streamt Download direkt in
   die Extraktion (curl | tar), kein Zwischenspeichern mehr noetig.
   backend_launch() partitioniert/formatiert/mountet jetzt VOR dem
   Download-Versuch statt danach.

2. /etc/resolv.conf im Zielbaum ist bei der echten Referenz-VM ein von
   NetworkManager verwalteter Symlink - "cp" verweigerte das Schreiben
   "through a dangling symlink". Fix: Ziel vor dem Kopieren explizit
   entfernen.

3. mount --bind auf /dev, /proc, /sys schlug fehl, weil diese Verzeichnisse
   nach dem Entpacken gar nicht existierten (package_golden_image.sh
   schliesst sie bewusst aus) - und zwar SILENT, weil das bisherige
   "cmd && stack_ref+=(...)"-Muster einen Fehlschlag unter "set -e" nicht
   als Statement-Fehler wertet. Fiel dadurch erst beim naechsten
   chroot-Aufruf auf ("ssh-keygen -A: Couldn't open /dev/null"), weit weg
   von der eigentlichen Ursache. Fix: neue image_deploy_restore_excluded_dirs()
   legt alle sechs von package_golden_image.sh ausgeschlossenen
   Verzeichnisse (proc/sys/dev/run/tmp/var-tmp) direkt nach der Extraktion
   wieder an; jeder Mount wird jetzt einzeln explizit geprueft statt auf
   &&-Verkettung zu vertrauen.

4. package_golden_image.sh: "--exclude=dev" (ohne "./"-Praefix) matcht bei
   GNU tar gegen JEDEN Verzeichnis-Basisnamen im ganzen Baum, nicht nur
   den Top-Level-Eintrag - hat dadurch auch kernel/drivers/net/can/dev/
   (ein zufaellig gleichnamiger, voellig unverwandter Kernelmodul-Ordner)
   aus dem Archiv gerissen, update-initramfs scheiterte an fehlenden
   can-dev.ko.zst-Abhaengigkeiten. Lokal mit einem Wegwerf-Testbaum
   verifiziert (wie beim "run"-Fund vom selben Tag): "./"-Praefix
   verankert das Muster auf den exakten Top-Level-Pfad, gleichnamige
   verschachtelte Ordner bleiben erhalten. Betrifft das AKTUELL AUF ANODE
   GEHOSTETE Archiv - muss mit dem korrigierten Skript auf der
   Referenz-VM neu gepackt und hochgeladen werden (steht noch aus,
   Nutzer verschlankt die Referenz-VM gerade zusaetzlich).

Live-Fortschritt in der enterprise-QEMU-VM: nach Fix 1-3 kam der
Deployment-Versuch bis kurz vor update-initramfs durch (Partitionierung,
Formatierung, Mounten, Download+Extraktion, chroot-Fixup bis machine-id +
SSH-Hostkeys liefen alle sauber) - Fund 4 (das defekte Archiv) ist der
letzte noch offene Blocker fuer einen vollstaendig erfolgreichen
End-to-End-Durchlauf.
2026-08-31 16:36:35 +02:00
admin 95447f7486 feat(boot-medium): Begrüßungsbanner (Tuxflotte-Schriftzug + Flottengrafik)
80-Spalten-ASCII-Banner (pics/tuxflotte-terminal-80.txt, lose Asset-Datei,
nicht versioniert - pics/ ist kein Git-Repo) wird beim Boot vor
installer.sh angezeigt, sowohl im Dev- als auch im Produktiv-Build.
Schriftzug frisch per figlet (Font "big") erzeugt, passt sauber in 80
Spalten. Grafik-Teil aus der bestehenden 160-Spalten-Vorlage per
Spalten-Verdichtung (2:1) abgeleitet, da die Original-SVG-Logo-Konturen
(reine offene Pfade ohne Fill) bei 80 Spalten direkt aus dem Vektor
konvertiert nur noch vereinzelte Punkte ergeben - live geprueft, siehe
Konversation.

boot-autostart.sh zeigt das Banner nur wenn lesbar (if statt &&, sonst
wuerde ein fehlendes Banner das Skript unter set -e sofort beenden).

Live verifiziert in der enterprise-QEMU-VM: Banner erscheint korrekt vor
[1/12] Vorbereitung, passt vollstaendig in die 80-Spalten-Konsole.
2026-08-31 14:57:09 +02:00
admin bc13169418 feat(boot-medium): systemd-Autostart, Fortschrittsanzeige, SSH-Dev-Modus (Phase 2)
Neuer Service tuxflotte-installer.service startet installer.sh beim Boot
direkt auf tty1 (Type=idle, Conflicts=getty@tty1.service) - kein manuelles
Anmelden/sudo mehr noetig, egal ob Auto-Modus oder interaktiver
Test-/Entwicklungslauf. Wrapper boot-autostart.sh spiegelt die Ausgabe
zusaetzlich nach /var/log/tuxflotte-installer.log.

log_step() (scripts/lib/logging.sh) gibt vor jedem Modul einen klar
abgesetzten "[n/12] <Label>"-Block aus - gilt fuer Dev- UND Produktiv-Build
gleichermassen (die tty-Konsole ist die einzige UI, die eine Person vor
dem Geraet sieht, kein Kiosk-Browser mehr).

scripts/build_boot_medium.sh buendelt lb clean/config/build (loeste die
bisherigen Hand-Aufrufe ab) und steuert per --dev-Flag einen SSH-
Debug-Zugang (tuxflotte/test123) - ohne --dev bleibt SSH deaktiviert,
keine gebackenen Zugangsdaten (Produktiv-Default).

Zwei echte, live gefundene Bugs unterwegs behoben:
- Debians trixie-sshd_config deaktiviert PasswordAuthentication per
  Default - fuer den Dev-Testzugang explizit wieder aktiviert.
- Ein ExecStopPost, der getty@tty1.service nach Dienstende neu startet,
  ist unzuverlaessig (Race mit dem eigenen TTY-Teardown, Job wurde
  angestossen, blieb aber inactive/dead). Geloest durch einen
  deterministischen Fallback in boot-autostart.sh selbst: die Konsole
  faellt nach installer.sh in eine interaktive Shell statt auf einen
  eventuell nie zurueckkehrenden getty zu warten.

Live verifiziert in der enterprise-QEMU-VM (zwei frische Enrollment-
Sessions, echte anode-Aktivierung, "Bekanntes Geraet erkannt"-Pfad):
Boot laeuft ohne jede manuelle Anmeldung direkt in installer.sh, alle
12 Fortschritts-Banner erscheinen korrekt nummeriert, Commit-Gate und
kontrollierter Abbruch funktionieren, SSH-Login mit Passwort
funktioniert, Fallback-Shell nach Programmende reagiert auf Eingaben.
2026-08-31 14:40:39 +02:00
admin 2190d6f403 feat(boot-medium): Tuxflotte-Nutzlast ins Boot-Medium einbauen (Phase 1)
scripts/ (installer.sh, lib/*, modules/00-99) und backends/mint-image/
(inkl. echtem postinstall.sh statt Symlink auf backends/mint/) werden ueber
config/includes.chroot/opt/tuxflotte/ ins Image kopiert - bewusst nur die
zur Laufzeit benoetigten Dateien, nicht die Build-Host-Werkzeuge
(build_customer_iso.sh, build_golden_image.sh, package_golden_image.sh,
lib/initrd.sh etc. bleiben aussen vor).

00_preflight.sh und backend_init() (backends/mint-image/backend.sh)
verlieren ihre Laufzeit-apt-get-Nachinstallation (jq, parted, dosfstools,
e2fsprogs, zstd, btrfs-progs, gettext-base, curl) - alles bereits in
Phase 0 vorinstalliert. Werden durch reine Assertions ersetzt, die frueh
und klar melden, falls die Paketliste doch mal luecken sollte.

backends/mint/postinstall.sh nach backends/mint-image/postinstall.sh als
echte Datei verschoben (war Symlink) - noetig, weil backends/mint/ in
Phase 4 komplett entfernt wird.

Live verifiziert in der enterprise-QEMU-VM: installer.sh von Hand
gestartet, Module 00/05/10/12/15/17 liefen sauber durch, inkl. echtem
Server-Kontakt zu anode und echter Geraeteregistrierung (Liebherr-Org),
Commit-Gate erschien interaktiv wie erwartet, kontrollierter Abbruch ohne
jede destruktive Aktion.
2026-08-31 13:52:38 +02:00
admin ff4f48432e feat(boot-medium): live-build-Grundgerüst für unabhängiges Boot-Medium (Phase 0)
lb config für Debian trixie/amd64, iso-hybrid, GRUB-EFI+syslinux. Paketliste
(tuxflotte.list.chroot) übernimmt die Hardware-/WLAN-Abdeckung aus
build_golden_image.sh, ergänzt um btrfs-progs sowie die bisher erst zur
Laufzeit nachinstallierten Werkzeuge (jq, gettext-base, dosfstools,
e2fsprogs, zstd).

Ersetzt langfristig das Patchen der echten Mint-Live-ISO
(build_customer_iso.sh + Casper-Hook-Injection) - siehe Plan
~/.claude/plans/inherited-floating-treasure.md und Memory
project_independent_boot_medium.md. Auslöser: ein live gefundener Bug, bei
dem statt der direkten Partitionier-Mechanik unerwartet Ubiquity hochkam,
weil das Boot-Medium bislang weiterhin die echte, Ubiquity-tragende
Mint-ISO war.

Noch kein lauffähiges Image - nur das live-build-Grundgerüst, Bau + Boot-
Test folgt.
2026-08-31 12:40:19 +02:00
adminandClaude Sonnet 5 bc9cefa1b8 feat(mint-image): GOLDEN_IMAGE_URL auf echtes Referenz-VM-Archiv umgestellt
Zeigt jetzt auf das aus der Proxmox-Referenz-VM golden-linux-mint
gezogene, bereinigte Archiv (linux-mint-22.3-cinnamon.tar.zst,
2,3 GiB komprimiert), gehostet ueber die neue /golden-images/-Route in
provisioning-server. Live per Public-HTTPS verifiziert (voller
Download, byte-exakte Groesse, Traversal/fehlende Datei korrekt
abgelehnt).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 10:10:11 +02:00
adminandClaude Sonnet 5 86ebea6d66 fix(golden-image): tar --exclude braucht relative Pfade bei -C /
--exclude=/proc (mit fuehrendem Slash) matcht nicht gegen die von
'tar -C / .' erzeugten relativen Elementnamen (./proc/...). Live gegen
die echte Referenz-VM entdeckt: der erste Packlauf haette dadurch
/proc, /sys, /dev, /run, /tmp, /var/tmp real mit eingepackt (u.a.
/proc/kcore) statt sie auszuschliessen. Abgebrochen, Excludes auf
relative Pfade (proc, sys, dev, run, tmp, var/tmp) umgestellt und
lokal mit einem Testverzeichnis verifiziert (inkl. Gegenprobe: ein
'runner/'-Verzeichnis bleibt vom 'run'-Exclude unberuehrt).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 09:38:09 +02:00
adminandClaude Sonnet 5 cb182a058f feat: package_golden_image.sh - Golden Image aus einer echten Referenz-VM ziehen
Ersetzt debootstrap als Hauptweg (siehe ADR-0024-Nachtrag): laeuft direkt
auf einer fertig installierten Referenz-VM (Proxmox), bereinigt
maschinen-/betriebsspezifische Spuren (Testkonto, SSH-Autorisierung,
Root-Passwort, machine-id, SSH-Hostkeys, NetworkManager-Profile,
Caches/Logs) und packt den Dateibaum im selben tar/zstd-Format, das
image_deploy_extract_image() (Phase 1) bereits erwartet.

build_golden_image.sh (debootstrap) bleibt als dokumentierter Fallback
erhalten.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 09:31:03 +02:00
adminandClaude Sonnet 5 72d7a4b27d feat: neues Backend backends/mint-image/ (Golden-Image-Deployment, Phase 2)
Implementiert die von 40_backend.sh erwartete Fuenf-Funktionen-
Lebenszyklus-Schnittstelle (backend_init/validate/generate_config/
launch/postinstall) auf Basis der in Phase 1 isoliert verifizierten
Mechanik in scripts/lib/image_deploy.sh (siehe ADR-0024).

- backend_generate_config() liest dieselben Werte wie das bestehende
  Mint-Backend (Hostname, Device-ID, Device-Fingerprint, Root-Dateisystem,
  Blueprints-JSON), schreibt sie aber als konsolidierte JSON-Datei statt
  eines Preseed/Kickstart-Templates.
- backend_launch() laedt das Golden Image von anode, partitioniert,
  formatiert, entpackt, schreibt fstab, macht chroot-Fixup, installiert
  den Bootloader.
- backend_postinstall() rendert dasselbe postinstall.sh (per Symlink
  geteilt mit backends/mint/, unveraendert wiederverwendet) per envsubst,
  fuehrt es per chroot aus, haengt aus, startet neu.
- backend_validate() beschraenkt sich bewusst auf das einfache
  Partitionierungsschema ('single') - 'custom' mit extra_partitions ist
  noch nicht auf die parted-basierte Mechanik uebertragen, klarer Fehler
  statt stiller Fehlinterpretation.

backends/mint/ bleibt unveraendert als Referenz erhalten - neuer,
eigenstaendiger backend_id ('mint-image'), nichts wird live umgeschaltet.

Noch offen (Phase 3): Golden Image muss noch auf anode bereitgestellt
werden (GOLDEN_IMAGE_URL zeigt bereits dorthin), End-to-End-Test ueber
den echten Self-Service-Flow steht noch aus.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 19:04:15 +02:00
adminandClaude Sonnet 5 8be6ece0d3 feat: Golden Image auf Debian trixie umstellen, WLAN-Abdeckung erweitern
trixie statt bookworm: bookworm ist inzwischen oldstable, trixie liefert
ausserdem von Haus aus einen neueren Kernel - direkt relevant fuers Ziel
'moeglichst breite Hardwareunterstuetzung'. Secure-Boot-Kette
(shim-signed/grub-efi-amd64-signed) funktioniert in beiden Suiten
identisch, kein Unterschied dort.

WLAN-Paketliste erweitert: firmware-brcm80211 (Broadcom, vorher nicht
abgedeckt), wireless-regdb (Regulatory-Datenbank - ohne sie
Kanal-/Sendeleistungs-Einschraenkungen, leicht zu uebersehen),
wpasupplicant explizit (kam vorher nur transitiv mit), iw + rfkill
(Diagnose/Kontrolle).

Noch nicht neu gebaut/getestet - naechster Schritt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 18:45:24 +02:00
adminandClaude Sonnet 5 d35f1d257e fix: zstd -f setzen, damit wiederholte Golden-Image-Baeulaeufe die vorherige Ausgabedatei ueberschreiben
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 23:39:46 +02:00
adminandClaude Sonnet 5 fec208be5f fix: Root-Dateisystem des Golden Image auf 0755 statt 0700 korrigieren
Real beim Testen entdeckt: mktemp -d legt WORK_DIR mit Modus 0700 an -
debootstrap aendert die Rechte des Zielverzeichnisses selbst nicht, tar -p
uebernimmt diesen Modus beim Verpacken/Entpacken 1:1 als Root-Verzeichnis-
Rechte des gesamten ausgerollten Dateisystems. Ergebnis auf der realen
QEMU-Testplatte: dbus-daemon (wechselt intern auf den unprivilegierten
'messagebus'-Benutzer) bekam 'Permission denied' schon beim Traversieren
von '/', was in einer kompletten Boot-Fehlerkaskade endete (dbus, logind,
NetworkManager, wpa_supplicant, ModemManager schlugen alle fehl - kein
Netzwerk, das eigentliche Ziel von Phase 1). Fix: chmod 0755 direkt nach
debootstrap.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 23:36:19 +02:00
adminandClaude Sonnet 5 f57bdea9b1 fix: GRUB zusaetzlich auf EFI-Fallback-Pfad installieren (--removable)
Real beim Testen entdeckt: grub-install konnte im Testkontext keinen
NVRAM-Booteintrag setzen ('EFI variables are not supported on this
system'), ohne --removable blieb dann nur der benannte
/EFI/tuxflotte/-Pfad uebrig, den die Firmware ohne NVRAM-Eintrag nie
findet - Ergebnis: 'No bootable option or device was found' beim
Testboot von der frisch beschriebenen Platte. Fix: zusaetzlicher
grub-install-Lauf mit --removable schreibt auf den Standard-Fallback-Pfad
EFI/BOOT/BOOTX64.EFI, den jede UEFI-Firmware ohne NVRAM-Eintrag
automatisch versucht - robuster generell fuer heterogene Zielhardware,
nicht nur fuer dieses Testszenario.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 22:52:22 +02:00
adminandClaude Sonnet 5 5845e0108a feat: Golden-Image-Deployment als Ersatz fuer Ubiquity-Automatisierung (Phase 0+1)
Neue Richtung nach ADR-0024-Diskussion: statt Distributions-Installer
(Ubiquity/Anaconda) zu automatisieren - strukturell fragil, siehe
ADR-0023-Nachtrag zum partman-rebuild-cache-Loop - wird das
curtin/FAI-Muster genutzt: Zieldatentraeger direkt partitionieren, ein
fertiges Root-Filesystem-Image entpacken, per chroot nacharbeiten.

- build_golden_image.sh: baut eine schlanke Debian-bookworm-Basis per
  debootstrap (Kernel, breites linux-firmware, NetworkManager,
  openssh-server) - KEINE Desktop-Umgebung, die kommt wie jedes andere
  Merkmal per Ansible-Blueprint nach dem ersten Boot (ADR-0002). Keine
  SSH-Hostkeys/kein Root-Passwort im Ergebnis - reale Zugangsdaten
  entstehen erst durch den Provisioning Agent pro Geraet.
- scripts/lib/image_deploy.sh: Kernmechanik als wiederverwendbare
  Funktionsbibliothek (partitionieren, formatieren, mounten, Image
  entpacken, fstab aus echten UUIDs, chroot-Fixup fuer machine-id/SSH-
  Hostkeys/initramfs, Bootloader-Installation UEFI+BIOS).
- scripts/image_deploy_test.sh: isolierter Testtreiber fuer Phase 1,
  ruft dieselben Funktionen auf, die spaeter backends/mint-image/
  backend.sh (Phase 2) nutzen wird.

Golden Image real gebaut und verifiziert (enterprise/LMDE 6, debootstrap
bookworm): 302 MB, Kernel vorhanden, keine SSH-Hostkeys, machine-id leer.
Deployment-Mechanik noch nicht live getestet - naechster Schritt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 22:26:37 +02:00
adminandClaude Sonnet 5 dfb8c2fc72 fix: Status-Text-Suche liest auch das AT-SPI-Text-Interface
Der 'wird ueberprueft'-Text wurde trotz sichtbar auf dem Screenshot nie
gefunden - GtkLabel exponiert seinen Text ueblicherweise nicht ueber
.name/.description (bleiben oft leer), sondern nur ueber das separate
Text-Interface (queryText().getText(0, -1)). _node_text() sammelt jetzt
alle drei Quellen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 18:02:09 +02:00
adminandClaude Sonnet 5 4bf1992eb9 fix: Autoklicker wartet auf Ubiquitys Hintergrundpruefung statt sie zu unterbrechen
Timing-Hypothese fuer den partman-rebuild-cache-Loop: der $bootable{}-Fix
brachte live keine Aenderung (siehe ADR-0023-Nachtrag), was gegen einen
rein rezeptseitigen Fehler spricht. Stattdessen zeigt die 'Etwas
Anderes'-Seite waehrend der Klickphase ein Status-Panel 'Konfiguration
der Installation wird ueberprueft ...' - ein Klick auf 'Jetzt
installieren' WAEHREND dieser Pruefung noch laeuft koennte sie
unterbrechen/neu anstossen statt sie abschliessen zu lassen.

atspi_click.py sucht jetzt vor jedem Klickversuch aktiv nach diesem
sichtbaren Text (find_showing_text(), rollenunabhaengig) und gibt bei
Treffer Exit-Code 3 zurueck, ohne zu klicken. autoclicker.sh behandelt
das als eigenen, nicht als Fehlversuch gezaehlten Zustand.

Noch nicht live verifiziert - naechster Schritt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 17:53:10 +02:00
adminandClaude Sonnet 5 2e68dbea71 fix: Root-Partition auf UEFI nicht mehr zusaetzlich $bootable{ } markieren
Real beim Testen entdeckt: nach einem nachweislich korrekten Klick auf
'Jetzt installieren' (Debug-Log erreichte sogar 'grub-installer/bootdev
seen') sprang der Installer immer wieder zurueck auf dieselbe
Partitionierungsseite - ausgeloest durch die wiederholt gestellte
Debconf-Frage 'ubiquity/partman-rebuild-cache'
(/lib/partman/update.d/99signal_ubiquity), die ubi-partman.py's
rebuild_cache() aufruft.

Vergleich mit der Original-Recipe, aus der unsere ESP-Stanza kopiert
wurde (/usr/lib/partman/recipes-amd64-efi/30atomic): dort traegt NUR die
ESP-Stanza die Boot-Kennzeichnung (method{ efi }), die Root-Partition
bekommt kein zusaetzliches $bootable{ }. Unser Rezept setzte
$bootable{ } bisher unbedingt auf Root, unabhaengig von EFI/BIOS -
moeglicherweise die Ursache der wiederholten Neubewertung durch partman.

Root_extra_flags jetzt bedingt: nur im BIOS-Zweig (wo keine ESP existiert,
die diese Rolle uebernehmen koennte) weiterhin $bootable{ } gesetzt.
Noch nicht live verifiziert - naechster Schritt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 16:57:43 +02:00
adminandClaude Sonnet 5 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
adminandClaude Sonnet 5 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
adminandClaude Sonnet 5 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
adminandClaude Sonnet 5 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
adminandClaude Sonnet 5 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
adminandClaude Sonnet 5 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
adminandClaude Sonnet 5 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
adminandClaude Opus 5 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
admin 18738be01d Merge: Volume-ID-Feature (anderer Session-Strang) + device_fingerprint-Lokalablage zusammenführen 2026-08-28 10:36:19 +02:00
adminandClaude Opus 5 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
adminandClaude Sonnet 5 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
adminandClaude Sonnet 5 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
adminandClaude Sonnet 5 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