tuxflotte-installer/scripts/build_customer_iso.sh
Thomas Stallinger 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

116 lines
4.3 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] [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}"
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 "${VOLID}" \
-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}"