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

85 lines
3.8 KiB
Bash
Executable File

#!/usr/bin/env bash
set -Eeuo pipefail
# Baut das Golden Image aus einer bereits fertig installierten
# Referenz-VM (siehe ADR-0024-Nachtrag "Referenz-VM statt debootstrap") -
# laeuft DIREKT AUF der Referenz-VM (als root), anders als
# build_golden_image.sh, das auf einem separaten Build-Host ein
# Basissystem von Grund auf neu baut. Bereinigt zuerst alle maschinen-/
# betriebsspezifischen Spuren, packt danach den verbleibenden Dateibaum
# in genau dem Format, das image_deploy_extract_image()
# (scripts/lib/image_deploy.sh, Phase 1) erwartet - tar/zstd, keine
# Blockgeraete-Kopie.
#
# WICHTIG: entfernt als Teil der Bereinigung auch den bisherigen
# Betriebs-/Testzugang zu dieser Maschine (Testkonto, SSH-Autorisierung,
# Root-Passwort) - das ist beabsichtigt (jede damit ausgerollte
# Kundeninstallation wuerde sonst dieselben, bekannten Zugangsdaten
# tragen), nicht versehentlich. Das Ergebnis-Archiv muss ueber dieselbe,
# bereits authentifizierte Verbindung abgeholt werden, mit der dieses
# Skript gestartet wurde (z.B. per SSH-ControlMaster) - eine NEUE
# Verbindung nach dem Lauf funktioniert nicht mehr. Ein Proxmox-Snapshot
# von VOR diesem Lauf ist die vorgesehene Rueckfallebene fuer kuenftige
# Wartung/Versions-Upgrades der Referenz-VM (siehe Plan).
OUTPUT_FILE="${1:-/root/golden-image.tar.zst}"
if [[ "${EUID}" -ne 0 ]]; then
echo "Fehler: muss als root laufen." >&2
exit 1
fi
echo "==> Entferne Betriebs-/Testzugang (nicht Teil des Kundenimages)"
if id tuxflotte >/dev/null 2>&1; then
userdel -r tuxflotte 2>/dev/null || userdel tuxflotte 2>/dev/null || true
fi
mkdir -p /root/.ssh
: > /root/.ssh/authorized_keys
passwd -l root >/dev/null
echo "==> Entferne maschinenspezifische Identität"
rm -f /etc/ssh/ssh_host_*
: > /etc/machine-id
# Manche Distributionen legen /var/lib/dbus/machine-id als echte Kopie an
# statt als Symlink auf /etc/machine-id (siehe ADR-0024-Fund, 29.08.2026) -
# beide Fälle abdecken, ein Symlink zeigt ohnehin automatisch auf die
# gerade geleerte Datei.
if [[ -e /var/lib/dbus/machine-id && ! -L /var/lib/dbus/machine-id ]]; then
: > /var/lib/dbus/machine-id
fi
echo "==> Entferne Netzwerk-Zugangsdaten der Referenz-VM"
rm -f /etc/NetworkManager/system-connections/*
echo "==> Bereinige Caches/Logs/temporäre Dateien"
apt-get clean
rm -rf /var/lib/apt/lists/*
find /var/log -type f -exec truncate -s0 {} \;
rm -rf /tmp/* /var/tmp/*
rm -f /root/.bash_history
rm -f /home/*/.bash_history 2>/dev/null || true
# Paketauswahl eindampfen (Browser, Office-Pakete o.Ä.) bewusst NICHT im
# ersten Lauf - siehe Plan ("erster Durchlauf zeigt, wie groß das Archiv
# real wird, dann gezielt nachschärfen"). Blindes Purgen ohne die
# tatsächliche Paketliste gesehen zu haben, riskiert eher kaputte
# Abhängigkeiten als sinnvolle Einsparung. Nach diesem Lauf:
# `dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -rn | head -30`
# auf der Referenz-VM zeigt die groessten Kandidaten fuer einen gezielten
# zweiten Durchlauf.
echo "==> Packe nach ${OUTPUT_FILE}"
# WICHTIG: tar -C / erzeugt relative Elementnamen (./proc/..., ./sys/...),
# nicht absolute (/proc/...) - ein --exclude mit fuehrendem Slash matcht
# dagegen NICHT (live am 31.08.2026 entdeckt: das lief zunaechst
# unbemerkt gegen die echte Referenz-VM und haette u.a. /proc/kcore mit
# eingepackt). Ausschluesse deshalb ohne fuehrenden Slash angeben.
tar --numeric-owner --xattrs \
--exclude=proc --exclude=sys --exclude=dev \
--exclude=run --exclude=tmp --exclude=var/tmp \
--exclude="${OUTPUT_FILE#/}" \
-C / -cf - . | zstd -f -T0 -19 -o "${OUTPUT_FILE}"
echo "==> Fertig: ${OUTPUT_FILE} ($(du -h "${OUTPUT_FILE}" | cut -f1))"
echo "==> Root-Zugang zu dieser Maschine ist jetzt gesperrt (Testkonto entfernt, SSH-Autorisierung geleert, Root-Passwort gesperrt) - Proxmox-Snapshot ist die Rueckfallebene fuer kuenftige Laeufe."