#!/bin/sh # Notes {{{ # Extract Debian ISO, add a preseed file and rebuild an ISO. # At the end, mounting or extracting the iso use the same disk space, but # mount require root permissions, so i choose to extract the iso. # }}} # Test args {{{ case $# in 1 ) PRESEED_FILE="${1}" TEMP_DIR=$(mktemp --directory -t -- new-preseed-debian-iso-XXXXXX.tmp) ;; 2 ) PRESEED_FILE="${1}" USER_TEMP_DIR="${2}" ## Check user temp dir argument if [ ! -d "${USER_TEMP_DIR}" ]; then printf '%b\n' "ERROR : The second argument should be the path to a directory." exit 1 fi TEMP_DIR=$(mktemp --directory --tmpdir="${USER_TEMP_DIR}" -- new-preseed-debian-iso-XXXXXX.tmp) ;; * ) printf '%b\n' "Usage :" printf '%b\n' "$(basename ${0}) PRESEED_FILE_PATH [TEMP_DIR]" printf '%b\n' "-------" printf '%b\n' "PRESEED_FILE_PATH : Required" printf '%b\n' "Should be the absolut path to the preseed file you want to add to the ISO." printf '%b\n' "-------" printf '%b\n' "TEMP_DIR : Optionnal" printf '%b\n' "If you want to store temporary files and final ISO in a specific directory." printf '%b\n' "Note : This script require ISO size × 2 (eg for DVD. 3.4GB × 2)." printf '%b\n' "Otherwise \$TMPDIR will be used." printf '%b\n' "-------" printf '%b\n' "Dependencies :" printf '%b\n' "The script use 7z, gzip, xorriso and isolinux. You can install them :" printf '%b\n' "sudo apt install p7zip-full gzip xorriso isolinux" exit 1 ;; esac ## Check preseed argument if [ ! -f "${PRESEED_FILE}" ]; then printf '%b\n' "ERROR : The first argument should be the path to preseed file to add." exit 1 fi # }}} # Vars {{{ ## Debian release to use ### Can be buster, stable, stretch, oldstable, bullseye, testing, sid or unstable DEBIAN_VERSION_NAME="buster" ## ISO to download and use ### Can be : ### dvd ### net, netinst ### non-free, firm, firmware ### mini DEBIAN_ISO_TYPE="firm" # Define URL according to specified release name {{{ case "${DEBIAN_VERSION_NAME}" in "oldstable" | "stretch" ) DEBIAN_VERSION_NB="9.12.0" DEBIAN_ISO_DVD_URL="https://cdimage.debian.org/cdimage/archive/${DEBIAN_VERSION_NB}/amd64/iso-dvd/debian-${DEBIAN_VERSION_NB}-amd64-DVD-1.iso" DEBIAN_ISO_NETINST_URL="https://cdimage.debian.org/cdimage/archive/${DEBIAN_VERSION_NB}/amd64/iso-cd/debian-${DEBIAN_VERSION_NB}-amd64-netinst.iso" DEBIAN_ISO_NONFREE_URL="http://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/archive/${DEBIAN_VERSION_NB}+nonfree/amd64/iso-cd/firmware-${DEBIAN_VERSION_NB}-amd64-netinst.iso" DEBIAN_ISO_MINI_URL="http://ftp.fr.debian.org/debian/dists/${DEBIAN_VERSION_NAME}/main/installer-amd64/current/images/netboot/mini.iso" ;; "stable" | "buster" ) DEBIAN_VERSION_NB="10.3.0" DEBIAN_ISO_DVD_URL="https://cdimage.debian.org/debian-cd/current/amd64/iso-dvd/debian-${DEBIAN_VERSION_NB}-amd64-DVD-1.iso" DEBIAN_ISO_NETINST_URL="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-${DEBIAN_VERSION_NB}-amd64-netinst.iso" DEBIAN_ISO_NONFREE_URL="http://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/archive/10.1.0+nonfree/amd64/iso-cd/firmware-10.2.0-amd64-netinst.iso" DEBIAN_ISO_MINI_URL="http://ftp.fr.debian.org/debian/dists/${DEBIAN_VERSION_NAME}/main/installer-amd64/current/images/netboot/mini.iso" ;; "testing" | "bullseye" | "unstable" | "sid") DEBIAN_ISO_DVD_URL="https://cdimage.debian.org/cdimage/weekly-builds/amd64/iso-dvd/debian-testing-amd64-DVD-1.iso" DEBIAN_ISO_NETINST_URL="https://cdimage.debian.org/cdimage/daily-builds/daily/current/amd64/iso-cd/debian-testing-amd64-netinst.iso" DEBIAN_ISO_NONFREE_URL="http://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/weekly-builds/amd64/iso-cd/firmware-testing-amd64-netinst.iso" DEBIAN_ISO_MINI_URL="http://ftp.fr.debian.org/debian/dists/${DEBIAN_VERSION_NAME}/main/installer-amd64/current/images/netboot/mini.iso" ;; * ) printf '%b\n' "Please define a correct Debian release name according to :" printf '%b\n' "stable, buster, testing, sid or unstable" printf '%b\n' "${DEBIAN_VERSION_NAME} does not seems to be correct." exit 1 ;; esac # }}} # Define ISO type to use {{{ case "${DEBIAN_ISO_TYPE}" in dvd ) USE_DEBIAN_ISO="${DEBIAN_ISO_DVD_URL}" ;; net | netinst ) USE_DEBIAN_ISO="${DEBIAN_ISO_NETINST_URL}" ;; non-free | firm | firmware ) USE_DEBIAN_ISO="${DEBIAN_ISO_NONFREE_URL}" ;; mini ) USE_DEBIAN_ISO="${DEBIAN_ISO_MINI_URL}" ;; * ) printf '%b\n' "Please define a correct ISO type according to :" printf '%b\n' "dvd, net, netinst or mini" exit 1 ;; esac # }}} ## Temp directories according to $TEMP_DIR TEMP_ISO_DIR="${TEMP_DIR}/extracted-iso" TEMP_INITRD_DIR="${TEMP_DIR}/initrd" DEBIAN_DL_ISO_PATH="${TEMP_DIR}/debian.iso" DEBIAN_PRESEED_ISO_PATH="$(dirname ${TEMP_DIR})/preseed-debian-${DEBIAN_VERSION_NAME}-amd64.iso" # }}} # Pre-requisites {{{ if [ ! $(command -v 7z) ]; then printf '%b\n' "ERROR : Please install '7z' bin :\\nsudo apt install p7zip-full" exit 1 fi if [ ! $(command -v gzip) ]; then printf '%b\n' "ERROR : Please install 'gzip' bin :\\nsudo apt install gzip" exit 1 fi if [ ! $(command -v xorriso) ]; then printf '%b\n' "ERROR : Please install 'xorriso' bin :\\nsudo apt install xorriso" exit 1 fi if [ ! -f /usr/lib/ISOLINUX/isohdpfx.bin ]; then printf '%b\n' "ERROR : Please install 'isolinux' package :\\nsudo apt install isolinux" exit 1 fi # }}} # Download and extract ISO {{{ wget -q "${USE_DEBIAN_ISO}" -O "${DEBIAN_DL_ISO_PATH}" command 7z x -o"${TEMP_ISO_DIR}" -- "${DEBIAN_DL_ISO_PATH}" > /dev/null rm -rf -- "${DEBIAN_DL_ISO_PATH}" ## Ensure to have the write permission on the extracted folder chmod 0700 -- "${TEMP_ISO_DIR}" # }}} # Manage initrd.gz file {{{ mkdir -- "${TEMP_INITRD_DIR}" ## Exclude initrd.gz files from xen and gtk directories INITRD_GZ_PATH=$(find "${TEMP_ISO_DIR}" -type f \( -path '*xen*' -o -path '*gtk*' \) -prune -o -name "initrd.gz" -print -quit) ## Copy it to a directory cp -- "${INITRD_GZ_PATH}" "${TEMP_INITRD_DIR}" || exit 2 cd -- "${TEMP_INITRD_DIR}" > /dev/null || exit 2 ## Uncompress initrd.gz then delete it gunzip < initrd.gz | cpio --extract --quiet --make-directories --no-absolute-filenames >> /dev/null rm -f -- initrd.gz ## Add preseed file cp -- "${PRESEED_FILE}" preseed.cfg || exit 2 ## Recompress to initrd.gz and move it back to the extracted files for ISO find . -not -name initrd.gz | cpio --format=newc --create --quiet | gzip --best > initrd.gz cp -- initrd.gz "${INITRD_GZ_PATH}" || exit 2 ## Go back to previous directory and remove no longer useful files cd - > /dev/null || exit 2 rm -rf -- "${TEMP_INITRD_DIR}" ## Fix permissions in install directory chmod -w -R -- $(dirname -- "${INITRD_GZ_PATH}") # }}} # Generate new md5sum {{{ ## Ensure to have the write permission on the iso folder chmod 0700 -- "${TEMP_ISO_DIR}" cd -- "${TEMP_ISO_DIR}" > /dev/null || exit 2 ## Exclude some unwanted files find . -follow -type f -not \( -name "md5sum.txt" -o -name 'mkisofs' -o -name 'Bootable_NoEmulation.img' -o -path '*isolinux*' \) -exec md5sum {} \; > ./md5sum.txt ## Fix md5sum.txt permissions chmod -w -- md5sum.txt cd - > /dev/null || exit 2 # }}} # Generate new bootable iso {{{ if [ -d "${TEMP_ISO_DIR}/isolinux" ] ; then xorriso -as mkisofs -o "${DEBIAN_PRESEED_ISO_PATH}" \ -quiet -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin \ -c isolinux/boot.cat -b isolinux/isolinux.bin -no-emul-boot \ -boot-load-size 4 -boot-info-table "${TEMP_ISO_DIR}" else ## For mini.iso creation xorriso -as mkisofs -o "${DEBIAN_PRESEED_ISO_PATH}" \ -quiet -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin \ -c boot.cat -b isolinux.bin -no-emul-boot \ -boot-load-size 4 -boot-info-table "${TEMP_ISO_DIR}" fi ## Then remove temp iso directory chmod u+w -R -- "${TEMP_ISO_DIR}" rm -rf -- "${TEMP_ISO_DIR}" # }}} rmdir -- "${TEMP_DIR}" printf '%b\n' "The new ISO image is available : ${DEBIAN_PRESEED_ISO_PATH}" exit 0