Skip to content

Commit

Permalink
Use common functions for Debian ISO generation
Browse files Browse the repository at this point in the history
  • Loading branch information
dappnodedev committed May 30, 2024
1 parent ca0d9fd commit 45014a7
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 80 deletions.
61 changes: 61 additions & 0 deletions iso/scripts/common_functions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/bash

download_iso() {
local iso_path=$1
local iso_name=$2
local iso_url=$3

echo "[INFO] Downloading ISO image: ${iso_name}..."
if [ ! -f "${iso_path}" ]; then
wget "${iso_url}" -O "${iso_path}"
fi
echo "[INFO] Download complete!"
}

verify_download() {
local iso_path=$1
local expected_shasum=$2

echo "[INFO] Verifying download..."
local calculated_shasum=$(shasum -a 256 "${iso_path}" | awk '{ print $1 }')
if [ "${calculated_shasum}" != "${expected_shasum}" ]; then
echo "[ERROR] Wrong shasum"
exit 1
fi
echo "[INFO] Verification complete!"
}

clean_old_files() {
local iso_extraction_dir=$1
local base_iso_prefix=$2

echo "[INFO] Cleaning old files..."
rm -rf "${iso_extraction_dir}º"
rm -rf "${base_iso_prefix}*"
}

extract_iso() {
local iso_path=$1
local extraction_target_dir=$2

echo "[INFO] Extracting the ISO..."
osirrox -indev "${iso_path}" -extract / "${extraction_target_dir}"
}

# Using a 512-byte block size to ensure the entire Master Boot Record (MBR) is captured.
# The MBR contains boot code, the partition table, and a boot signature, all essential for creating bootable media.
# This ensures that the new ISO being created is bootable under different system setups
prepare_boot_process() {
local iso_path=$1
local mbr_output_path=$2
local block_size=512

echo "[INFO] Obtaining the MBR for hybrid ISO..."
dd if="${iso_path}" bs=${block_size} count=1 of="${mbr_output_path}"
}

handle_checksums() {
echo "Fix md5 sum..."
# shellcheck disable=SC2046
md5sum $(find ! -name "md5sum.txt" ! -path "./isolinux/*" -type f) >md5sum.txt
}
178 changes: 98 additions & 80 deletions iso/scripts/generate_dappnode_iso_debian.sh
Original file line number Diff line number Diff line change
@@ -1,86 +1,104 @@
#!/bin/bash
set -e

source /usr/src/app/iso/scripts/common_functions.sh

# Source = https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-12.5.0-amd64-netinst.iso
ISO_NAME=debian-12.5.0-amd64-netinst.iso
ISO_PATH="/images/${ISO_NAME}"
ISO_URL=https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/
SHASUM="013f5b44670d81280b5b1bc02455842b250df2f0c6763398feb69af1a805a14f ${ISO_PATH}"

echo "Downloading debian ISO image: ${ISO_NAME}..."
if [ ! -f ${ISO_PATH} ]; then
wget ${ISO_URL}/${ISO_NAME} \
-O ${ISO_PATH}
fi
echo "Done!"

echo "Verifying download..."
[[ "$(shasum -a 256 ${ISO_PATH})" != "$SHASUM" ]] && {
echo "ERROR: wrong shasum"
exit 1
BASE_ISO_NAME="debian-12.5.0-amd64-netinst.iso"
BASE_ISO_PATH="/images/${BASE_ISO_NAME}"
BASE_ISO_URL="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/${BASE_ISO_NAME}"
BASE_ISO_SHASUM="013f5b44670d81280b5b1bc02455842b250df2f0c6763398feb69af1a805a14f"

WORKDIR="/usr/src/app"
ISO_BUILD_PATH="${WORKDIR}/dappnode-iso"
DAPPNODE_ISO_PREFIX="Dappnode-"
DAPPNODE_ISO_NAME="${DAPPNODE_ISO_PREFIX}${BASE_ISO_NAME}"

download_third_party_packages() {
echo "[INFO] Downloading third-party packages..."
sed '1,/^\#\!ISOBUILD/!d' ${WORKDIR}/scripts/dappnode_install_pre.sh >/tmp/vars.sh
# shellcheck disable=SC1091
source /tmp/vars.sh
}

add_dappnode_files() {
echo "[INFO] Creating necessary directories and copying files..."
mkdir -p ${ISO_BUILD_PATH}/dappnode
cp -r ${WORKDIR}/scripts ${ISO_BUILD_PATH}/dappnode
cp -r ${WORKDIR}/dappnode/* ${ISO_BUILD_PATH}/dappnode
}

customize_debian_preseed() {
echo "[INFO] Customizing preseed..."

local tmp_initrd="/tmp/makeinitrd"
local install_dir="${ISO_BUILD_PATH}/install.amd"
local preseeds_dir="${WORKDIR}/iso/preseeds"

rm -rf "${tmp_initrd}"
mkdir -p "${tmp_initrd}"

local preseed_name="preseed.cfg"
[[ $UNATTENDED == *"true"* ]] && preseed_name="preseed_unattended.cfg"

local preseed_file="${preseeds_dir}/${preseed_name}"

if [ ! -f "${preseed_file}" ]; then
echo "[ERROR] Preseed file not found: ${preseed_file}"
exit 1
fi

# Extract the initrd into a temporary directory
gunzip -c "${install_dir}/initrd.gz" | cpio -idum -D "${tmp_initrd}" || {
echo "[ERROR] Could not decompress and extract initrd"
exit 1
}

# Add the preseed file to the initrd
cp "${preseed_file}" "${tmp_initrd}/preseed.cfg" || {
echo "[ERROR] Could not copy preseed file"
exit 1
}

# Recreate (and recompress) the initrd
(cd "${tmp_initrd}" && find . -print0 | cpio -0 -ov -H newc | gzip >"${install_dir}/initrd.gz") || {
echo "[ERROR] Could not create new initrd"
exit 1
}

echo "[INFO] Preseed customization complete."
}

configure_boot_menu() {
local boot_dir="${WORKDIR}/iso/boot"

echo "[INFO] Configuring the boot menu for Dappnode..."
cp ${boot_dir}/grub.cfg ${ISO_BUILD_PATH}/boot/grub/grub.cfg
cp ${boot_dir}/theme_1 ${ISO_BUILD_PATH}/boot/grub/theme/1
cp ${boot_dir}/isolinux.cfg ${ISO_BUILD_PATH}/isolinux/isolinux.cfg
cp ${boot_dir}/menu.cfg ${ISO_BUILD_PATH}/isolinux/menu.cfg
cp ${boot_dir}/txt.cfg ${ISO_BUILD_PATH}/isolinux/txt.cfg
cp ${boot_dir}/splash.png ${ISO_BUILD_PATH}/isolinux/splash.png
}

generate_debian_iso() {

echo "[INFO] Generating new ISO..."

xorriso -as mkisofs -isohybrid-mbr ${ISO_BUILD_PATH}/isolinux/isohdpfx.bin \
-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 -o "/images/${DAPPNODE_ISO_NAME}" ${ISO_BUILD_PATH}
}

echo "Clean old files..."
rm -rf dappnode-isoº
rm -rf DappNode-debian-*

echo "Extracting the iso..."
osirrox -indev /images/${ISO_NAME} -extract / dappnode-iso

# Using a 512-byte block size to ensure the entire Master Boot Record (MBR) is captured.
# The MBR contains boot code, the partition table, and a boot signature, all essential for creating bootable media.
# This ensures that the new ISO being created is bootable under different system setups
echo "Obtaining the isohdpfx.bin for hybrid ISO..."
dd if=/images/${ISO_NAME} bs=512 count=1 of=dappnode-iso/isolinux/isohdpfx.bin

cd /usr/src/app/dappnode-iso # /usr/src/app/dappnode-iso

echo "Downloading third-party packages..."
sed '1,/^\#\!ISOBUILD/!d' /usr/src/app/scripts/dappnode_install_pre.sh >/tmp/vars.sh
# shellcheck disable=SC1091
source /tmp/vars.sh

echo "Creating necessary directories and copying files..."
mkdir -p /usr/src/app/dappnode-iso/dappnode
cp -r /usr/src/app/scripts /usr/src/app/dappnode-iso/dappnode
cp -r /usr/src/app/dappnode/* /usr/src/app/dappnode-iso/dappnode

echo "Customizing preseed..."
mkdir -p /tmp/makeinitrd
cd install.amd
cp initrd.gz /tmp/makeinitrd/
if [[ $UNATTENDED == *"true"* ]]; then
cp /usr/src/app/iso/preseeds/preseed_unattended.cfg /tmp/makeinitrd/preseed.cfg
else
cp /usr/src/app/iso/preseeds/preseed.cfg /tmp/makeinitrd/preseed.cfg
fi
cd /tmp/makeinitrd
gunzip initrd.gz
cpio -id -H newc <initrd
# shellcheck disable=SC2002
cat initrd | cpio -t >/tmp/list
echo "preseed.cfg" >>/tmp/list
rm initrd
cpio -o -H newc </tmp/list >initrd
gzip initrd
cd -
mv /tmp/makeinitrd/initrd.gz ./initrd.gz
cd ..

echo "Configuring the boot menu for DappNode..."
cp /usr/src/app/iso/boot/grub.cfg boot/grub/grub.cfg
cp /usr/src/app/iso/boot/theme_1 boot/grub/theme/1
cp /usr/src/app/iso/boot/isolinux.cfg isolinux/isolinux.cfg
cp /usr/src/app/iso/boot/menu.cfg isolinux/menu.cfg
cp /usr/src/app/iso/boot/txt.cfg isolinux/txt.cfg
cp /usr/src/app/iso/boot/splash.png isolinux/splash.png

echo "Fix md5 sum..."
# shellcheck disable=SC2046
md5sum $(find ! -name "md5sum.txt" ! -path "./isolinux/*" -type f) >md5sum.txt

echo "Generating new iso..."
xorriso -as mkisofs -isohybrid-mbr isolinux/isohdpfx.bin \
-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 -o /images/DAppNode-debian-bookworm-amd64.iso .
download_iso "${BASE_ISO_PATH}" "${BASE_ISO_NAME}" "${BASE_ISO_URL}"
verify_download "${BASE_ISO_PATH}" "${BASE_ISO_SHASUM}"
clean_old_files "${ISO_BUILD_PATH}" "${DAPPNODE_ISO_PREFIX}"
extract_iso "${BASE_ISO_PATH}" "${ISO_BUILD_PATH}"
prepare_boot_process "${BASE_ISO_PATH}" "${ISO_BUILD_PATH}/isolinux/isohdpfx.bin"
download_third_party_packages
add_dappnode_files
customize_debian_preseed
configure_boot_menu
handle_checksums # TODO: Check if it fits both ubuntu and debian
generate_debian_iso

0 comments on commit 45014a7

Please sign in to comment.