#!/usr/bin/env bash set -euo pipefail ############################################################################### # Aamsveen Audio Kiosk ISO builder # # VERSION: v1 # # BOOT DESIGN # # BIOS: # ISO # -> ISOLINUX # -> /isolinux/live.cfg # -> /casper/vmlinuz # -> casper # -> Ubiquity # # UEFI: # ISO # -> /boot/grub/efi.img # -> ORIGINAL Mint EFI GRUB loader # -> ISO /boot/grub/grub.cfg # -> /casper/vmlinuz # -> casper # -> Ubiquity # # CRITICAL: # # boot/grub/efi.img is NEVER modified. # # The custom UEFI menu exists ONLY in: # # /boot/grub/grub.cfg # # The custom BIOS menu exists in: # # /isolinux/live.cfg # # xorriso creates the hybrid ISO directly. # isohybrid is NOT run afterwards. ############################################################################### ############################################################################### # Configuration ############################################################################### BASE_ISO_FILENAME="linuxmint-22.3-cinnamon-64bit.iso" NEW_ISO_FILENAME="non-aamsveen-audio-kiosk_v1.iso" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ISO_PATH="$SCRIPT_DIR/$BASE_ISO_FILENAME" SCRIPT_PATH="$SCRIPT_DIR/install-kiosk-nl.sh" PRESEED_PATH="$SCRIPT_DIR/preseed.cfg" WORK_DIR="$SCRIPT_DIR/build-aamsveen" ISO_ROOT="$WORK_DIR/iso" SQUASHFS_DIR="$WORK_DIR/squashfs-root" NEW_ISO_PATH="$SCRIPT_DIR/$NEW_ISO_FILENAME" ############################################################################### # Helpers ############################################################################### die() { echo echo "ERROR: $*" >&2 exit 1 } log() { echo echo "============================================================" echo "$*" echo "============================================================" } require_command() { command -v "$1" >/dev/null 2>&1 \ || die "Required command not found: $1" } ############################################################################### # Mount cleanup # # Previous builds can leave efi.img loop mounts behind. # # IMPORTANT: # # We unmount deepest paths first, then remove the build directory. ############################################################################### cleanup_work_mounts() { if [[ ! -d "$WORK_DIR" ]]; then return 0 fi while read -r MOUNTPOINT; do [[ -n "$MOUNTPOINT" ]] || continue echo "Unmount: $MOUNTPOINT" sudo umount "$MOUNTPOINT" 2>/dev/null || \ sudo umount -l "$MOUNTPOINT" 2>/dev/null || true done < <( findmnt -rn -o TARGET 2>/dev/null | grep -F "$WORK_DIR/" | awk '{ print length($0), $0 }' | sort -rn | cut -d' ' -f2- ) } ############################################################################### # Dependency check # # NixOS: # # nix shell nixpkgs#xorriso nixpkgs#squashfsTools ############################################################################### log "Controleer benodigde programma's" for cmd in \ xorriso \ unsquashfs \ mksquashfs \ find \ sed \ awk \ stat \ mount \ umount \ dd \ cmp \ grep \ sudo \ mountpoint \ sort \ cut do require_command "$cmd" done ############################################################################### # Input validation ############################################################################### log "Controleer invoerbestanden" [[ -f "$ISO_PATH" ]] \ || die "Basis-ISO niet gevonden: $ISO_PATH" [[ -f "$SCRIPT_PATH" ]] \ || die "Installatiescript niet gevonden: $SCRIPT_PATH" [[ -f "$PRESEED_PATH" ]] \ || die "Preseed niet gevonden: $PRESEED_PATH" echo "Basis ISO : $ISO_PATH" echo "Preseed : $PRESEED_PATH" echo "Installer : $SCRIPT_PATH" echo "Output : $NEW_ISO_PATH" ############################################################################### # Basic file information ############################################################################### log "Controleer basis-ISO" ORIGINAL_ISO_SIZE="$(stat -c%s "$ISO_PATH")" echo "Originele ISO:" echo " $ISO_PATH" echo echo "Grootte:" echo " $ORIGINAL_ISO_SIZE bytes" ############################################################################### # Remove old build directory safely ############################################################################### log "Verwijder oude werkmap" cleanup_work_mounts rm -rf "$WORK_DIR" mkdir -p "$WORK_DIR" ############################################################################### # Remove old output ISO ############################################################################### if [[ -f "$NEW_ISO_PATH" ]]; then log "Verwijder oude output ISO" rm -f "$NEW_ISO_PATH" fi ############################################################################### # Preserve ORIGINAL Mint MBR boot code # # Only the first 432 bytes are reused. # # xorriso generates the partition structures. ############################################################################### log "Bewaar originele Mint MBR bootcode" ORIGINAL_MBR="$WORK_DIR/mint-isohybrid-mbr.bin" dd \ if="$ISO_PATH" \ of="$ORIGINAL_MBR" \ bs=432 \ count=1 \ status=none [[ "$(stat -c%s "$ORIGINAL_MBR")" -eq 432 ]] \ || die "Originele MBR bootcode heeft geen 432 bytes." ############################################################################### # Inspect original ISO boot structure ############################################################################### log "Controleer originele El Torito bootinformatie" xorriso \ -indev "$ISO_PATH" \ -report_el_torito plain log "Controleer originele system area" xorriso \ -indev "$ISO_PATH" \ -report_system_area plain ############################################################################### # Extract ISO ############################################################################### log "Pak Linux Mint ISO uit" mkdir -p "$ISO_ROOT" xorriso \ -osirrox on \ -indev "$ISO_PATH" \ -extract / "$ISO_ROOT" ############################################################################### # Verify required ISO structure ############################################################################### log "Controleer ISO-structuur" [[ -d "$ISO_ROOT/casper" ]] \ || die "casper directory ontbreekt." [[ -f "$ISO_ROOT/casper/vmlinuz" ]] \ || die "casper/vmlinuz ontbreekt." [[ -d "$ISO_ROOT/isolinux" ]] \ || die "isolinux directory ontbreekt." [[ -f "$ISO_ROOT/isolinux/isolinux.bin" ]] \ || die "isolinux/isolinux.bin ontbreekt." [[ -f "$ISO_ROOT/isolinux/boot.cat" ]] \ || die "isolinux/boot.cat ontbreekt." [[ -f "$ISO_ROOT/isolinux/live.cfg" ]] \ || die "isolinux/live.cfg ontbreekt." [[ -d "$ISO_ROOT/boot/grub" ]] \ || die "boot/grub ontbreekt." [[ -f "$ISO_ROOT/boot/grub/efi.img" ]] \ || die "boot/grub/efi.img ontbreekt." [[ -f "$ISO_ROOT/boot/grub/grub.cfg" ]] \ || die "boot/grub/grub.cfg ontbreekt." ############################################################################### # Preserve original efi.img for byte-for-byte verification ############################################################################### log "Bewaar originele EFI image" ORIGINAL_EFI_IMG="$WORK_DIR/original-efi.img" cp \ "$ISO_ROOT/boot/grub/efi.img" \ "$ORIGINAL_EFI_IMG" ############################################################################### # Locate filesystem.squashfs ############################################################################### log "Zoek filesystem.squashfs" SQUASHFS_FILE="$( find "$ISO_ROOT" \ -type f \ -name "filesystem.squashfs" \ -print \ -quit )" [[ -n "$SQUASHFS_FILE" ]] \ || die "filesystem.squashfs niet gevonden." echo "Squashfs:" echo " $SQUASHFS_FILE" ############################################################################### # Detect initrd ############################################################################### log "Detecteer initrd" INITRD_FILE="$( find "$ISO_ROOT/casper" \ -maxdepth 1 \ -type f \ -iname "initrd*" \ -print \ -quit )" [[ -n "$INITRD_FILE" ]] \ || die "Geen initrd gevonden." ACTUAL_INITRD_NAME="$(basename "$INITRD_FILE")" echo "Initrd:" echo " $ACTUAL_INITRD_NAME" ############################################################################### # Unpack squashfs ############################################################################### log "Pak squashfs uit" mkdir -p "$SQUASHFS_DIR" unsquashfs \ -f \ -d "$SQUASHFS_DIR" \ "$SQUASHFS_FILE" ############################################################################### # Install preseed into ISO ############################################################################### log "Plaats preseed op ISO" PRESEED_ISO_DIR="$ISO_ROOT/preseed" PRESEED_ISO_PATH="$PRESEED_ISO_DIR/preseed.cfg" mkdir -p "$PRESEED_ISO_DIR" cp \ "$PRESEED_PATH" \ "$PRESEED_ISO_PATH" chmod 644 \ "$PRESEED_ISO_PATH" ############################################################################### # Install preseed into live filesystem ############################################################################### log "Plaats preseed in live filesystem" cp \ "$PRESEED_PATH" \ "$SQUASHFS_DIR/preseed.cfg" chmod 644 \ "$SQUASHFS_DIR/preseed.cfg" ############################################################################### # Copy installer script into live filesystem ############################################################################### log "Plaats install-kiosk-nl.sh in live filesystem" INSTALL_SCRIPT_DEST="$SQUASHFS_DIR/usr/local/bin/install-kiosk-nl.sh" mkdir -p \ "$(dirname "$INSTALL_SCRIPT_DEST")" cp \ "$SCRIPT_PATH" \ "$INSTALL_SCRIPT_DEST" chmod +x \ "$INSTALL_SCRIPT_DEST" ############################################################################### # Keep installer script in /home/av-admin ############################################################################### log "Plaats install-kiosk-nl.sh in /home/av-admin" ADMIN_HOME="$SQUASHFS_DIR/home/av-admin" mkdir -p "$ADMIN_HOME" cp \ "$SCRIPT_PATH" \ "$ADMIN_HOME/install-kiosk-nl.sh" chmod +x \ "$ADMIN_HOME/install-kiosk-nl.sh" ############################################################################### # Create dedicated Ubiquity launcher wrapper # # This avoids fragile nested quoting in Exec=. ############################################################################### log "Maak Ubiquity installer wrapper" INSTALLER_WRAPPER="$SQUASHFS_DIR/usr/local/bin/aamsveen-start-installer.sh" mkdir -p \ "$(dirname "$INSTALLER_WRAPPER")" cat > "$INSTALLER_WRAPPER" << 'EOF' #!/bin/sh set -e sudo debconf-set-selections /preseed.cfg exec sudo env \ DEBIAN_FRONTEND=noninteractive \ ubiquity \ --automatic EOF chmod 755 \ "$INSTALLER_WRAPPER" ############################################################################### # Disable Mint Welcome ############################################################################### log "Schakel mintwelcome uit" MINT_WELCOME="$SQUASHFS_DIR/etc/xdg/autostart/mintwelcome.desktop" if [[ -f "$MINT_WELCOME" ]]; then mv \ "$MINT_WELCOME" \ "$MINT_WELCOME.bak" fi ############################################################################### # Remove normal Ubiquity launcher ############################################################################### log "Verwijder standaard Ubiquity launcher" UBIQUITY_DESKTOP="$SQUASHFS_DIR/usr/share/applications/ubiquity.desktop" if [[ -f "$UBIQUITY_DESKTOP" ]]; then rm -f "$UBIQUITY_DESKTOP" fi ############################################################################### # Create custom desktop installer launcher ############################################################################### log "Maak aangepaste Ubiquity desktop launcher" CUSTOM_DESKTOP_ENTRY="$SQUASHFS_DIR/usr/share/applications/install-kiosk.desktop" mkdir -p \ "$(dirname "$CUSTOM_DESKTOP_ENTRY")" cat > "$CUSTOM_DESKTOP_ENTRY" << 'EOF' [Desktop Entry] Name=Installeer Audio Kiosk voor Aamsveen Comment=Installeer Linux Mint met Audio Kiosk voor Aamsveen Exec=/usr/local/bin/aamsveen-start-installer.sh Icon=mintubiquity Terminal=false Type=Application Categories=System; EOF chmod 644 \ "$CUSTOM_DESKTOP_ENTRY" ############################################################################### # Replace Mint desktop installer shortcut ############################################################################### log "Maak aangepaste desktop installer shortcut" MINT_DESKTOP_DIR="$SQUASHFS_DIR/home/mint/Desktop" MINT_DESKTOP_ENTRY="$MINT_DESKTOP_DIR/install.desktop" mkdir -p "$MINT_DESKTOP_DIR" rm -f "$MINT_DESKTOP_ENTRY" cp \ "$CUSTOM_DESKTOP_ENTRY" \ "$MINT_DESKTOP_ENTRY" chmod +x \ "$MINT_DESKTOP_ENTRY" ############################################################################### # Desktop database ############################################################################### if command -v update-desktop-database >/dev/null 2>&1; then update-desktop-database \ "$SQUASHFS_DIR/usr/share/applications/" \ 2>/dev/null || true fi ############################################################################### # UEFI GRUB # # DO NOT MODIFY efi.img. # # Verified original Mint EFI loader: # # search --set=root --file /.disk/info # set prefix=($root)/boot/grub # configfile ($root)/boot/grub/grub.cfg # # Therefore the actual UEFI menu is the ISO-level: # # /boot/grub/grub.cfg ############################################################################### log "Maak UEFI GRUB bootmenu" GRUB_CFG="$ISO_ROOT/boot/grub/grub.cfg" cat > "$GRUB_CFG" << EOF loadfont unicode set color_normal=dark-green/light-gray set color_highlight=light-gray/dark-green set default=1 set timeout=5 menuentry "Start Linux Mint 22.3 Cinnamon 64-bit" --class linuxmint { set gfxpayload=keep linux /casper/vmlinuz boot=casper uuid=6e72f523-dc09-4880-8910-93ffa64401c5 username=mint hostname=mint iso-scan/filename=\${iso_path} quiet splash -- initrd /casper/${ACTUAL_INITRD_NAME} } menuentry "Unattended Install Aamsveen Kiosk" --class linuxmint { set gfxpayload=keep linux /casper/vmlinuz boot=casper uuid=6e72f523-dc09-4880-8910-93ffa64401c5 username=mint hostname=mint iso-scan/filename=\${iso_path} automatic-ubiquity noprompt file=/cdrom/preseed/preseed.cfg priority=critical quiet splash -- initrd /casper/${ACTUAL_INITRD_NAME} } menuentry "Start Linux Mint 22.3 Cinnamon 64-bit (compatibility mode)" { set gfxpayload=keep linux /casper/vmlinuz boot=casper uuid=6e72f523-dc09-4880-8910-93ffa64401c5 username=mint hostname=mint iso-scan/filename=\${iso_path} noapic noacpi nosplash irqpoll nomodeset -- initrd /casper/${ACTUAL_INITRD_NAME} } menuentry "OEM install (for manufacturers)" { set gfxpayload=keep linux /casper/vmlinuz oem-config/enable=true only-ubiquity boot=casper uuid=6e72f523-dc09-4880-8910-93ffa64401c5 username=mint hostname=mint iso-scan/filename=\${iso_path} quiet splash -- initrd /casper/${ACTUAL_INITRD_NAME} } if [ "\$grub_platform" = "efi" ]; then menuentry "Boot from next volume" { exit 1 } menuentry "UEFI Firmware Settings" { fwsetup } if [ -f /boot/memtest.efi ]; then menuentry "Memory test" { linux /boot/memtest.efi } fi fi EOF ############################################################################### # Verify UEFI GRUB source configuration ############################################################################### log "Controleer UEFI GRUB" grep -q \ 'Unattended Install Aamsveen Kiosk' \ "$GRUB_CFG" \ || die "UEFI unattended entry ontbreekt." grep -q \ 'automatic-ubiquity' \ "$GRUB_CFG" \ || die "UEFI automatic-ubiquity ontbreekt." grep -q \ 'noprompt' \ "$GRUB_CFG" \ || die "UEFI noprompt ontbreekt." grep -q \ 'file=/cdrom/preseed/preseed.cfg' \ "$GRUB_CFG" \ || die "UEFI preseed path ontbreekt." grep -q \ 'iso-scan/filename=${iso_path}' \ "$GRUB_CFG" \ || die "UEFI iso-scan/filename ontbreekt." grep -q \ 'set default=1' \ "$GRUB_CFG" \ || die "UEFI unattended entry is niet default." grep -q \ 'set timeout=5' \ "$GRUB_CFG" \ || die "UEFI timeout=5 ontbreekt." ############################################################################### # Verify original EFI image BEFORE ISO creation ############################################################################### log "Controleer originele EFI loader" EFI_IMG="$ISO_ROOT/boot/grub/efi.img" EFI_MOUNT="$WORK_DIR/efi_mount" mkdir -p "$EFI_MOUNT" EFI_MOUNTED=0 cleanup_efi() { if [[ "$EFI_MOUNTED" -eq 1 ]]; then sudo umount "$EFI_MOUNT" 2>/dev/null || \ sudo umount -l "$EFI_MOUNT" 2>/dev/null || true EFI_MOUNTED=0 fi } trap cleanup_efi EXIT sudo mount \ -o loop,ro \ "$EFI_IMG" \ "$EFI_MOUNT" EFI_MOUNTED=1 EFI_GRUB_CFG="$( sudo find "$EFI_MOUNT" \ -type f \ -name "grub.cfg" \ -print \ -quit )" [[ -n "$EFI_GRUB_CFG" ]] \ || die "Geen grub.cfg gevonden in efi.img." EFI_GRUB_CONTENT="$( sudo cat "$EFI_GRUB_CFG" )" echo "$EFI_GRUB_CONTENT" grep -q \ 'search --set=root --file /.disk/info' \ <<< "$EFI_GRUB_CONTENT" \ || die "Originele EFI loader mist /.disk/info search." grep -q \ 'set prefix=($root)/boot/grub' \ <<< "$EFI_GRUB_CONTENT" \ || die "Originele EFI loader mist GRUB prefix." grep -q \ 'configfile ($root)/boot/grub/grub.cfg' \ <<< "$EFI_GRUB_CONTENT" \ || die "Originele EFI loader mist configfile." if grep -q \ 'Unattended Install Aamsveen Kiosk' \ <<< "$EFI_GRUB_CONTENT" then die "Aamsveen menu staat ten onrechte in efi.img." fi cleanup_efi trap - EXIT ############################################################################### # BIOS / ISOLINUX # # The original Mint ISO uses /isolinux/live.cfg as its visible BIOS menu. ############################################################################### log "Maak BIOS/ISOLINUX bootmenu" LIVE_CFG_PATH="$ISO_ROOT/isolinux/live.cfg" [[ -f "$LIVE_CFG_PATH" ]] \ || die "isolinux/live.cfg ontbreekt." ############################################################################### # Remove any previous Aamsveen unattended block # # This removes: # # label unattended-install # ... # # until the next "label" or EOF. ############################################################################### TMP_LIVE_CFG="$WORK_DIR/live.cfg.tmp" awk ' BEGIN { skip = 0 } /^[[:space:]]*label[[:space:]]+unattended-install[[:space:]]*$/ { skip = 1 next } skip == 1 && /^[[:space:]]*label[[:space:]]+/ { skip = 0 } skip == 1 { next } { print } ' "$LIVE_CFG_PATH" > "$TMP_LIVE_CFG" mv \ "$TMP_LIVE_CFG" \ "$LIVE_CFG_PATH" ############################################################################### # Remove old timeout directives ############################################################################### sed -i \ '/^[[:space:]]*timeout[[:space:]]\+[0-9]\+[[:space:]]*$/d' \ "$LIVE_CFG_PATH" ############################################################################### # Make unattended entry the BIOS default # # ISOLINUX uses "menu default" in the label block. ############################################################################### sed -i \ '/^[[:space:]]*menu default[[:space:]]*$/d' \ "$LIVE_CFG_PATH" ############################################################################### # Add unattended BIOS entry ############################################################################### cat >> "$LIVE_CFG_PATH" << EOF # --------------------------------------------------------------------------- # Aamsveen custom unattended installer # --------------------------------------------------------------------------- label unattended-install menu label ^Unattended Install Aamsveen Kiosk menu default kernel /casper/vmlinuz append boot=casper automatic-ubiquity noprompt file=/cdrom/preseed/preseed.cfg priority=critical quiet splash -- initrd /casper/${ACTUAL_INITRD_NAME} # Wait indefinitely for user input. timeout 0 EOF ############################################################################### # Verify BIOS configuration ############################################################################### log "Controleer BIOS/ISOLINUX configuratie" grep -q \ '^label unattended-install$' \ "$LIVE_CFG_PATH" \ || die "BIOS unattended entry ontbreekt." grep -q \ 'Unattended Install Aamsveen Kiosk' \ "$LIVE_CFG_PATH" \ || die "BIOS Aamsveen menu-entry ontbreekt." grep -q \ 'automatic-ubiquity' \ "$LIVE_CFG_PATH" \ || die "BIOS automatic-ubiquity ontbreekt." grep -q \ 'noprompt' \ "$LIVE_CFG_PATH" \ || die "BIOS noprompt ontbreekt." grep -q \ 'file=/cdrom/preseed/preseed.cfg' \ "$LIVE_CFG_PATH" \ || die "BIOS preseed path ontbreekt." grep -q \ '^timeout 0$' \ "$LIVE_CFG_PATH" \ || die "BIOS timeout 0 ontbreekt." grep -q \ '^[[:space:]]*menu default[[:space:]]*$' \ "$LIVE_CFG_PATH" \ || die "BIOS unattended entry is niet default." ############################################################################### # Display boot configurations ############################################################################### echo echo "================ UEFI grub.cfg ================" cat "$GRUB_CFG" echo echo "================ BIOS live.cfg ================" cat "$LIVE_CFG_PATH" ############################################################################### # Rebuild squashfs ############################################################################### log "Verwijder oude filesystem.squashfs" rm -f \ "$SQUASHFS_FILE" log "Bouw filesystem.squashfs opnieuw" mksquashfs \ "$SQUASHFS_DIR" \ "$ISO_ROOT/casper/filesystem.squashfs" \ -b 256K \ -comp xz \ -Xdict-size 100% \ -no-duplicates \ -no-xattrs \ -noappend [[ -f "$ISO_ROOT/casper/filesystem.squashfs" ]] \ || die "Nieuw filesystem.squashfs ontbreekt." ############################################################################### # Build ISO ############################################################################### log "Bouw nieuwe ISO met xorriso-native hybrid layout" cd "$ISO_ROOT" xorriso -as mkisofs \ -r \ -V "NonAamsveenAudioKiosk" \ -J \ -l \ -isohybrid-mbr "$ORIGINAL_MBR" \ -partition_cyl_align on \ -partition_offset 16 \ -partition_hd_cyl 185 \ -partition_sec_hd 32 \ --mbr-force-bootable \ -apm-block-size 2048 \ -iso_mbr_part_type 0x00 \ -c isolinux/boot.cat \ -b isolinux/isolinux.bin \ -no-emul-boot \ -boot-load-size 4 \ -boot-info-table \ -eltorito-alt-boot \ -e boot/grub/efi.img \ -no-emul-boot \ -isohybrid-gpt-basdat \ -isohybrid-apm-hfsplus \ -o "$NEW_ISO_PATH" \ . ############################################################################### # Verify ISO exists ############################################################################### log "Controleer gemaakte ISO" [[ -f "$NEW_ISO_PATH" ]] \ || die "Nieuwe ISO is niet gemaakt." NEW_ISO_SIZE="$(stat -c%s "$NEW_ISO_PATH")" echo "Originele ISO : $ORIGINAL_ISO_SIZE bytes" echo "Nieuwe ISO : $NEW_ISO_SIZE bytes" if [[ "$NEW_ISO_SIZE" -lt "$((ORIGINAL_ISO_SIZE * 90 / 100))" ]]; then die "Nieuwe ISO is verdacht klein." fi ############################################################################### # Verify El Torito ############################################################################### log "Controleer El Torito" xorriso \ -indev "$NEW_ISO_PATH" \ -report_el_torito plain ############################################################################### # Verify hybrid system area ############################################################################### log "Controleer hybrid system area" SYSTEM_AREA_REPORT="$WORK_DIR/system-area-report.txt" xorriso \ -indev "$NEW_ISO_PATH" \ -report_system_area plain \ > "$SYSTEM_AREA_REPORT" cat "$SYSTEM_AREA_REPORT" grep -Eq \ 'System area summary:.*MBR.*GPT.*APM' \ "$SYSTEM_AREA_REPORT" \ || die "MBR/GPT/APM hybrid layout ontbreekt." ############################################################################### # Create final ISO verification directory ############################################################################### TMP_CHECK_DIR="$WORK_DIR/iso-check" mkdir -p "$TMP_CHECK_DIR" ############################################################################### # Verify boot files ############################################################################### log "Controleer bootbestanden" xorriso \ -indev "$NEW_ISO_PATH" \ -ls \ /casper/vmlinuz \ /casper/"$ACTUAL_INITRD_NAME" \ /boot/grub/efi.img \ /boot/grub/grub.cfg \ /isolinux/live.cfg ############################################################################### # Verify BIOS config inside FINAL ISO ############################################################################### log "Controleer BIOS configuratie in eind-ISO" xorriso \ -osirrox on \ -indev "$NEW_ISO_PATH" \ -cpx /isolinux/live.cfg "$TMP_CHECK_DIR/" FINAL_LIVE_CFG="$TMP_CHECK_DIR/live.cfg" grep -q \ '^label unattended-install$' \ "$FINAL_LIVE_CFG" \ || die "Finale ISO mist BIOS unattended entry." grep -q \ 'Unattended Install Aamsveen Kiosk' \ "$FINAL_LIVE_CFG" \ || die "Finale ISO mist BIOS Aamsveen entry." grep -q \ 'automatic-ubiquity' \ "$FINAL_LIVE_CFG" \ || die "Finale ISO mist BIOS automatic-ubiquity." grep -q \ 'noprompt' \ "$FINAL_LIVE_CFG" \ || die "Finale ISO mist BIOS noprompt." grep -q \ 'file=/cdrom/preseed/preseed.cfg' \ "$FINAL_LIVE_CFG" \ || die "Finale ISO mist BIOS preseed." grep -q \ '^[[:space:]]*menu default[[:space:]]*$' \ "$FINAL_LIVE_CFG" \ || die "Finale BIOS unattended entry is niet default." ############################################################################### # Verify UEFI config inside FINAL ISO ############################################################################### log "Controleer UEFI configuratie in eind-ISO" TMP_GRUB_CHECK="$TMP_CHECK_DIR/grub.cfg" xorriso \ -osirrox on \ -indev "$NEW_ISO_PATH" \ -cpx /boot/grub/grub.cfg "$TMP_GRUB_CHECK" grep -q \ 'Unattended Install Aamsveen Kiosk' \ "$TMP_GRUB_CHECK" \ || die "Finale ISO mist UEFI unattended entry." grep -q \ 'automatic-ubiquity' \ "$TMP_GRUB_CHECK" \ || die "Finale ISO mist UEFI automatic-ubiquity." grep -q \ 'noprompt' \ "$TMP_GRUB_CHECK" \ || die "Finale ISO mist UEFI noprompt." grep -q \ 'file=/cdrom/preseed/preseed.cfg' \ "$TMP_GRUB_CHECK" \ || die "Finale ISO mist UEFI preseed path." grep -q \ 'iso-scan/filename=${iso_path}' \ "$TMP_GRUB_CHECK" \ || die "Finale ISO mist UEFI iso-scan/filename." grep -q \ 'set default=1' \ "$TMP_GRUB_CHECK" \ || die "Finale UEFI unattended entry is niet default." ############################################################################### # Verify ORIGINAL efi.img remains byte-for-byte identical ############################################################################### log "Controleer dat efi.img byte-for-byte origineel is" EFI_VERIFY_DIR="$TMP_CHECK_DIR/efi-verify" mkdir -p "$EFI_VERIFY_DIR" xorriso \ -osirrox on \ -indev "$NEW_ISO_PATH" \ -cpx /boot/grub/efi.img "$EFI_VERIFY_DIR/" FINAL_EFI_IMG="$EFI_VERIFY_DIR/efi.img" [[ -f "$FINAL_EFI_IMG" ]] \ || die "Finale efi.img kon niet uit ISO worden gehaald." cmp \ "$ORIGINAL_EFI_IMG" \ "$FINAL_EFI_IMG" \ || die "Finale efi.img verschilt van de originele Mint efi.img." echo "efi.img: BYTE-FOR-BYTE IDENTIEK AAN ORIGINEEL" ############################################################################### # Mount final efi.img and verify chainloader ############################################################################### log "Controleer EFI chainloader in eind-ISO" FINAL_EFI_MOUNT="$EFI_VERIFY_DIR/mount" mkdir -p "$FINAL_EFI_MOUNT" FINAL_EFI_MOUNTED=0 cleanup_final_efi() { if [[ "$FINAL_EFI_MOUNTED" -eq 1 ]]; then sudo umount "$FINAL_EFI_MOUNT" 2>/dev/null || \ sudo umount -l "$FINAL_EFI_MOUNT" 2>/dev/null || true FINAL_EFI_MOUNTED=0 fi } trap cleanup_final_efi EXIT sudo mount \ -o loop,ro \ "$FINAL_EFI_IMG" \ "$FINAL_EFI_MOUNT" FINAL_EFI_MOUNTED=1 FINAL_EFI_GRUB_CFG="$( sudo find "$FINAL_EFI_MOUNT" \ -type f \ -name "grub.cfg" \ -print \ -quit )" [[ -n "$FINAL_EFI_GRUB_CFG" ]] \ || die "Geen grub.cfg in finale efi.img." FINAL_EFI_CONTENT="$( sudo cat "$FINAL_EFI_GRUB_CFG" )" echo echo "================ FINAL EFI grub.cfg ================" echo "$FINAL_EFI_CONTENT" grep -q \ 'search --set=root --file /.disk/info' \ <<< "$FINAL_EFI_CONTENT" \ || die "Finale EFI loader mist Mint search." grep -q \ 'set prefix=($root)/boot/grub' \ <<< "$FINAL_EFI_CONTENT" \ || die "Finale EFI loader mist GRUB prefix." grep -q \ 'configfile ($root)/boot/grub/grub.cfg' \ <<< "$FINAL_EFI_CONTENT" \ || die "Finale EFI loader mist ISO-level configfile." if grep -q \ 'Unattended Install Aamsveen Kiosk' \ <<< "$FINAL_EFI_CONTENT" then die "Finale efi.img bevat ten onrechte custom Aamsveen menu." fi cleanup_final_efi trap - EXIT ############################################################################### # Verify preseed in FINAL ISO ############################################################################### log "Controleer preseed in eind-ISO" TMP_PRESEED_CHECK="$TMP_CHECK_DIR/preseed.cfg" xorriso \ -osirrox on \ -indev "$NEW_ISO_PATH" \ -cpx /preseed/preseed.cfg "$TMP_PRESEED_CHECK" [[ -s "$TMP_PRESEED_CHECK" ]] \ || die "Finale ISO bevat geen geldige preseed." ############################################################################### # Verify installer wrapper in rebuilt squashfs ############################################################################### [[ -f "$SQUASHFS_DIR/usr/local/bin/aamsveen-start-installer.sh" ]] \ || die "Installer wrapper ontbreekt." [[ -x "$SQUASHFS_DIR/usr/local/bin/aamsveen-start-installer.sh" ]] \ || die "Installer wrapper is niet executable." [[ -f "$SQUASHFS_DIR/usr/local/bin/install-kiosk-nl.sh" ]] \ || die "install-kiosk-nl.sh ontbreekt." [[ -x "$SQUASHFS_DIR/usr/local/bin/install-kiosk-nl.sh" ]] \ || die "install-kiosk-nl.sh is niet executable." ############################################################################### # Final report ############################################################################### log "BUILD VOLTOOID" echo echo "ISO:" echo " $NEW_ISO_PATH" echo echo "UEFI:" echo " Start Linux Mint" echo " Unattended Install Aamsveen Kiosk <-- DEFAULT" echo " Compatibility mode" echo " OEM" echo " UEFI Firmware Settings" echo echo "UEFI colors:" echo " normal = dark-green / light-gray" echo " highlight = light-gray / dark-green" echo echo "UEFI timeout:" echo " 5 seconden" echo echo "BIOS:" echo " Start Linux Mint" echo " Compatibility mode" echo " OEM" echo " Hardware Detection" echo " Boot from local drive" echo " Memory test" echo " Unattended Install Aamsveen Kiosk <-- DEFAULT" echo echo "BIOS timeout:" echo " 0 = oneindig" echo echo "Installer:" echo " automatic-ubiquity" echo " noprompt" echo " file=/cdrom/preseed/preseed.cfg" echo " priority=critical" echo echo "EFI image:" echo " ORIGINAL" echo " byte-for-byte verified" echo echo "Hybrid ISO:" echo " MBR + GPT + APM" echo " xorriso native" echo " GEEN isohybrid post-processing" ############################################################################### # Cleanup ############################################################################### log "Ruim werkmap op" cd "$SCRIPT_DIR" cleanup_work_mounts rm -rf "$WORK_DIR" echo echo "============================================================" echo "KLAAR" echo "============================================================" echo echo "ISO:" echo " $NEW_ISO_PATH" echo echo "Burn ISO:" echo "sudo dd if=$NEW_ISO_PATH of=/dev/sdX bs=4M status=progress conv=fsync" echo echo "Run in QEMU" echo echo qemu-img create -f qcow2 ./kiosk-aamsveen.qcow2 32G echo echo "qemu-system-x86_64 \ -enable-kvm \ -cpu host \ -smp 4 \ -m 8G \ -boot order=d \ -cdrom $NEW_ISO_PATH \ -drive file=./kiosk-aamsveen.qcow2,format=qcow2,if=ide \ -vga std \ -display gtk \ -usb \ -device usb-tablet \ -audiodev pipewire,id=snd0 \ -device intel-hda \ -device hda-duplex,audiodev=snd0"