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>
110 lines
4.0 KiB
Bash
Executable File
110 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Baut eine personalisierte Kunden-ISO fuer den Self-Service-Flow (Phase 4).
|
|
# Anders als build.sh (das fuer Testzwecke einen statischen Preseed mit
|
|
# Fake-Geraete-ID einbrennt, siehe bake_test_preseed()) wird hier nur
|
|
# config/installer.conf mit den echten, organisationsspezifischen Werten
|
|
# befuellt - Hostname/Geraete-ID/Partitionierung werden weiterhin erst live
|
|
# auf dem Zielgeraet erzeugt (siehe backend_generate_config() in
|
|
# backends/mint/backend.sh). Hier geht es nur um WLAN-Zugangsdaten +
|
|
# Enrollment-Session-Code als Boot-Konfiguration, die start-kiosk.sh dazu
|
|
# bringt, den Installer beim Hochfahren automatisch zu starten statt der
|
|
# interaktiven Kiosk-Startseite.
|
|
|
|
usage() {
|
|
echo "Usage: $0 <source.iso> <output.iso> <activation_code> [wifi_ssid] [wifi_psk]" >&2
|
|
}
|
|
|
|
SOURCE_ISO="${1:-}"
|
|
OUTPUT_ISO="${2:-}"
|
|
ACTIVATION_CODE="${3:-}"
|
|
WIFI_SSID="${4:-}"
|
|
WIFI_PSK="${5:-}"
|
|
|
|
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
WORK_DIR="$(mktemp -d)"
|
|
|
|
# shellcheck source=lib/initrd.sh
|
|
source "$REPO_DIR/scripts/lib/initrd.sh"
|
|
|
|
cleanup() {
|
|
# xorriso extrahiert Verzeichnisse teils mit den Original-ISO-Rechten
|
|
# (z.B. 555, kein 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
|
|
|
|
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; }
|
|
|
|
for cmd in xorriso cpio; do
|
|
command -v "${cmd}" >/dev/null 2>&1 ||
|
|
{ echo "Error: fehlendes Werkzeug: ${cmd}" >&2; exit 1; }
|
|
done
|
|
|
|
echo "Extrahiere Quell-ISO..."
|
|
xorriso -indev "${SOURCE_ISO}" -osirrox on -extract / "${WORK_DIR}" >/dev/null
|
|
# xorriso uebernimmt die Original-ISO-Rechte (haeufig 555 auf
|
|
# Verzeichnissen, 444 auf Dateien) - ohne Write-Bit koennen weder
|
|
# spaetere Schritte noch der Cleanup-Trap Dateien darin ersetzen/entfernen.
|
|
chmod -R u+w "${WORK_DIR}"
|
|
|
|
echo "Installiere Tuxflotte-GRUB-Konfiguration..."
|
|
# -f: xorriso extrahiert ISO-Dateien mit deren Original-Rechten, die auf
|
|
# Live-Medien haeufig read-only (444) sind - ohne -f schlaegt cp beim
|
|
# Ueberschreiben mit "Keine Berechtigung" fehl.
|
|
cp -f "${REPO_DIR}/grub/mint-boot-grub.cfg" "${WORK_DIR}/boot/grub/grub.cfg"
|
|
cp -f "${REPO_DIR}/grub/mint-isolinux-live.cfg" "${WORK_DIR}/isolinux/live.cfg"
|
|
|
|
grep -q "Tuxflotte" "${WORK_DIR}/boot/grub/grub.cfg"
|
|
grep -q "Tuxflotte" "${WORK_DIR}/isolinux/live.cfg"
|
|
|
|
echo "Baue personalisierte Boot-Konfiguration..."
|
|
updates_dir="${WORK_DIR}/updates"
|
|
rm -rf "${updates_dir}"
|
|
mkdir -p "${updates_dir}"
|
|
cp -a "${REPO_DIR}/live-updates/." "${updates_dir}/"
|
|
cp -a "${REPO_DIR}/scripts" "${updates_dir}/opt/tuxflotte/"
|
|
cp -a "${REPO_DIR}/backends" "${updates_dir}/opt/tuxflotte/"
|
|
mkdir -p "${updates_dir}/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}"
|
|
} >"${updates_dir}/opt/tuxflotte/config/installer.conf"
|
|
|
|
chmod 0440 "${updates_dir}/etc/sudoers.d/90-tuxflotte"
|
|
|
|
echo "Injiziere casper-bottom Updates-Hook in die Initrd..."
|
|
custom_initrd="${WORK_DIR}/casper/initrd-tuxflotte.lz"
|
|
inject_casper_bottom_hooks "${REPO_DIR}" \
|
|
"${WORK_DIR}/casper/initrd.lz" \
|
|
"${custom_initrd}"
|
|
|
|
echo "Erzeuge Kunden-ISO..."
|
|
rm -f "${OUTPUT_ISO}"
|
|
|
|
xorriso \
|
|
-indev "${SOURCE_ISO}" \
|
|
-outdev "${OUTPUT_ISO}" \
|
|
-compliance no_emul_toc \
|
|
-volid TUXFLOTTE \
|
|
-map "${REPO_DIR}/grub/mint-boot-grub.cfg" /boot/grub/grub.cfg \
|
|
-map "${REPO_DIR}/grub/mint-isolinux-live.cfg" /isolinux/live.cfg \
|
|
-map "${custom_initrd}" /casper/initrd.lz \
|
|
-map "${updates_dir}" /updates \
|
|
-chown_r 0 /updates -- \
|
|
-chgrp_r 0 /updates -- \
|
|
-boot_image any replay
|
|
|
|
echo "Kunden-ISO erstellt: ${OUTPUT_ISO}"
|