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
This commit is contained in:
1 parent
7c52e5fb90
commit
8196166c90
1 file changed
+147
-8
@@ -68,6 +68,21 @@ mkdir -p "${STAGING_BASE_DIR}"
|
||||
STAGING_DIR="$(mktemp -d -p "${STAGING_BASE_DIR}")"
|
||||
|
||||
cleanup() {
|
||||
# Schutzmassnahme nach dem Mount-Incident vom 11.09.2026 (siehe
|
||||
# unmount_chroot_binds() weiter unten): "rm -rf" darf NIEMALS gegen
|
||||
# einen Pfad laufen, unter dem noch ein Bind-/devpts-Mount haengt - genau
|
||||
# das ist damals passiert (ein manueller Lazy-Unmount war noch nicht
|
||||
# fertig, als "rm -rf" schon lief) und hat dabei echte Geraetedateien
|
||||
# (u.a. /dev/null) auf dem Build-Host geloescht. Deshalb hier
|
||||
# UNABHAENGIG von unmount_chroot_binds() ein zweites, autoritatives
|
||||
# Nachpruefen: nur loeschen, wenn WIRKLICH nichts mehr eingehaengt ist.
|
||||
local mnt
|
||||
for mnt in "${STAGING_DIR}/dev/pts" "${STAGING_DIR}/dev" "${STAGING_DIR}/sys" "${STAGING_DIR}/proc"; do
|
||||
if mountpoint -q "${mnt}" 2>/dev/null; then
|
||||
echo "FEHLER: ${mnt} ist noch eingehaengt - rm -rf auf ${STAGING_DIR} wird NICHT ausgefuehrt. Manuell aushaengen (umount ${mnt}) und ${STAGING_DIR} danach von Hand loeschen." >&2
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
chmod -R u+w "${STAGING_DIR}" 2>/dev/null || true
|
||||
rm -rf "${STAGING_DIR}"
|
||||
}
|
||||
@@ -141,14 +156,138 @@ rm -rf "${STAGING_DIR}"/tmp/* "${STAGING_DIR}"/var/tmp/*
|
||||
rm -f "${STAGING_DIR}/root/.bash_history"
|
||||
rm -f "${STAGING_DIR}"/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:
|
||||
# `chroot "${STAGING_DIR}" dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -rn | head -30`
|
||||
# auf der Staging-Kopie zeigt die groessten Kandidaten fuer einen gezielten
|
||||
# zweiten Durchlauf.
|
||||
# Paketauswahl eindampfen (11.09.2026, zweiter Durchlauf nach dem oben
|
||||
# beschriebenen ersten Lauf - echte Groessenanalyse auf golden-linux-mint/103
|
||||
# per `dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -rn`, jeder
|
||||
# Kandidat einzeln per `apt-cache rdepends --installed` gegen versteckte
|
||||
# Abhaengigkeiten geprueft, nicht blind uebernommen):
|
||||
# - ansible: eigenes Provisionierungswerkzeug, Testueberbleibsel auf der
|
||||
# Referenz-VM - gehoert nie auf ein Kundengeraet.
|
||||
# - gcc-13/g++-13/cpp-13 + linux-headers-*/linux-hwe-*-headers-*: kein
|
||||
# lokales Entwickeln vorgesehen ([[project_no_local_install_capability]],
|
||||
# ADR-0026), `dkms status` auf der Referenz-VM leer - kein Kernel-Modul
|
||||
# braucht sie zum Neubauen.
|
||||
# - mint-l-icons/yaru-theme-icon/mint-l-theme: ungenutzte Alternativ-Themes
|
||||
# - NICHT in der Inherits-Kette des aktiven Icon-Themes (Mint-Y-Sand ->
|
||||
# Mint-Y,Adwaita,gnome,hicolor) und nicht das aktive GTK-Theme
|
||||
# (Mint-Y-Aqua, liefert mint-themes - bleibt). mint-x-icons war
|
||||
# URSPRUENGLICH auch auf der Liste, aber nach echtem Testlauf (11.09.2026)
|
||||
# WIEDER RAUSGENOMMEN: einziger Trigger einer eigenen Kaskade
|
||||
# (mint-meta-cinnamon/mint-meta-core/mint-artwork/mint-themes selbst!) -
|
||||
# vermutlich ueber folder-color-switcher, das Mint-X-Ordnerfarbvarianten
|
||||
# braucht. Bisektion (jedes Paket einzeln simuliert) hat das eindeutig
|
||||
# auf mint-x-icons zurueckgefuehrt, die anderen drei sind einzeln UND
|
||||
# zusammen sauber.
|
||||
# - mintinstall + app-install-data: URSPRUENGLICH auf der Liste (ADR-0026 -
|
||||
# kein sudo/pkexec fuer den interaktiven Nutzer, damit funktionslos), aber
|
||||
# nach echtem Testlauf (11.09.2026) WIEDER RAUSGENOMMEN: mintinstall
|
||||
# haengt an mint-meta-core/mint-meta-cinnamon, deren Entfernung eine
|
||||
# Kaskade aus (apt autoremove reisst alles mit, was NUR ueber dieses
|
||||
# Meta-Paket als "automatisch installiert" markiert war) - hat im
|
||||
# Testlauf mint-themes (!), mint-artwork, xorg und lightdm-settings mit
|
||||
# zur Entfernung markiert. Das Risiko (kaputter Desktop) steht in keinem
|
||||
# Verhaeltnis zur Ersparnis (~45MB) - bewusst NICHT entfernt.
|
||||
# - libreoffice* + mythes-*: der Katalog installiert LibreOffice separat per
|
||||
# Flatpak (roles/libreoffice in ansible-content) - die apt-Variante hier
|
||||
# ist reine Redundanz.
|
||||
# - kolibri: der Katalog installiert es identisch per apt (roles/kolibri) -
|
||||
# ebenfalls redundant.
|
||||
#
|
||||
# NICHT entfernt (geprueft, echte Abhaengigkeiten): mint-cursor-themes (liefert
|
||||
# das aktive Cursor-Theme Bibata-Modern-Classic), mint-y-icons/mint-themes
|
||||
# (aktive Themes), mint-x-icons (siehe oben), libwebkit2gtk*/libwebkitgtk*
|
||||
# (braucht yelp/Xreader), mesa-vulkan-drivers (Xorg-Basis).
|
||||
#
|
||||
# Nebeneffekt der gcc-Entfernung, bewusst akzeptiert (11.09.2026 geprueft):
|
||||
# das "xorg"-META-Paket (SDK/Bundle, NICHT der laufende X-Server selbst -
|
||||
# xserver-xorg-core haengt unabhaengig an den echten Treiber-Paketen) geht
|
||||
# ueber dpkg-dev->build-essential->gcc mit, dabei auch x11-xserver-utils
|
||||
# (xrandr/xset & Co.) und lightdm-settings (GUI-Konfig fuer den Login-
|
||||
# Manager) - im eigenen Code (ansible-content/provisioning-server) nirgends
|
||||
# referenziert, unproblematisch.
|
||||
#
|
||||
# Bewusst als PATTERN-LISTE + dpkg-query-Auflösung statt direkt an
|
||||
# `apt-get purge` durchgereicht - macht explizit sichtbar/loggbar, welche
|
||||
# tatsaechlichen Paketnamen getroffen werden, statt sich auf apt-eigenes
|
||||
# Wildcard-Matching zu verlassen. Patterns, die auf dieser Distro nichts
|
||||
# treffen (z.B. "mintinstall" auf Debian/Ubuntu), werden einfach
|
||||
# uebersprungen - kein Fehler.
|
||||
#
|
||||
# `apt-get purge`/`autoremove` brauchen ein funktionierendes /proc im
|
||||
# chroot (u.a. fuer update-initramfs/Trigger-Skripte) - deshalb kurz
|
||||
# bind-mounten, aber VOR jedem Skript-Ende (auch bei Fehlern) wieder
|
||||
# aushaengen, sonst wuerde der cleanup()-Trap (`rm -rf STAGING_DIR`) gegen
|
||||
# das ECHTE /proc/etc. des Build-Hosts durchschlagen.
|
||||
TRIM_PATTERNS=(
|
||||
ansible
|
||||
gcc-13-x86-64-linux-gnu g++-13-x86-64-linux-gnu cpp-13-x86-64-linux-gnu
|
||||
'linux-headers-*' 'linux-hwe-*-headers-*'
|
||||
mint-l-icons yaru-theme-icon mint-l-theme
|
||||
'libreoffice*' mythes-de mythes-en-us
|
||||
kolibri
|
||||
)
|
||||
|
||||
mkdir -p "${STAGING_DIR}/proc" "${STAGING_DIR}/sys" "${STAGING_DIR}/dev" "${STAGING_DIR}/dev/pts"
|
||||
mount --bind /proc "${STAGING_DIR}/proc"
|
||||
mount --bind /sys "${STAGING_DIR}/sys"
|
||||
# NICHT --rbind fuer /dev (Bugfix 12.09.2026, nach dem Incident vom
|
||||
# 11.09.2026 - siehe unmount_chroot_binds() unten): --rbind ist rekursiv und
|
||||
# haette /dev/pts der STAGING_DIR 1:1 an dieselbe devpts-INSTANZ gebunden,
|
||||
# die auch das eigene Terminal dieses Skripts nutzt. Damit ist der
|
||||
# Sub-Mount beim Aufraeumen "busy" (normaler umount schlaegt fehl), was
|
||||
# beim Incident zu einem manuellen Lazy-Unmount (umount -l) verleitet hat -
|
||||
# der dann noch lief, als bereits "rm -rf" auf die STAGING_DIR losging, und
|
||||
# dabei ECHTE Geraetedateien (u.a. /dev/null) auf dem Build-Host geloescht
|
||||
# hat. Stattdessen: normaler (nicht-rekursiver) --bind fuer /dev selbst
|
||||
# (bringt alle Geraetedateien mit, u.a. /dev/null/zero/ptmx), plus eine
|
||||
# FRISCHE, eigenstaendige devpts-Instanz NUR fuer dev/pts - dpkg/apt
|
||||
# brauchen die zum Oeffnen eines Pseudo-Terminals ("posix_openpt"), aber sie
|
||||
# teilt sich dann nichts mehr mit dem Host-Terminal und laesst sich darum
|
||||
# immer sauber mit einem normalen (nicht-lazy) umount aushaengen.
|
||||
mount --bind /dev "${STAGING_DIR}/dev"
|
||||
mount -t devpts devpts "${STAGING_DIR}/dev/pts"
|
||||
unmount_chroot_binds() {
|
||||
# Zweiter Teil des Bugfixes vom 12.09.2026: kein Lazy-Unmount (umount
|
||||
# -l/-R) mehr an irgendeiner Stelle - das war der eigentliche Ausloeser
|
||||
# des Incidents (rm -rf lief los, bevor der Lazy-Unmount fertig war).
|
||||
# Stattdessen ein normaler umount mit begrenztem Retry, und danach eine
|
||||
# ECHTE Verifikation per mountpoint -q statt stillschweigend
|
||||
# weiterzumachen. dev/pts zuerst (Blattmount), erst danach dev selbst -
|
||||
# sonst waere dev noch "busy" durch die eigene devpts-Einhaengung
|
||||
# darunter. sys/proc sind voneinander unabhaengig.
|
||||
local mnt tries
|
||||
for mnt in "${STAGING_DIR}/dev/pts" "${STAGING_DIR}/dev" "${STAGING_DIR}/sys" "${STAGING_DIR}/proc"; do
|
||||
tries=0
|
||||
while mountpoint -q "${mnt}" 2>/dev/null && [[ "${tries}" -lt 10 ]]; do
|
||||
umount "${mnt}" 2>/dev/null || true
|
||||
tries=$((tries + 1))
|
||||
mountpoint -q "${mnt}" 2>/dev/null && sleep 0.5
|
||||
done
|
||||
if mountpoint -q "${mnt}" 2>/dev/null; then
|
||||
echo "WARNUNG: ${mnt} laesst sich nach ${tries} Versuchen nicht aushaengen - bleibt eingehaengt (bewusst KEIN Lazy-Unmount hier, siehe Incident 11.09.2026). cleanup() weigert sich weiter unten, die STAGING_DIR zu loeschen, solange das so bleibt - manuelle Nachschau noetig." >&2
|
||||
fi
|
||||
done
|
||||
}
|
||||
trap 'unmount_chroot_binds; cleanup' EXIT
|
||||
|
||||
mapfile -t TRIM_PACKAGES < <(
|
||||
for pattern in "${TRIM_PATTERNS[@]}"; do
|
||||
chroot "${STAGING_DIR}" dpkg-query -Wf '${Package}\n' "${pattern}" 2>/dev/null || true
|
||||
done | sort -u
|
||||
)
|
||||
|
||||
if [[ "${#TRIM_PACKAGES[@]}" -gt 0 ]]; then
|
||||
echo "==> Entferne redundante/unnötige Basis-Pakete: ${TRIM_PACKAGES[*]}"
|
||||
chroot "${STAGING_DIR}" env DEBIAN_FRONTEND=noninteractive \
|
||||
apt-get purge -y "${TRIM_PACKAGES[@]}"
|
||||
chroot "${STAGING_DIR}" env DEBIAN_FRONTEND=noninteractive apt-get autoremove -y
|
||||
chroot "${STAGING_DIR}" apt-get clean
|
||||
else
|
||||
echo "==> Keines der Trimming-Pakete auf dieser Referenz-VM gefunden, nichts zu tun."
|
||||
fi
|
||||
|
||||
unmount_chroot_binds
|
||||
trap cleanup EXIT
|
||||
|
||||
echo "==> Packe nach ${OUTPUT_FILE}"
|
||||
# WICHTIG: tar -C STAGING_DIR erzeugt relative Elementnamen (./proc/...,
|
||||
|
||||
Reference in new issue
Block a user