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.
129 lines
5.7 KiB
Bash
Executable File
129 lines
5.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Personalisiert das eigenstaendige Boot-Medium (scripts/build_boot_medium.sh)
|
|
# fuer eine bestimmte Kundenorganisation - befuellt config/installer.conf mit
|
|
# Aktivierungscode + WLAN-Zugangsdaten. Hostname/Geraete-ID/Partitionierung
|
|
# werden weiterhin erst live auf dem Zielgeraet erzeugt (siehe
|
|
# backend_generate_config() in backends/mint-image/backend.sh).
|
|
#
|
|
# Anders als das alte, Casper-basierte Verfahren (Xorriso-Extraktion der
|
|
# ganzen ISO + Initrd-Hook-Injection, siehe scripts/lib/initrd.sh) kann hier
|
|
# NICHT einfach eine einzelne Datei direkt auf der ISO9660-Ebene ersetzt
|
|
# werden: /opt/tuxflotte/ liegt innerhalb von /live/filesystem.squashfs
|
|
# (read-only, von live-boot gemountet). Ein direktes
|
|
# `xorriso -update datei /opt/tuxflotte/config/installer.conf` traf live
|
|
# getestet ins Leere - das gebootete System sah weiterhin die leere
|
|
# Platzhalter-Konfiguration aus dem Basis-Image, weil dieser Pfad ausserhalb
|
|
# des Squashfs liegt und live-boot ihn nie liest (31.08.2026, live in der
|
|
# enterprise-QEMU-VM gefunden: Aktivierungscode-Prompt erschien trotz
|
|
# TUXFLOTTE_AUTO_MODE=true in der vermeintlich aktualisierten ISO).
|
|
#
|
|
# Stattdessen: das Squashfs wird entpackt, installer.conf darin ersetzt, neu
|
|
# gepackt (mksquashfs -no-progress braucht dafuer nur reine Kompressionszeit,
|
|
# ~1 Minute - kein debootstrap/apt, kein Netzwerk) und als Ganzes per
|
|
# `xorriso -update` ins Ziel-ISO eingespielt (Boot-Sektoren/GRUB-Branding
|
|
# bleiben unangetastet, stecken schon im Basis-Image aus
|
|
# scripts/build_boot_medium.sh). mksquashfs kann ein bestehendes Squashfs
|
|
# zwar inkrementell erweitern, aber NICHT bereits vorhandene Dateien
|
|
# ueberschreiben (live getestet: identischer Dateiinhalt trotz
|
|
# augenscheinlich erfolgreichem Lauf) - deshalb der volle
|
|
# unsquashfs/mksquashfs-Zyklus statt eines inkrementellen Appends.
|
|
|
|
usage() {
|
|
echo "Usage: $0 <source.iso> <output.iso> <activation_code> [wifi_ssid] [wifi_psk] [volid]" >&2
|
|
}
|
|
|
|
SOURCE_ISO="${1:-}"
|
|
OUTPUT_ISO="${2:-}"
|
|
ACTIVATION_CODE="${3:-}"
|
|
WIFI_SSID="${4:-}"
|
|
WIFI_PSK="${5:-}"
|
|
# Vom Aufrufer (provisioning-server, compute_iso_volid()) bereits
|
|
# ISO9660-konform aufbereitet (Grossbuchstaben/Ziffern/Unterstrich, <=32
|
|
# Zeichen) - dieses Skript validiert/sanitisiert das bewusst nicht nochmal,
|
|
# um die Sanitisierungslogik nicht doppelt zu pflegen. Fallback nur fuer
|
|
# Aufrufe ohne sechsten Parameter (z.B. manuelle Tests).
|
|
VOLID="${6:-TUXFLOTTE}"
|
|
|
|
if [[ -z "${SOURCE_ISO}" || -z "${OUTPUT_ISO}" || -z "${ACTIVATION_CODE}" ]]; then
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
[[ -f "${SOURCE_ISO}" ]] ||
|
|
{ echo "Error: Quell-ISO nicht gefunden: ${SOURCE_ISO}" >&2; exit 1; }
|
|
|
|
if [[ "${EUID}" -ne 0 ]]; then
|
|
echo "Error: muss als root laufen (unsquashfs/mksquashfs brauchen root, um" >&2
|
|
echo " Datei-Eigentuemer im Squashfs korrekt zu erhalten - ohne root" >&2
|
|
echo " gehen z.B. root:shadow-Zuordnungen verloren, live gefunden)." >&2
|
|
exit 1
|
|
fi
|
|
|
|
for cmd in xorriso unsquashfs mksquashfs; do
|
|
command -v "${cmd}" >/dev/null 2>&1 ||
|
|
{ echo "Error: fehlendes Werkzeug: ${cmd}" >&2; exit 1; }
|
|
done
|
|
|
|
WORK_DIR="$(mktemp -d)"
|
|
|
|
cleanup() {
|
|
# unsquashfs uebernimmt Original-Rechte (teils ohne Write-Bit) - ohne
|
|
# chmod schlaegt rm -rf darauf fehl.
|
|
chmod -R u+w "${WORK_DIR}" 2>/dev/null || true
|
|
rm -rf "${WORK_DIR}"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
echo "Extrahiere Squashfs aus Quell-ISO..."
|
|
xorriso -indev "${SOURCE_ISO}" -osirrox on -extract /live/filesystem.squashfs \
|
|
"${WORK_DIR}/orig.squashfs" >/dev/null
|
|
|
|
echo "Entpacke Squashfs..."
|
|
# "-excludes ... dev" schliesst /dev von der Extraktion aus - live auf anode
|
|
# gefunden (01.09.2026): anode laeuft in einem LXC-Container, der CAP_MKNOD
|
|
# grundsaetzlich blockiert (auch fuer root) - unsquashfs scheiterte beim
|
|
# Wiederherstellen der paar Geraetedateien im Boot-Medium-Squashfs
|
|
# (/dev/null, /dev/console, ...) mit "Operation not permitted".
|
|
unsquashfs -excludes -d "${WORK_DIR}/root" "${WORK_DIR}/orig.squashfs" dev ||
|
|
{ echo "Error: Squashfs konnte nicht entpackt werden." >&2; exit 1; }
|
|
|
|
# ECHTER BUG, live auf echter Hardware gefunden (01.09.2026, direkt nach dem
|
|
# vorigen Fix): "-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. Anders als beim Golden Image (siehe
|
|
# package_golden_image.sh/image_deploy_restore_excluded_dirs(), wo dasselbe
|
|
# Muster schon einmal gefunden wurde) reicht hier ein leeres Verzeichnis -
|
|
# devtmpfs bindet sich selbst darueber, die eigentlichen Geraetedateien
|
|
# werden nie aus dem Squashfs gebraucht.
|
|
mkdir -p "${WORK_DIR}/root/dev"
|
|
|
|
echo "Schreibe personalisierte installer.conf..."
|
|
mkdir -p "${WORK_DIR}/root/opt/tuxflotte/config"
|
|
{
|
|
echo "export TUXFLOTTE_AUTO_MODE=true"
|
|
printf 'export TUXFLOTTE_ACTIVATION_CODE=%q\n' "${ACTIVATION_CODE}"
|
|
[[ -n "${WIFI_SSID}" ]] && printf 'export TUXFLOTTE_WIFI_SSID=%q\n' "${WIFI_SSID}"
|
|
[[ -n "${WIFI_PSK}" ]] && printf 'export TUXFLOTTE_WIFI_PSK=%q\n' "${WIFI_PSK}"
|
|
} >"${WORK_DIR}/root/opt/tuxflotte/config/installer.conf"
|
|
|
|
echo "Packe Squashfs neu (nur Kompression, kein apt/debootstrap)..."
|
|
mksquashfs "${WORK_DIR}/root" "${WORK_DIR}/new.squashfs" -comp xz -no-progress >/dev/null
|
|
chmod 444 "${WORK_DIR}/new.squashfs"
|
|
|
|
echo "Erzeuge Kunden-ISO..."
|
|
rm -f "${OUTPUT_ISO}"
|
|
|
|
xorriso \
|
|
-indev "${SOURCE_ISO}" \
|
|
-outdev "${OUTPUT_ISO}" \
|
|
-volid "${VOLID}" \
|
|
-update "${WORK_DIR}/new.squashfs" /live/filesystem.squashfs \
|
|
-boot_image any replay
|
|
|
|
echo "Kunden-ISO erstellt: ${OUTPUT_ISO}"
|