317037f8eb
Two jobs, one repack pass. BRANDING. Every ISO now carries a Felhom boot screen built from the website's og-image_2.png at repack time (ImageMagick in the assistant container), so the boot card has ONE source and not a second pre-rendered copy in the repo to drift. The card is scaled onto a 1024x768 gfxterm canvas, top-centered, and the card's own subtle background grid is continued across the letterbox fill PHASE-LOCKED to where the card's grid lands — the fill is seamless rather than a square of grid floating in flat navy. Menu positioning needs a gfxmenu theme (plain background_image cannot move the menu off the wordmark), so the stock pvetheme is replaced by felhomtheme, which puts the menu in the lower third the layout deliberately leaves empty. SAFETY — the half that matters. The stock PVE menu offers Graphical, Terminal UI and serial installers plus an Advanced Options submenu (nomodeset x2, three debug variants, Rescue Boot, memtest, UEFI settings). Every one of them reaches the MANUAL installer, whose first question is which disk to wipe. A customer, or their helpful nephew, must not be able to get there from a boot menu. They are not hidden and not password-gated: they are NOT EMITTED. What ships is one entry, 'Felhom telepítés', default, 5s. Boot behavior is unchanged. The kernel/append and initrd lines are lifted VERBATIM from the ISO's own 'Install Proxmox VE (Automated)' entry rather than frozen into a copy here, so a PVE bump tracks automatically; the build fails if they cannot be found, if the append line has lost proxmox-start-auto-installer, or if auto-installer-mode.toml is absent (which would mean the one Felhom- labelled entry boots a manual installer). The rendered menu is then gated for exactly 1 entry, 0 submenus, and zero references to proxtui/proxdebug/nomodeset/ Rescue Boot/memtest/fwsetup — and re-verified by reading the menu back OUT of the finished ISO, not merely out of the extract tree. mkimage-surgery.sh -> iso-repack.sh: branding and the slice-B loader swap need the same extract -> modify -> re-master cycle, so they share one pass instead of re-mastering twice. The mkimage recipe is untouched. The embedded module list is still derived from the STOCK grub.cfg (snapshotted before branding rewrites it), plus gfxmenu's bitmap/bitmap_scale/trig renderer deps. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Nn3VgQk9iwEGgyx6QJ2NvE
321 lines
20 KiB
Bash
321 lines
20 KiB
Bash
#!/bin/bash
|
|
#===============================================================================
|
|
# iso-repack.sh — the post-prepare-iso repack stage: GRUB branding + single-entry menu surgery
|
|
# (scripts v1.22.0, R-38) and, when asked, the slice-B mkimage UEFI loader swap.
|
|
#
|
|
# WAS mkimage-surgery.sh (slice B, v1.18.0). v1.22.0 generalised it because BOTH jobs need the same
|
|
# expensive extract -> modify -> re-master cycle, and doing them as two separate repacks would double
|
|
# the runtime and re-master the image twice for no reason. The mkimage recipe below is UNCHANGED and
|
|
# still the N100 run's proven-live one — do NOT re-derive it.
|
|
#
|
|
# RUNS INSIDE the felhom-iso-assistant container; operates on /work/out.iso (the prepare-iso output)
|
|
# and writes /work/final.iso. NEVER touches the source ISO or the assistant's answer/first-boot
|
|
# payload — only the GRUB menu, the theme, and (in mkimage mode) the EFI boot path.
|
|
#
|
|
# Env:
|
|
# FELHOM_LOADER = shim | mkimage (default shim) — mkimage swaps BOOTX64.EFI (F1 firmware fix)
|
|
# FELHOM_BRAND = 1 | 0 (default 1) — 0 leaves the stock PVE menu completely alone
|
|
#
|
|
# Expects in /work (placed by build-felhom-iso.sh) when FELHOM_BRAND=1:
|
|
# brand/grub.cfg.tmpl, brand/felhom-theme.txt, brand/generate-grub-background.sh, brand/card.png
|
|
#
|
|
# Writes: /work/final.iso, /work/grub-version.txt (mkimage), /work/brand-report.txt (branding)
|
|
#
|
|
# --- the mkimage recipe (unchanged from v1.18.0) ---------------------------------------------------
|
|
# Build BOOTX64.EFI from the ISO's OWN x86_64-efi GRUB modules (the box's working 2.12-9+pmx2 build),
|
|
# embedding the module set the ISO's grub.cfg needs + an embedded config that `search --fs-uuid`es the
|
|
# ISO and `configfile`s its real menu; swap it into the ISO9660 EFI/BOOT tree AND inside efi.img. The
|
|
# image is UNSIGNED (Secure Boot must be OFF on the target) — that is the documented mkimage contract.
|
|
#===============================================================================
|
|
set -euo pipefail
|
|
|
|
OUT=/work/out.iso
|
|
FINAL=/work/final.iso
|
|
EX=/work/ex
|
|
EMB=/work/embedded.cfg
|
|
LDR=/work/BOOTX64.EFI
|
|
BRANDDIR=/work/brand
|
|
ORIG_CFG=/work/grub.cfg.orig
|
|
|
|
LOADER="${FELHOM_LOADER:-shim}"
|
|
BRAND="${FELHOM_BRAND:-1}"
|
|
|
|
say() { echo "iso-repack: $*"; }
|
|
|
|
# The osirrox extract tree is written by container-root; the host-side build cleanup (a non-root user)
|
|
# cannot remove it. Remove it here (we ARE root in the container) on every exit path so no /tmp litter
|
|
# survives the run.
|
|
cleanup_ex() { if [[ -n "${EX:-}" && -e "$EX" ]]; then rm -rf "$EX" 2>/dev/null || true; fi; }
|
|
trap cleanup_ex EXIT
|
|
|
|
[[ -f "$OUT" ]] || { echo "iso-repack: /work/out.iso missing" >&2; exit 2; }
|
|
[[ "$LOADER" == "shim" || "$LOADER" == "mkimage" ]] || { echo "iso-repack: bad FELHOM_LOADER '$LOADER'" >&2; exit 2; }
|
|
|
|
# Nothing to do at all -> pass the prepared ISO through byte-for-byte rather than re-mastering it.
|
|
if [[ "$BRAND" != "1" && "$LOADER" == "shim" ]]; then
|
|
say "no branding, shim loader — passing the prepared ISO through unmodified"
|
|
cp "$OUT" "$FINAL"; exit 0
|
|
fi
|
|
|
|
command -v xorriso >/dev/null || { echo "iso-repack: missing tool: xorriso" >&2; exit 2; }
|
|
if [[ "$LOADER" == "mkimage" ]]; then
|
|
for t in grub-mkimage mcopy mdir; do
|
|
command -v "$t" >/dev/null || { echo "iso-repack: missing tool: $t" >&2; exit 2; }
|
|
done
|
|
fi
|
|
if [[ "$BRAND" == "1" ]]; then
|
|
command -v magick >/dev/null || command -v convert >/dev/null \
|
|
|| { echo "iso-repack: ImageMagick missing (needed for the GRUB background) — rebuild the assistant image" >&2; exit 2; }
|
|
for f in grub.cfg.tmpl felhom-theme.txt generate-grub-background.sh card.png; do
|
|
[[ -f "$BRANDDIR/$f" ]] || { echo "iso-repack: brand asset missing: $BRANDDIR/$f" >&2; exit 2; }
|
|
done
|
|
fi
|
|
|
|
# --- 1. extract the full prepared ISO tree (osirrox) — preserves the answer + first-boot payload.
|
|
# osirrox reproduces the ISO's (read-only) file modes, so make the tree writable afterwards or
|
|
# the loader swap and the workspace cleanup can't overwrite/remove the files. ------------------
|
|
[[ -e "$EX" ]] && { chmod -R u+w "$EX" 2>/dev/null || true; rm -rf "$EX"; }
|
|
mkdir -p "$EX"
|
|
xorriso -osirrox on -indev "$OUT" -extract / "$EX" >/dev/null 2>&1
|
|
chmod -R u+w "$EX"
|
|
say "extracted prepared ISO tree"
|
|
|
|
# Locate the ISO's real grub.cfg and snapshot it BEFORE branding rewrites it: the mkimage module list
|
|
# below is derived from the STOCK cfg's insmods, and branding must not be able to shrink that set.
|
|
GCFG=""
|
|
for c in "$EX/boot/grub/grub.cfg" "$EX/boot/grub/x86_64-efi/grub.cfg"; do
|
|
[[ -f "$c" ]] && { GCFG="$c"; break; }
|
|
done
|
|
[[ -n "$GCFG" ]] || { echo "iso-repack: no grub.cfg found in the extracted tree" >&2; exit 3; }
|
|
cp "$GCFG" "$ORIG_CFG"
|
|
|
|
#====================================================================================================
|
|
# --- 2. BRANDING + SINGLE-ENTRY MENU SURGERY (R-38) ------------------------------------------------
|
|
#====================================================================================================
|
|
if [[ "$BRAND" == "1" ]]; then
|
|
say "branding GRUB (background + single-entry menu)"
|
|
|
|
# 2a. The prepared ISO MUST be an auto-install ISO. Our one menu entry boots the automated
|
|
# installer, which reads this file; without it the entry would drop into the manual installer
|
|
# — the exact outcome the single-entry menu exists to prevent. Fail loudly, never silently.
|
|
AIM="$(find "$EX" -maxdepth 2 -iname 'auto-installer-mode.toml' | head -1)"
|
|
[[ -n "$AIM" ]] || {
|
|
echo "iso-repack: auto-installer-mode.toml not found in the ISO — this is not a prepared" >&2
|
|
echo " auto-install ISO, so the single Felhom entry would boot the MANUAL installer. Refusing." >&2
|
|
exit 10
|
|
}
|
|
|
|
# 2b. Lift the kernel + initrd lines VERBATIM from the stock 'Install Proxmox VE (Automated)'
|
|
# entry, so a PVE bump that changes the kernel path or append line tracks automatically.
|
|
LINUX_LINE="$(awk '
|
|
/menuentry .Install Proxmox VE \(Automated\)./ { inblk=1; next }
|
|
inblk && /^[[:space:]]*linux[[:space:]]/ { print; exit }
|
|
inblk && /^[[:space:]]*}/ { inblk=0 }
|
|
' "$ORIG_CFG")"
|
|
INITRD_LINE="$(awk '
|
|
/menuentry .Install Proxmox VE \(Automated\)./ { inblk=1; next }
|
|
inblk && /^[[:space:]]*initrd[[:space:]]/ { print; exit }
|
|
inblk && /^[[:space:]]*}/ { inblk=0 }
|
|
' "$ORIG_CFG")"
|
|
|
|
[[ -n "$LINUX_LINE" ]] || { echo "iso-repack: could not lift the 'linux' line from the stock automated entry" >&2; exit 11; }
|
|
[[ -n "$INITRD_LINE" ]] || { echo "iso-repack: could not lift the 'initrd' line from the stock automated entry" >&2; exit 11; }
|
|
# The append flag that MAKES it unattended. If PVE ever renames it, we must not ship an ISO that
|
|
# boots a manual installer behind a button labelled "Felhom telepítés".
|
|
grep -q 'proxmox-start-auto-installer' <<<"$LINUX_LINE" || {
|
|
echo "iso-repack: the lifted kernel line has no 'proxmox-start-auto-installer' flag:" >&2
|
|
echo " $LINUX_LINE" >&2; exit 12
|
|
}
|
|
grep -q '/boot/initrd.img' <<<"$INITRD_LINE" || {
|
|
echo "iso-repack: the lifted initrd line looks wrong: $INITRD_LINE" >&2; exit 12
|
|
}
|
|
# Normalise indentation only — the command and its arguments are untouched.
|
|
LINUX_NORM=" $(sed -E 's/^[[:space:]]+//' <<<"$LINUX_LINE")"
|
|
INITRD_NORM=" $(sed -E 's/^[[:space:]]+//' <<<"$INITRD_LINE")"
|
|
say "lifted kernel line: $(sed -E 's/^[[:space:]]+//' <<<"$LINUX_LINE")"
|
|
|
|
# 2c. Build the background and install the theme.
|
|
THEMEDIR="$EX/boot/grub/felhomtheme"
|
|
mkdir -p "$THEMEDIR"
|
|
bash "$BRANDDIR/generate-grub-background.sh" "$BRANDDIR/card.png" "$THEMEDIR/background.png" \
|
|
| sed 's/^/ /'
|
|
cp "$BRANDDIR/felhom-theme.txt" "$THEMEDIR/theme.txt"
|
|
|
|
# 2d. Render the new grub.cfg. Use awk (not sed) so the lifted lines are inserted literally —
|
|
# the append line is full of `/` and `=` that sed would need escaped.
|
|
awk -v lx="$LINUX_NORM" -v ird="$INITRD_NORM" '
|
|
{ gsub(/@@LINUX@@/, lx); gsub(/@@INITRD@@/, ird); print }
|
|
' "$BRANDDIR/grub.cfg.tmpl" > "$GCFG"
|
|
grep -q '@@LINUX@@\|@@INITRD@@' "$GCFG" && { echo "iso-repack: grub.cfg still has unfilled markers" >&2; exit 13; }
|
|
|
|
# 2e. GATES — the safety half is the whole point, so assert it on the rendered file rather than
|
|
# trusting the template. Exactly one entry, zero submenus, no path back to a manual installer.
|
|
N_ENTRY="$(grep -c '^[[:space:]]*menuentry ' "$GCFG" || true)"
|
|
N_SUB="$(grep -c '^[[:space:]]*submenu ' "$GCFG" || true)"
|
|
[[ "$N_ENTRY" == "1" ]] || { echo "iso-repack: rendered grub.cfg has $N_ENTRY menuentries, want exactly 1" >&2; exit 14; }
|
|
[[ "$N_SUB" == "0" ]] || { echo "iso-repack: rendered grub.cfg has $N_SUB submenus, want 0" >&2; exit 14; }
|
|
for banned in proxtui proxdebug nomodeset 'Rescue Boot' memtest fwsetup; do
|
|
if grep -q "$banned" "$GCFG"; then
|
|
echo "iso-repack: rendered grub.cfg still references '$banned'" >&2; exit 14
|
|
fi
|
|
done
|
|
grep -q "set theme=/boot/grub/felhomtheme/theme.txt" "$GCFG" \
|
|
|| { echo "iso-repack: rendered grub.cfg does not point at the Felhom theme" >&2; exit 14; }
|
|
[[ -s "$THEMEDIR/background.png" && -s "$THEMEDIR/theme.txt" ]] \
|
|
|| { echo "iso-repack: theme assets missing after install" >&2; exit 14; }
|
|
|
|
# The stock PVE theme is now unreferenced. Remove it so the ISO carries one theme, not two.
|
|
rm -rf "$EX/boot/grub/pvetheme"
|
|
|
|
cat > /work/brand-report.txt <<EOF
|
|
menu-entries : 1 ('Felhom telepítés', default, timeout 5s)
|
|
menu-removed : Graphical, Terminal UI, serial TUI, Advanced Options submenu (nomodeset x2,
|
|
debug x3, Rescue Boot, memtest86+, UEFI Firmware Settings)
|
|
kernel-line : $(sed -E 's/^[[:space:]]+//' <<<"$LINUX_LINE")
|
|
initrd-line : $(sed -E 's/^[[:space:]]+//' <<<"$INITRD_LINE")
|
|
theme : /boot/grub/felhomtheme/theme.txt (stock pvetheme removed)
|
|
background : 1024x768 PNG24 from website/assets/og-image_2.png
|
|
EOF
|
|
say "menu surgery OK — 1 entry, 0 submenus, stock installers not emitted"
|
|
fi
|
|
|
|
#====================================================================================================
|
|
# --- 3. mkimage UEFI loader surgery (slice B; recipe unchanged) ------------------------------------
|
|
#====================================================================================================
|
|
if [[ "$LOADER" == "mkimage" ]]; then
|
|
grub-mkimage --version | head -1 > /work/grub-version.txt
|
|
say "grub: $(cat /work/grub-version.txt)"
|
|
|
|
# 3a. GRUB build to assemble the loader from. The N100 fix used the box's OWN INSTALLED 2.12 GRUB
|
|
# (a DIFFERENT, working build than the ISO's problem one — which is the whole point). The ISO
|
|
# ships modules but NOT kernel.img, so grub-mkimage cannot use the ISO's module dir directly;
|
|
# the box used its /usr/lib/grub/x86_64-efi. The container mirrors that: grub 2.12 == the PVE
|
|
# 9.x ISO's 2.12-9+pmx2 generation. We take the module BINARIES from here and the module LIST
|
|
# from the ISO's own grub.cfg (so we embed exactly what the ISO menu needs). -------------------
|
|
GDIR=""
|
|
for d in /usr/lib/grub/x86_64-efi /usr/lib/grub/x86_64-efi-signed; do
|
|
[[ -f "$d/kernel.img" ]] && { GDIR="$d"; break; }
|
|
done
|
|
[[ -n "$GDIR" ]] || { echo "iso-repack: no usable GRUB x86_64-efi build (kernel.img) in the container" >&2; exit 3; }
|
|
say "grub module source: $GDIR"
|
|
|
|
# 3b. module list: the base set the search/configfile-from-USB chain needs, PLUS every module the
|
|
# STOCK grub.cfg insmod's (read from the pre-branding snapshot — branding must not be able to
|
|
# shrink the embedded set). bitmap/bitmap_scale/trig are gfxmenu's renderer dependencies: the
|
|
# Felhom theme needs them and the stock cfg does not insmod them explicitly.
|
|
BASE="part_gpt part_msdos msdospart fat exfat iso9660 udf search search_fs_uuid search_fs_file search_label \
|
|
configfile normal boot linux linuxefi chain loadenv loopback echo test true cat ls help \
|
|
all_video efi_gop efi_uga video video_fb font gfxterm gfxterm_background gfxmenu bitmap bitmap_scale trig \
|
|
png jpeg terminal serial gzio xzio lzopio minicmd reboot halt probe regexp sleep keystatus read"
|
|
CFGMODS="$(grep -hoE 'insmod[[:space:]]+[a-zA-Z0-9_]+' "$ORIG_CFG" | awk '{print $2}' | sort -u)"
|
|
MODS=""
|
|
for m in $BASE $CFGMODS; do
|
|
[[ -f "$GDIR/$m.mod" ]] && MODS="$MODS $m"
|
|
done
|
|
MODS="$(echo "$MODS" | tr ' ' '\n' | awk 'NF' | sort -u | tr '\n' ' ')"
|
|
say "embedding $(echo "$MODS" | wc -w) modules from the ISO's own x86_64-efi build"
|
|
fi
|
|
|
|
# --- 4. pin the volume modification-date so the ISO's GRUB fs-uuid is DETERMINISTIC and KNOWN before
|
|
# we build the loader (GRUB's iso9660 fs_uuid is derived from the PVD modification timestamp).
|
|
# Reuse the prepared ISO's own timestamp verbatim -> the embedded search matches the re-mastered
|
|
# image (we pin the same value on re-master in step 6). -----------------------------------------
|
|
MDATE="$(xorriso -indev "$OUT" -report_el_torito as_mkisofs 2>/dev/null \
|
|
| grep -oE "modification-date='[0-9]+'" | grep -oE '[0-9]+' | head -1)"
|
|
[[ -n "$MDATE" && ${#MDATE} -ge 14 ]] || { echo "iso-repack: could not read the ISO modification-date" >&2; exit 4; }
|
|
ISO_UUID="$(echo "${MDATE:0:16}" | sed -E 's/^(.{4})(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})$/\1-\2-\3-\4-\5-\6-\7/')"
|
|
say "ISO fs-uuid (from modification-date $MDATE): $ISO_UUID"
|
|
|
|
if [[ "$LOADER" == "mkimage" ]]; then
|
|
# --- 5a. embedded config: find the ISO by fs-uuid, then chain its real menu (the recorded recipe) --
|
|
cat > "$EMB" <<CFG
|
|
search --no-floppy --fs-uuid --set=root $ISO_UUID
|
|
if [ -z "\$root" ]; then search --no-floppy --file --set=root /boot/grub/grub.cfg; fi
|
|
set prefix=(\$root)/boot/grub
|
|
configfile (\$root)/boot/grub/grub.cfg
|
|
CFG
|
|
|
|
# --- 5b. build the monolithic BOOTX64.EFI from the ISO's OWN modules (-d $GDIR) ------------------
|
|
# shellcheck disable=SC2086
|
|
grub-mkimage -O x86_64-efi -d "$GDIR" -p /boot/grub -c "$EMB" -o "$LDR" $MODS
|
|
[[ -s "$LDR" ]] || { echo "iso-repack: grub-mkimage produced no image" >&2; exit 5; }
|
|
say "built BOOTX64.EFI ($(stat -c%s "$LDR") bytes)"
|
|
|
|
# --- 5c. swap the loader into BOTH the ISO9660 EFI/BOOT tree AND inside the efi.img ESP. The ISO
|
|
# tree uses Rock Ridge (LOWERCASE) names — `/efi/boot/bootx64.efi` — so overwrite the
|
|
# EXISTING files in place (case-insensitive find), NEVER mkdir a spurious uppercase path.
|
|
# The efi.img ESP is FAT (case-insensitive), the authoritative loader UEFI firmware actually
|
|
# runs from USB. -------------------------------------------------------------------------
|
|
TREE_HITS=0
|
|
while IFS= read -r f; do cp "$LDR" "$f"; TREE_HITS=$((TREE_HITS+1)); done \
|
|
< <(find "$EX" -ipath '*/efi/boot/bootx64.efi')
|
|
while IFS= read -r f; do cp "$LDR" "$f"; done \
|
|
< <(find "$EX" -ipath '*/efi/boot/grubx64.efi')
|
|
[[ "$TREE_HITS" -ge 1 ]] || { echo "iso-repack: no bootx64.efi found in the ISO9660 tree to replace" >&2; exit 6; }
|
|
|
|
EFIIMG="$EX/efi.img"
|
|
[[ -f "$EFIIMG" ]] || EFIIMG="$(find "$EX" -maxdepth 3 -iname 'efi*.img' | head -1)"
|
|
[[ -f "$EFIIMG" ]] || { echo "iso-repack: efi.img ESP not found in the ISO tree" >&2; exit 6; }
|
|
# FAT is case-insensitive: ::/EFI/BOOT/BOOTX64.EFI resolves the real loader regardless of stored case.
|
|
mcopy -i "$EFIIMG" -o "$LDR" ::/EFI/BOOT/BOOTX64.EFI
|
|
if mdir -i "$EFIIMG" ::/EFI/BOOT 2>/dev/null | grep -qi grubx64; then
|
|
mcopy -i "$EFIIMG" -o "$LDR" ::/EFI/BOOT/grubx64.efi
|
|
fi
|
|
say "swapped bootx64.efi in the ISO tree ($TREE_HITS) and inside $(basename "$EFIIMG")"
|
|
fi
|
|
|
|
# --- 6. re-master from the (modified) tree, reproducing the source ISO's boot geometry from its OWN
|
|
# as_mkisofs report so we track PVE minor versions. We drop ONLY the Apple APM/HFS+ boot map
|
|
# (-hfsplus / -apm-block-size): re-emitting it trips xorriso 1.5.6's "Overlapping MBR partition
|
|
# entries" on THIS layout, and Mac boot is irrelevant for N100/PC hardware. We KEEP the hybrid
|
|
# BIOS grub2-mbr + El Torito (BIOS eltorito.img + UEFI /efi.img) + the GPT EFI System Partition
|
|
# (-efi-boot-part) that USB UEFI firmware boots from — the whole point of this fix. The volume
|
|
# id + modification-date are pinned explicitly so the embedded fs-uuid stays valid. -------------
|
|
RPT="$(xorriso -indev "$OUT" -report_el_torito as_mkisofs 2>/dev/null)"
|
|
VOLID="$(printf '%s\n' "$RPT" | sed -nE "s/^-V '(.*)'\$/\\1/p" | head -1)"; [[ -n "$VOLID" ]] || VOLID="PVE"
|
|
# Drop, then re-add explicitly: the volume id + modification-date. Drop entirely: the Apple APM/HFS+
|
|
# map (-hfsplus / -apm-block-size) AND the isohybrid GPT-basdat marking (-part_like_isohybrid /
|
|
# -isohybrid-gpt-basdat) — prepare-iso re-masters with these, and re-emitting them alongside
|
|
# -efi-boot-part + the protective MBR trips xorriso 1.5.6's "Overlapping MBR partition entries". The
|
|
# resulting image keeps the protective MBR + grub2-mbr (BIOS) + El Torito (BIOS+UEFI) + the GPT EFI
|
|
# System Partition (verified). Repoint the grub2-mbr template at the in-container out.iso.
|
|
FILTERED="$(printf '%s\n' "$RPT" \
|
|
| grep -vE "^-V '|^--modification-date=|^-apm-block-size |^-hfsplus\$|^-part_like_isohybrid\$|^-isohybrid-gpt-basdat\$" \
|
|
| sed -E "s#(--interval:[^']*:)'[^']*'#\\1'$OUT'#")"
|
|
rm -f "$FINAL"
|
|
# shellcheck disable=SC2086
|
|
eval xorriso -as mkisofs -V "'$VOLID'" --modification-date="'$MDATE'" \
|
|
$FILTERED -o "$FINAL" "$EX" >/work/xorriso.log 2>&1 \
|
|
|| { echo "iso-repack: xorriso re-master FAILED"; tail -25 /work/xorriso.log >&2; exit 7; }
|
|
|
|
[[ -f "$FINAL" ]] || { echo "iso-repack: no final.iso produced" >&2; exit 7; }
|
|
# assert both boot images survived (BIOS eltorito.img + UEFI efi.img) — a silent loss would fail-safe
|
|
# to an unbootable stick, so gate it here.
|
|
ETIMG="$(xorriso -indev "$FINAL" -report_el_torito plain 2>/dev/null | grep -cE 'El Torito boot img')"
|
|
[[ "$ETIMG" -ge 2 ]] || { echo "iso-repack: re-master lost a boot image (El Torito entries=$ETIMG, want >=2)" >&2; exit 8; }
|
|
say "re-mastered final.iso ($(stat -c%s "$FINAL") bytes; El Torito boot images=$ETIMG)"
|
|
|
|
# --- 7. verify the re-mastered image kept the modification-date (so the embedded fs-uuid matches) ---
|
|
FINAL_MDATE="$(xorriso -indev "$FINAL" -report_el_torito as_mkisofs 2>/dev/null \
|
|
| grep -oE "modification-date='[0-9]+'" | grep -oE '[0-9]+' | head -1)"
|
|
if [[ "${FINAL_MDATE:0:14}" != "${MDATE:0:14}" ]]; then
|
|
echo "iso-repack: WARN final modification-date ($FINAL_MDATE) != source ($MDATE) — the search fs-uuid may not match; re-check" >&2
|
|
else
|
|
say "fs-uuid preserved ($ISO_UUID)"
|
|
fi
|
|
|
|
# --- 8. post-re-master proof that the branding actually LANDED in the image we ship (not merely in
|
|
# the extract tree) — read the menu back out of final.iso. --------------------------------------
|
|
if [[ "$BRAND" == "1" ]]; then
|
|
VER=/work/verify; rm -rf "$VER"; mkdir -p "$VER"
|
|
xorriso -osirrox on -indev "$FINAL" -extract /boot/grub/grub.cfg "$VER/grub.cfg" >/dev/null 2>&1
|
|
xorriso -osirrox on -indev "$FINAL" -extract /boot/grub/felhomtheme "$VER/felhomtheme" >/dev/null 2>&1
|
|
N="$(grep -c '^[[:space:]]*menuentry ' "$VER/grub.cfg" 2>/dev/null || echo 0)"
|
|
[[ "$N" == "1" ]] || { echo "iso-repack: final.iso menu has $N entries, want 1" >&2; exit 15; }
|
|
[[ -s "$VER/felhomtheme/background.png" ]] || { echo "iso-repack: final.iso carries no theme background" >&2; exit 15; }
|
|
grep -q "Felhom telepítés" "$VER/grub.cfg" || { echo "iso-repack: final.iso menu entry is not the Felhom one" >&2; exit 15; }
|
|
rm -rf "$VER"
|
|
say "verified in final.iso: 1 entry ('Felhom telepítés') + theme background present"
|
|
fi
|
|
say "done"
|