1301 lines
32 KiB
Bash
Executable File
1301 lines
32 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
set -o pipefail
|
|
|
|
###############################################################################
|
|
# Linux Mint 22.3 Aamsveen Audio Kiosk ISO builder
|
|
#
|
|
# VERSION: v9
|
|
#
|
|
# Host:
|
|
# NixOS 26.11 unstable
|
|
#
|
|
# Guest:
|
|
# Linux Mint 22.3 Cinnamon 64-bit
|
|
#
|
|
# 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_v10.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
|