Fix: image_deploy.sh Boot-Medium-Kopie nicht mit Phase-3-Aenderungen synchronisiert
Live in QEMU gefunden (19.09.2026, erster Testlauf der neuen Lokal-Test-ISO
mit custom-Partitionierung): "image_deploy_partition_custom: command not
found" - die Custom-Partitionierungsfunktionen (Commit 020aa66) wurden nur
in scripts/lib/image_deploy.sh ergaenzt, die zweite, tatsaechlich ins
Boot-Medium gepackte Kopie unter boot-medium/config/includes.chroot/...
blieb auf dem Phase-1/2-Stand stehen. Genau die Sync-Falle, die im Roadmap-
Dokument als Risiko benannt wurde.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
This commit is contained in:
1 parent
020aa66bfa
commit
25f6987948
1 file changed
+156
@@ -145,6 +145,145 @@ image_deploy_partition() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Partitionierung fuer scheme:"custom" (Bereitstellungsvorlage.partitioning,
|
||||
# siehe platform-docs/roadmap/e2e-testrunde-lokale-adressierung.md Phase 3):
|
||||
# ESP/biosgrub wie image_deploy_partition(), danach je einen "extra
|
||||
# partition"-Eintrag aus extra_partitions_json (kompaktes JSON-Array
|
||||
# [{"mountpoint":"/home","percent":20,"filesystem":"ext4"}, ...]), Root
|
||||
# nimmt den verbleibenden Rest. Prozentangaben sind bewusst Anteile der
|
||||
# GESAMTEN Platte (nicht des nach ESP verbleibenden Rests) - "20% fuer
|
||||
# /home" bedeutet 20% der Plattengroesse, parted interpretiert "X%" in
|
||||
# mkpart ohnehin relativ zur Gesamtgroesse des Datentraegers, nicht zum
|
||||
# vorherigen Partitionsende. Eigene Funktion statt Erweiterung von
|
||||
# image_deploy_partition() - komplett andere Partitionsanzahl/-logik,
|
||||
# und das bestehende (viel genutzte) single-Schema soll dadurch keinerlei
|
||||
# Verhaltensaenderung/Risiko erfahren.
|
||||
#
|
||||
# Gibt ein JSON-Objekt auf stdout aus:
|
||||
# {"boot_part": "...", "root_part": "...",
|
||||
# "extra_partitions": [{"mountpoint": "/home", "device": "...", "filesystem": "ext4"}, ...]}
|
||||
image_deploy_partition_custom() {
|
||||
local disk="$1"
|
||||
local is_efi="$2"
|
||||
local extra_partitions_json="$3"
|
||||
|
||||
_image_deploy_release_disk "${disk}"
|
||||
|
||||
if ! parted --script "${disk}" mklabel gpt; then
|
||||
image_deploy_log "parted meldete einen Fehler beim Anlegen der Partitionstabelle auf ${disk} (haeufig: eine alte Partition war noch belegt) - pruefe, ob der Kernel die neue Tabelle trotzdem uebernimmt."
|
||||
fi
|
||||
|
||||
_image_deploy_settle_partitions "${disk}" ||
|
||||
{ image_deploy_fatal "Kernel konnte die neue Partitionstabelle auf ${disk} auch nach mehreren Versuchen nicht uebernehmen."; return 1; }
|
||||
|
||||
parted --script "${disk}" print 2>/dev/null | grep -q "Partition Table: gpt" ||
|
||||
{ image_deploy_fatal "Nach dem Partitionieren liegt kein gueltiges GPT-Label auf ${disk} vor."; return 1; }
|
||||
|
||||
local part_num=1 cursor boot_part=""
|
||||
if [[ "${is_efi}" == "true" ]]; then
|
||||
parted --script "${disk}" mkpart ESP fat32 1MiB 513MiB &&
|
||||
parted --script "${disk}" set 1 esp on ||
|
||||
{ image_deploy_fatal "ESP-Partitionierung fehlgeschlagen auf ${disk}"; return 1; }
|
||||
boot_part="$(image_deploy_partition_path "${disk}" 1)"
|
||||
cursor="513MiB"
|
||||
else
|
||||
parted --script "${disk}" mkpart biosgrub 1MiB 2MiB &&
|
||||
parted --script "${disk}" set 1 bios_grub on ||
|
||||
{ image_deploy_fatal "biosgrub-Partitionierung fehlgeschlagen auf ${disk}"; return 1; }
|
||||
cursor="2MiB"
|
||||
fi
|
||||
|
||||
local extra_partitions_result="[]"
|
||||
local mountpoint percent filesystem name cumulative_percent=0 device entry
|
||||
while IFS= read -r entry; do
|
||||
[[ -n "${entry}" ]] || continue
|
||||
part_num=$((part_num + 1))
|
||||
mountpoint="$(jq --raw-output '.mountpoint' <<<"${entry}")"
|
||||
percent="$(jq --raw-output '.percent' <<<"${entry}")"
|
||||
filesystem="$(jq --raw-output '.filesystem' <<<"${entry}")"
|
||||
# Partitionsname aus Mountpoint ableiten ("/home" -> "home",
|
||||
# "/var/lib" -> "var-lib") - rein kosmetisch (parted-Label), hat
|
||||
# keine funktionale Bedeutung.
|
||||
name="$(sed -e 's#^/##' -e 's#/#-#g' <<<"${mountpoint}")"
|
||||
cumulative_percent=$((cumulative_percent + percent))
|
||||
|
||||
parted --script "${disk}" mkpart "${name}" "${filesystem}" "${cursor}" "${cumulative_percent}%" ||
|
||||
{ image_deploy_fatal "Partitionierung von ${mountpoint} (${percent}%) fehlgeschlagen auf ${disk}"; return 1; }
|
||||
|
||||
cursor="${cumulative_percent}%"
|
||||
device="$(image_deploy_partition_path "${disk}" "${part_num}")"
|
||||
extra_partitions_result="$(jq --compact-output \
|
||||
--arg mountpoint "${mountpoint}" --arg device "${device}" --arg filesystem "${filesystem}" \
|
||||
'. + [{mountpoint: $mountpoint, device: $device, filesystem: $filesystem}]' \
|
||||
<<<"${extra_partitions_result}")"
|
||||
done < <(jq --compact-output '.[]' <<<"${extra_partitions_json}")
|
||||
|
||||
part_num=$((part_num + 1))
|
||||
parted --script "${disk}" mkpart root ext4 "${cursor}" 100% ||
|
||||
{ image_deploy_fatal "Root-Partitionierung fehlgeschlagen auf ${disk}"; return 1; }
|
||||
local root_part
|
||||
root_part="$(image_deploy_partition_path "${disk}" "${part_num}")"
|
||||
|
||||
_image_deploy_settle_partitions "${disk}" ||
|
||||
{ image_deploy_fatal "Kernel konnte die neuen Partitionen auf ${disk} nicht uebernehmen."; return 1; }
|
||||
|
||||
[[ -z "${boot_part}" || -b "${boot_part}" ]] && [[ -b "${root_part}" ]] ||
|
||||
{ image_deploy_fatal "Partitionen nach partprobe nicht gefunden (${boot_part}, ${root_part})"; return 1; }
|
||||
|
||||
jq --null-input --compact-output \
|
||||
--arg boot_part "${boot_part}" --arg root_part "${root_part}" \
|
||||
--argjson extra_partitions "${extra_partitions_result}" \
|
||||
'{boot_part: $boot_part, root_part: $root_part, extra_partitions: $extra_partitions}'
|
||||
}
|
||||
|
||||
# Formatiert boot_part/root_part wie image_deploy_format(), zusaetzlich
|
||||
# jede Extra-Partition mit ihrem eigenen Dateisystem (aus dem stdout-JSON
|
||||
# von image_deploy_partition_custom()).
|
||||
image_deploy_format_custom() {
|
||||
local boot_part="$1"
|
||||
local root_part="$2"
|
||||
local root_fs="$3"
|
||||
local partition_result="$4"
|
||||
|
||||
image_deploy_format "${boot_part}" "${root_part}" "${root_fs}" || return 1
|
||||
|
||||
local device filesystem entry
|
||||
while IFS= read -r entry; do
|
||||
[[ -n "${entry}" ]] || continue
|
||||
device="$(jq --raw-output '.device' <<<"${entry}")"
|
||||
filesystem="$(jq --raw-output '.filesystem' <<<"${entry}")"
|
||||
case "${filesystem}" in
|
||||
ext4) mkfs.ext4 -F -L "$(basename "${device}")" "${device}" ;;
|
||||
btrfs) mkfs.btrfs -f -L "$(basename "${device}")" "${device}" ;;
|
||||
*) image_deploy_fatal "Nicht unterstuetztes Dateisystem: ${filesystem}"; return 1 ;;
|
||||
esac || { image_deploy_fatal "mkfs auf ${device} fehlgeschlagen"; return 1; }
|
||||
done < <(jq --compact-output '.extra_partitions[]' <<<"${partition_result}")
|
||||
}
|
||||
|
||||
# Mountet root/ESP wie image_deploy_mount(), zusaetzlich jede Extra-
|
||||
# Partition unter ihrem Mountpoint innerhalb von target - VOR dem Golden-
|
||||
# Image-Extract, damit das entpackte Archiv direkt auf den richtigen
|
||||
# Partitionen landet statt hinterher umkopiert werden zu muessen.
|
||||
image_deploy_mount_custom() {
|
||||
local target="$1"
|
||||
local boot_part="$2"
|
||||
local root_part="$3"
|
||||
local partition_result="$4"
|
||||
|
||||
image_deploy_mount "${target}" "${boot_part}" "${root_part}" || return 1
|
||||
|
||||
local device mountpoint entry
|
||||
while IFS= read -r entry; do
|
||||
[[ -n "${entry}" ]] || continue
|
||||
device="$(jq --raw-output '.device' <<<"${entry}")"
|
||||
mountpoint="$(jq --raw-output '.mountpoint' <<<"${entry}")"
|
||||
install -d "${target}${mountpoint}" ||
|
||||
{ image_deploy_fatal "Mountpunkt ${target}${mountpoint} konnte nicht angelegt werden"; return 1; }
|
||||
mount "${device}" "${target}${mountpoint}" ||
|
||||
{ image_deploy_fatal "${device} konnte nicht auf ${target}${mountpoint} gemountet werden"; return 1; }
|
||||
done < <(jq --compact-output '.extra_partitions[]' <<<"${partition_result}")
|
||||
}
|
||||
|
||||
image_deploy_format() {
|
||||
local boot_part="$1"
|
||||
local root_part="$2"
|
||||
@@ -354,11 +493,16 @@ image_deploy_install_network_profile() {
|
||||
{ image_deploy_fatal "Verbindungsprofil konnte nicht nach ${dest_dir} kopiert werden"; return 1; }
|
||||
}
|
||||
|
||||
# extra_partitions_json (5. Parameter, optional): kompaktes JSON-Array wie
|
||||
# von image_deploy_partition_custom() zurueckgegeben
|
||||
# ([{"mountpoint":...,"device":...,"filesystem":...}, ...]) - Default "[]",
|
||||
# damit bestehende Aufrufer (scheme:"single") unveraendert bleiben.
|
||||
image_deploy_write_fstab() {
|
||||
local target="$1"
|
||||
local boot_part="$2"
|
||||
local root_part="$3"
|
||||
local root_fs="$4"
|
||||
local extra_partitions_json="${5:-[]}"
|
||||
|
||||
local root_uuid
|
||||
root_uuid="$(blkid -s UUID -o value "${root_part}")"
|
||||
@@ -375,6 +519,18 @@ image_deploy_write_fstab() {
|
||||
{ image_deploy_fatal "Keine UUID fuer ${boot_part} gefunden"; return 1; }
|
||||
echo "UUID=${boot_uuid} /boot/efi vfat umask=0077 0 1"
|
||||
fi
|
||||
|
||||
local device mountpoint filesystem uuid entry
|
||||
while IFS= read -r entry; do
|
||||
[[ -n "${entry}" ]] || continue
|
||||
device="$(jq --raw-output '.device' <<<"${entry}")"
|
||||
mountpoint="$(jq --raw-output '.mountpoint' <<<"${entry}")"
|
||||
filesystem="$(jq --raw-output '.filesystem' <<<"${entry}")"
|
||||
uuid="$(blkid -s UUID -o value "${device}")"
|
||||
[[ -n "${uuid}" ]] ||
|
||||
{ image_deploy_fatal "Keine UUID fuer ${device} gefunden"; return 1; }
|
||||
echo "UUID=${uuid} ${mountpoint} ${filesystem} defaults 0 2"
|
||||
done < <(jq --compact-output '.[]' <<<"${extra_partitions_json}")
|
||||
} > "${target}/etc/fstab"
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user