Skip to content

Instantly share code, notes, and snippets.

@john-clark
Created April 8, 2025 19:38
Show Gist options
  • Save john-clark/07f7108a57d08dd6df8f439927699b4f to your computer and use it in GitHub Desktop.
Save john-clark/07f7108a57d08dd6df8f439927699b4f to your computer and use it in GitHub Desktop.
menu driven iso generator for debian
#!/bin/bash
# Author: John Clark
# License: MIT License
# Copyright: © 2025 John Clark
# Description:
# This script is a comprehensive tool for creating, customizing, and managing Debian ISO images.
# It provides functionality to download Debian ISO images, extract and modify them,
# create preseed configuration files, and generate new ISO images with custom settings.
# The script uses `whiptail` for an interactive menu-driven interface.
# Features:
# - Download the latest Debian ISO images (stable, oldstable, archived, weekly testing, and unstable builds).
# - Extract ISO images and modify their contents.
# - Create and edit preseed configuration files for automated installations.
# - Customize package selection and generate override files.
# - Rebuild ISO images with custom configurations.
# - Validate required tools and dependencies before execution.
# Requirements:
# - Root privileges to execute the script.
# - Required tools: whiptail, wget, make, md5sum, xorriso, openssl (will install if missing).
# Usage:
# Run the script as root using the following command:
# sudo ./generate-debian-iso.sh
# Function to check if a command exists
command_exists() {
command -v "$1" &>/dev/null
}
# Variables
WORK_DIR=$(mktemp -d) # Temporary working directory
EXTRACTED_DIR="$WORK_DIR/debian_extracted"
MOUNT_DIR="$WORK_DIR/debian_mount"
ISO_FILE="" # This will hold the downloaded ISO filename
# check if the script is being run as root
check_root() {
if [ "$(id -u)" -ne 0 ]; then
whiptail --title "Root Privileges Required" --msgbox "This script must be run as root. Please run it with sudo." 8 78
return 1
fi
}
# Check if the necessary tools are installed and available
check_tools() {
required_tools=("whiptail" "wget" "make" "md5sum" "xorriso" "openssl")
# check if tools are installed
for tool in "${required_tools[@]}"; do
if ! command_exists "$tool"; then
whiptail --title "Missing Tool" --yesno "The required tool '$tool' is not installed. Would you like to install it?" 8 78
if [ $? -eq 0 ]; then
apt-get install -y "$tool"
else
whiptail --title "Installation Cancelled" --msgbox "Please install '$tool' manually and rerun the script." 8 78
return 1
fi
fi
done
# verify tools can be run
for tool in "${required_tools[@]}"; do
if ! command_exists "$tool"; then
whiptail --title "Tool Verification Failed" --msgbox "The tool '$tool' could not be verified. Please check your installation." 8 78
return 1
fi
done
whiptail --title "All Tools Installed" --msgbox "All required tools are installed." 8 78
}
cleanup() {
# Remove temporary directories and files
if [ -d "$EXTRACTED_DIR" ]; then
whiptail --title "Cleanup" --yesno "Do you want to remove the extracted directory?" 8 78
if [ $? -eq 0 ]; then
rm -rf "$EXTRACTED_DIR"
fi
fi
if [ -d "$WORK_DIR" ]; then
# prompt to remove directory
if [ -d "$WORK_DIR" ]; then
whiptail --title "Cleanup" --yesno "Do you want to remove the work directory?" 8 78
if [ $? -eq 0 ]; then
rm -rf "$WORK_DIR"
fi
fi
fi
if [ -f "$ISO_FILE" ]; then
# prompt to remove ISO
whiptail --title "Cleanup" --yesno "Do you want to remove the ISO file?" 8 78
if [ $? -eq 0 ]; then
rm -f "$ISO_FILE"
fi
fi
whiptail --title "Cleanup Complete" --msgbox "Temporary files and directories have been cleaned up." 8 78
}
# Function to download the Debian DVD-1 ISO
download_iso() {
declare -A debian_versions
debian_versions=()
# Check if there is already a downloaded ISO
if [ -n "$ISO_FILE" ] && [ -f "$ISO_FILE" ]; then
whiptail --title "ISO Already Downloaded" --msgbox "A Debian ISO is already downloaded: $ISO_FILE. Would you like to download a new one?" 8 78
if [ $? -ne 0 ]; then
return 1
fi
fi
# whiptail menu to choose the Debian architecture
ARCH=$(whiptail --title "Choose Debian Architecture" --menu "Select the architecture of Debian to download" 15 60 4 \
"amd64" "" \
"i386" "" \
"arm64" "" \
"armel" "" 3>&1 1>&2 2>&3)
if [ -z "$ARCH" ]; then
whiptail --title "Selection Error" --msgbox "No architecture selected. Please try again." 8 78
return 1
fi
# Get the latest stable release
VERSION=$(wget -qO- "https://cdimage.debian.org/cdimage/release/current/${ARCH}/iso-dvd/" | grep -o 'debian-[0-9]\+\.[0-9]\+\.[0-9]\+-'"${ARCH}"'-DVD-1\.iso' | head -n 1 | sed -E 's/debian-([0-9]+\.[0-9]+\.[0-9]+)-'"${ARCH}"'-DVD-1\.iso/\1/')
if [ -z "$VERSION" ]; then
whiptail --title "Version Detection Error" --msgbox "Failed to detect the latest stable release version." 8 78
return 1
fi
debian_versions["Stable Release (v$VERSION)"]="https://cdimage.debian.org/cdimage/release/current/${ARCH}/iso-dvd/debian-$VERSION-$ARCH-DVD-1.iso"
# Automatically detect the latest oldstable release
VERSION=$(wget -qO- https://cdimage.debian.org/cdimage/archive/ | grep -oP 'href="\K12\.[0-9]+\.[0-9]+' | sort -V | tail -n 1)
if [ -z "$VERSION" ]; then
whiptail --title "Version Detection Error" --msgbox "Failed to detect the latest oldstable release version." 8 78
fi
debian_versions["Oldstable Release (v$VERSION)"]="https://cdimage.debian.org/cdimage/archive/$VERSION/${ARCH}/iso-dvd/debian-$VERSION-$ARCH-DVD-1.iso"
# Automatically find the latest archived release
VERSION=$(wget -qO- https://cdimage.debian.org/cdimage/archive/ | grep -oP 'href="\K11\.\d+\.\d+(?=/)' | sort -V | tail -n 1)
if [ -z "$VERSION" ]; then
whiptail --title "Version Detection Error" --msgbox "Failed to detect the latest archived release version." 8 78
fi
debian_versions["Archived Release (v$VERSION)"]="https://cdimage.debian.org/cdimage/archive/$VERSION/${ARCH}/iso-dvd/debian-$VERSION-$ARCH-DVD-1.iso"
# Add weekly testing build to the array
debian_versions["Weekly Testing Build"]="https://cdimage.debian.org/cdimage/weekly-builds/${ARCH}/iso-dvd/debian-testing-$ARCH-DVD-1.iso"
# Add unstable build to the array
debian_versions["Unstable Build"]="https://cdimage.debian.org/cdimage/unstable/${ARCH}/iso-dvd/debian-unstable-$ARCH-DVD-1.iso"
# Add an option for a custom version
debian_versions["Custom Version"]="Enter a custom URL"
# Create an array with keys for whiptail
OPTIONS=()
declare -A key_map
sorted_versions=$(for version in "${!debian_versions[@]}"; do
echo "$version"
done | grep -E "Stable|Oldstable|Archived" | sort -r)
# Add sorted versions to the menu
n=1
while IFS= read -r version; do
OPTIONS+=("$n" "$version")
key_map["$n"]="$version"
((n++))
done <<< "$sorted_versions"
# Add Weekly Testing Build and Unstable Build
OPTIONS+=("$n" "Weekly Testing Build")
key_map["$n"]="Weekly Testing Build"
((n++))
OPTIONS+=("$n" "Unstable Build")
key_map["$n"]="Unstable Build"
((n++))
# Add Custom Version last
OPTIONS+=("$n" "Custom Version")
key_map["$n"]="Custom Version"
# Calculate the height of the menu dynamically
num_options=$(( ${#OPTIONS[@]} / 2 ))
height=$((num_options + 7))
[ $height -gt 15 ] && height=15
# Use whiptail to show the menu for selecting a Debian version
VERSION=$(whiptail --title "Choose Debian Version" --menu "Select the version of Debian to download" "$height" 80 "${num_options}" "${OPTIONS[@]}" 3>&1 1>&2 2>&3)
if [ $? -ne 0 ]; then
whiptail --title "Selection Cancelled" --msgbox "No version selected." 8 78
return 1
fi
# Map the numeric selection back to the corresponding key
selected_key="${key_map[$VERSION]}"
# Handle the selection and get the URL from the associative array
if [ "$selected_key" == "Custom Version" ]; then
# Prompt the user to enter a custom URL
ISO_URL=$(whiptail --title "Custom Debian ISO" --inputbox "Enter the URL of the Debian DVD-1 ISO:" 10 60 3>&1 1>&2 2>&3)
# Check if the user canceled or entered an empty URL
if [ $? -ne 0 ]; then
whiptail --title "Input Error" --msgbox "You canceled the input. Please try again." 8 60
return 1
elif [ -z "$ISO_URL" ]; then
whiptail --title "Input Error" --msgbox "No URL provided. Please try again." 8 60
return 1
fi
else
# Retrieve the URL from the associative array
ISO_URL=${debian_versions["$selected_key"]}
# Check if the URL is empty
if [ -z "$ISO_URL" ]; then
whiptail --title "Download Error" --msgbox "No URL found for the selected version. Please try again." 8 60
return 1
fi
fi
# Download the ISO
if [ -z "$ISO_URL" ]; then
whiptail --title "Download Error" --msgbox "No URL provided." 8 78
return 1
fi
# Download the ISO
ISO_FILE="$WORK_DIR/$VERSION"
wget -O "$ISO_FILE" "$ISO_URL"
if [ $? -ne 0 ]; then
whiptail --title "Download Error" --msgbox "Failed to download the ISO." 8 78
return 1
fi
whiptail --title "Download Complete" --msgbox "The Debian ISO has been downloaded successfully." 8 78
}
# Function to extract the ISO
diunpk() {
# Default values
local di_iso=${1:-$ISO_FILE}
local di_ro=${2:-$MOUNT_DIR}
local di_rw=${3:-$EXTRACTED_DIR}
# Ensure the ISO file exists
if [ ! -f "$di_iso" ]; then
whiptail --title "Error" --msgbox "The ISO file $di_iso does not exist." 8 78
return 1
fi
# Create read-only and read-write directories
mkdir -p "$di_ro"
mkdir -p "$di_rw"
# Mount the ISO image as read-only
mount "$di_iso" "$di_ro" -t iso9660 -o loop
if [ $? -ne 0 ]; then
whiptail --title "Error" --msgbox "Failed to mount the ISO image." 8 78
return 1
fi
# Create a work directory for overlayfs
mkdir -p "$WORK_DIR/work"
# Mount the overlay filesystem with read-write capabilities
mount -t overlay overlay -o lowerdir="$di_ro",upperdir="$di_rw",workdir="$WORK_DIR/work" "$di_rw"
if [ $? -ne 0 ]; then
whiptail --title "Error" --msgbox "Failed to mount the overlay filesystem." 8 78
umount "$di_ro"
return 1
fi
# Set write permissions
chmod u+w "$di_rw"
chmod u+w "$di_rw/md5sum.txt" 2>/dev/null || true
find "$di_rw/dists" -exec chmod u+w {} \; 2>/dev/null || true
find "$di_rw/pool" -type d -exec chmod u+w {} \; 2>/dev/null || true
whiptail --title "ISO Extraction" --msgbox "The ISO has been extracted to $di_rw." 8 78
return 0
}
# Function to create a new Debian ISO
dipk() {
# Local customization
local di_iso=${1:-d-i.iso}
local di_rw=${2:-$EXTRACTED_DIR}
# Detect release and architecture dynamically
local release=$(basename "$(find "$di_rw/dists" -mindepth 1 -maxdepth 1 -type d | head -n 1)")
local arch=$(basename "$(find "$di_rw/dists/$release/main/debian-installer" -mindepth 1 -maxdepth 1 -type d | grep binary- | sed 's/binary-//')")
if [ -z "$release" ] || [ -z "$arch" ]; then
whiptail --title "Error" --msgbox "Failed to detect release or architecture from the extracted ISO." 8 78
return 1
fi
# Generate the apt-ftparchive configuration file
cat > "$di_rw/config" << EOF
Dir {
ArchiveDir "$di_rw";
OverrideDir "$di_rw";
CacheDir "$di_rw";
};
TreeDefault {
Directory "pool/";
};
BinDirectory "pool/main" {
Packages "dists/${release}/main/binary-${arch}/Packages";
BinOverride "${di_rw}/binoverride";
};
Default {
Packages {
Extensions ".deb";
};
};
EOF
# Generate the apt-ftparchive configuration file for udebs
cat > "$di_rw/config-udeb" << EOF
Dir {
ArchiveDir "$di_rw";
OverrideDir "$di_rw";
CacheDir "$di_rw";
};
TreeDefault {
Directory "pool/";
};
BinDirectory "pool/main" {
Packages "dists/${release}/main/debian-installer/binary-${arch}/Packages";
BinOverride "${di_rw}/binoverride";
};
Default {
Packages {
Extensions ".udeb";
};
};
EOF
# Generate the Packages file for .deb packages
apt-ftparchive generate "$di_rw/config"
if [ $? -ne 0 ]; then
whiptail --title "Error" --msgbox "Failed to generate Packages file for .deb packages." 8 78
return 1
fi
# Generate the Packages file for .udeb packages
apt-ftparchive generate "$di_rw/config-udeb"
if [ $? -ne 0 ]; then
whiptail --title "Error" --msgbox "Failed to generate Packages file for .udeb packages." 8 78
return 1
fi
# Generate the Release file
apt-ftparchive release "$di_rw/dists/${release}" > "$di_rw/dists/${release}/Release"
if [ $? -ne 0 ]; then
whiptail --title "Error" --msgbox "Failed to generate Release file." 8 78
return 1
fi
# Generate the MD5 checksum file
md5sum $(find "$di_rw" -type f ! -name "md5sum.txt") > "$di_rw/md5sum.txt"
if [ $? -ne 0 ]; then
whiptail --title "Error" --msgbox "Failed to generate MD5 checksum file." 8 78
return 1
fi
# Generate the ISO image
genisoimage -r -o "$di_iso" -V "CustomDebian" \
-b isolinux/isolinux.bin -c isolinux/boot.cat \
-no-emul-boot -boot-load-size 4 -boot-info-table "$di_rw"
if [ $? -ne 0 ]; then
whiptail --title "Error" --msgbox "Failed to generate the ISO image." 8 78
return 1
fi
whiptail --title "ISO Creation" --msgbox "ISO image $di_iso has been successfully created." 8 78
return 0
}
# Function to extract the ISO
extract_iso() {
# Ensure the ISO file exists
if [ -z "$ISO_FILE" ] || [ ! -f "$ISO_FILE" ]; then
whiptail --title "Error" --msgbox "The ISO file does not exist. Please download the ISO first." 8 78
return 1
fi
# Create the extracted directory
mkdir -p "$EXTRACTED_DIR"
# Call diunpk with the correct ISO file and extracted directory
diunpk "$ISO_FILE" "$EXTRACTED_DIR"
if [ $? -ne 0 ]; then
whiptail --title "Extraction Error" --msgbox "Failed to extract the ISO." 8 78
return 1
fi
}
# Function to choose packages for the pool
choose_packages() {
# Ensure the extracted directory exists
if [ ! -d "$EXTRACTED_DIR" ]; then
whiptail --title "Error" --msgbox "The extracted directory does not exist. Please extract the ISO first." 8 78
return 1
fi
# Define the path for the binoverride file
local binoverride_file="$EXTRACTED_DIR/binoverride"
# Ensure the binoverride file exists or create an empty one
if [ ! -f "$binoverride_file" ]; then
> "$binoverride_file"
fi
# Define a default array of packages
DEFAULT_PACKAGES=("vim" "curl" "wget" "git" "build-essential" "python3" "apache")
# Read the package list from the binoverride file if it exists and is not empty
OPTIONS=()
if [ -s "$binoverride_file" ]; then
# If the binoverride file is not empty, read packages from it
while IFS= read -r line; do
package=$(echo "$line" | awk '{print $1}')
OPTIONS+=("$package" "" OFF)
done < "$binoverride_file"
else
# If the binoverride file is empty, use the default packages
for package in "${DEFAULT_PACKAGES[@]}"; do
OPTIONS+=("$package" "" OFF)
done
fi
# Display a checklist for package selection
selected_packages=$(whiptail --title "Choose Packages" --checklist \
"Select packages to include in the pool:" 15 60 8 \
"${OPTIONS[@]}" 3>&1 1>&2 2>&3)
# Handle user cancellation
if [ $? -ne 0 ]; then
whiptail --title "Selection Cancelled" --msgbox "No packages selected." 8 78
return 1
fi
# Convert the selected packages into an array
IFS=" " read -r -a SELECTED_PACKAGES <<< "$selected_packages"
# Update the binoverride file with user-defined priority and section
> "$binoverride_file" # Clear the existing binoverride file
for package in "${SELECTED_PACKAGES[@]}"; do
# Remove quotes around the package name
package=$(echo "$package" | tr -d '"')
# Prompt the user for priority and section for each selected package
priority=$(whiptail --title "Package Priority" --inputbox "Enter the priority for package $package (e.g., optional, important):" 10 60 "optional" 3>&1 1>&2 2>&3)
if [ $? -ne 0 ]; then
whiptail --title "Cancelled" --msgbox "Priority input cancelled for $package. Skipping..." 8 78
continue
fi
section=$(whiptail --title "Package Section" --inputbox "Enter the section for package $package (e.g., editors, net):" 10 60 "misc" 3>&1 1>&2 2>&3)
if [ $? -ne 0 ]; then
whiptail --title "Cancelled" --msgbox "Section input cancelled for $package. Skipping..." 8 78
continue
fi
# Add the package to the binoverride file
echo "$package $priority $section" >> "$binoverride_file"
done
whiptail --title "Packages Saved" --msgbox "The selected packages and their overrides have been saved successfully." 8 78
}
# Function to generate the override file
generate_md5sum() {
# Ensure the extracted directory exists
if [ ! -d "$EXTRACTED_DIR" ]; then
whiptail --title "Error" --msgbox "The extracted directory does not exist. Please extract the ISO first." 8 78
return 1
fi
# Generate the MD5 checksum file in the extracted directory
local md5_file="$EXTRACTED_DIR/md5sum.txt"
find "$EXTRACTED_DIR" -type f -exec md5sum {} \; > "$md5_file"
if [ $? -ne 0 ]; then
whiptail --title "Error" --msgbox "Failed to generate the MD5 checksum file." 8 78
return 1
fi
whiptail --title "MD5 Checksum Generated" --msgbox "The MD5 checksum file has been created successfully at $md5_file." 8 78
}
# Function to generate MD5 sum
generate_md5sum() {
# Ensure the extracted directory exists
if [ ! -d "$EXTRACTED_DIR" ]; then
whiptail --title "Error" --msgbox "The extracted directory does not exist. Please extract the ISO first." 8 78
return 1
fi
# Generate the MD5 checksum file in the extracted directory
local md5_file="$EXTRACTED_DIR/md5sum.txt"
find "$EXTRACTED_DIR" -type f -exec md5sum {} \; > "$md5_file"
if [ $? -ne 0 ]; then
whiptail --title "Error" --msgbox "Failed to generate the MD5 checksum file." 8 78
return 1
fi
whiptail --title "MD5 Checksum Generated" --msgbox "The MD5 checksum file has been created successfully at $md5_file." 8 78
}
create_preseed_cfg() {
# Define common values for the preseed file
# rootpassword
ROOT_PASS_ENCRYPTED="\$6\$rounds=4096\$FZ5F4qMlgVt2\$F9zFJtQAxmTTItdbdwDQaxWkh9OGOVAWm8Nz/27HV0a"
# userpassword
USER_PASS_ENCRYPTED="\$6\$rounds=4096\$PbE1bYr9dfb1\$mSuW7OSXnHzxaSzGRmWTnx0DTX2d4hZpy2K02x1ptFc"
PACKAGE_SELECTION="standard, ssh-server"
MIRROR_HOSTNAME="ftp.us.debian.org"
MIRROR_COUNTRY="US"
TIMEZONE="America/New_York"
KEYMAP_LOCALE="en_US.UTF-8"
cat <<EOF > debian_extracted/preseed.cfg
# Default preseed.cfg for automated Debian installation
# Language settings
d-i localechooser/language-name string en
d-i localechooser/locale string en_US.UTF-8
d-i keyboard-configuration/xkb-keymap select us
# Network configuration
d-i netcfg/choose_interface select auto
d-i netcfg/get_hostname string debian
# Timezone settings
d-i time/zone string $TIMEZONE
# Mirror settings
d-i mirror/country string $MIRROR_COUNTRY
d-i mirror/http/hostname string $MIRROR_HOSTNAME
d-i mirror/http/directory string /debian
# Disk partitioning (use entire disk)
d-i partman-auto/method string regular
d-i partman-auto/choose_recipe select atomic
# Package selection
tasksel tasksel/first multiselect $PACKAGE_SELECTION
# Set up the root password
d-i passwd/root-password-crypted password $ROOT_PASS_ENCRYPTED
# User account setup
d-i passwd/user-fullname string User
d-i passwd/username string user
d-i passwd/user-password-crypted password $USER_PASS_ENCRYPTED
# Autoinstallation settings
d-i preseed/early_command string anna-install libdebconfclient
d-i preseed/late_command string in-target apt-get update
# Reboot after installation
d-i finish-install/reboot_in_progress note
EOF
whiptail --title "Preseed File Created" --msgbox "The preseed.cfg has been created successfully." 8 78
}
# Function to edit preseed.cfg
edit_preseed() {
preseed_file="debian_extracted/preseed.cfg"
# If the preseed.cfg file doesn't exist, create it with default content
if [ ! -f "$preseed_file" ]; then
create_preseed_cfg
fi
# Allow the user to edit the preseed.cfg file using nano
vim "$preseed_file"
}
# Function to modify preseed.cfg with guided options
modify_preseed() {
preseed_file="debian_extracted/preseed.cfg"
# If preseed.cfg doesn't exist, create a default one
if [ ! -f "$preseed_file" ]; then
create_preseed_cfg
fi
while true; do
# Display a menu for modifying preseed settings
CHOICE=$(whiptail --title "Modify Preseed File" --menu "Select a setting to modify:" 15 60 7 \
"1" "Root Password" \
"2" "User Account" \
"3" "Package Selection" \
"4" "Timezone" \
"5" "Keyboard, Locale, and Language" \
"6" "Mirror Settings" \
"7" "Back to Main Menu" 3>&1 1>&2 2>&3)
# Handle user cancellation
if [ $? -ne 0 ]; then
break
fi
case $CHOICE in
1) # Modify root password
ROOT_PASS=$(whiptail --title "Root Password" --inputbox "Enter root password:" 10 60 "" 3>&1 1>&2 2>&3)
if [ $? -eq 0 ]; then
sed -i "s|^d-i passwd/root-password-crypted.*|d-i passwd/root-password-crypted password $ROOT_PASS|g" "$preseed_file"
fi
;;
2) # Modify user account details
USERNAME=$(whiptail --title "Username" --inputbox "Enter the username for the user account:" 10 60 "user" 3>&1 1>&2 2>&3)
USER_PASS=$(whiptail --title "User Password" --inputbox "Enter password for $USERNAME:" 10 60 "" 3>&1 1>&2 2>&3)
if [ $? -eq 0 ]; then
USER_PASS_ENCRYPTED=$(openssl passwd -6 "$USER_PASS")
sed -i "s|^d-i passwd/username.*|d-i passwd/username string $USERNAME|g" "$preseed_file"
sed -i "s|^d-i passwd/user-password-crypted.*|d-i passwd/user-password-crypted password $USER_PASS_ENCRYPTED|g" "$preseed_file"
fi
;;
3) # Modify package selection
PACKAGE_SELECTION=$(whiptail --title "Package Selection" --inputbox "Enter package selection (comma separated, e.g. ssh-server, standard):" 10 60 "ssh-server, standard" 3>&1 1>&2 2>&3)
if [ $? -eq 0 ]; then
sed -i "s|^tasksel tasksel/first.*|tasksel tasksel/first multiselect $PACKAGE_SELECTION|g" "$preseed_file"
fi
;;
4) # Modify timezone
TIMEZONE=$(whiptail --title "Timezone" --menu "Select your timezone" 15 60 5 \
"America/Chicago" "" \
"America/New_York" "" \
"Europe/London" "" \
"Asia/Kolkata" "" \
"Asia/Tokyo" "" 3>&1 1>&2 2>&3)
if [ $? -eq 0 ]; then
sed -i "s|^d-i time/zone.*|d-i time/zone string $TIMEZONE|g" "$preseed_file"
fi
;;
5) # Modify keyboard, locale, and language
KEYMAP_LOCALE=$(whiptail --title "Keyboard, Locale, and Language" --menu "Select keyboard, locale, and language" 15 60 5 \
"en_US.UTF-8" "" \
"fr_FR.UTF-8" "" \
"de_DE.UTF-8" "" \
"es_ES.UTF-8" "" \
"it_IT.UTF-8" "" 3>&1 1>&2 2>&3)
if [ $? -eq 0 ]; then
sed -i "s|^d-i localechooser/language-name.*|d-i localechooser/language-name string $KEYMAP_LOCALE|g" "$preseed_file"
sed -i "s|^d-i localechooser/locale.*|d-i localechooser/locale string $KEYMAP_LOCALE|g" "$preseed_file"
sed -i "s|^d-i keyboard-configuration/xkb-keymap.*|d-i keyboard-configuration/xkb-keymap select us|g" "$preseed_file"
fi
;;
6) # Modify mirror settings
MIRROR_HOSTNAME=$(whiptail --title "Mirror Hostname" --inputbox "Enter the mirror hostname (e.g. ftp.us.debian.org):" 10 60 "ftp.us.debian.org" 3>&1 1>&2 2>&3)
MIRROR_COUNTRY=$(whiptail --title "Mirror Country" --inputbox "Enter your mirror country code (e.g. US):" 10 60 "US" 3>&1 1>&2 2>&3)
if [ $? -eq 0 ]; then
sed -i "s|^d-i mirror/http/hostname.*|d-i mirror/http/hostname string $MIRROR_HOSTNAME|g" "$preseed_file"
sed -i "s|^d-i mirror/country.*|d-i mirror/country string $MIRROR_COUNTRY|g" "$preseed_file"
fi
;;
7) # Exit
break
;;
*) # Invalid option
whiptail --title "Invalid Option" --msgbox "Invalid option selected. Please try again." 8 60
;;
esac
done
whiptail --title "Preseed File Updated" --msgbox "The preseed.cfg has been updated successfully." 8 78
}
# Function to create the new image
create_new_image() {
# Define the paths for the extracted ISO and the output ISO
local di_rw=${1:-$EXTRACTED_DIR}
local di_iso=${2:-"$WORK_DIR/custom_debian.iso"}
# Call the dipk function to create the new ISO
dipk "$di_iso" "$di_rw"
if [ $? -ne 0 ]; then
whiptail --title "ISO Creation Error" --msgbox "Failed to create the new image." 8 78
return 1
fi
whiptail --title "ISO Created" --msgbox "The new image has been created successfully as $di_iso." 8 78
}
# Main menu function
main_menu() {
# Define menu options in an array (function and description)
local menu_options=(
"Download Debian ISO" "download_iso"
"Extract ISO" "extract_iso"
"Choose Packages" "choose_packages"
"Generate Override File" "generate_override"
"Edit preseed.cfg" "edit_preseed"
"Modify preseed.cfg" "modify_preseed"
"Generate MD5" "generate_md5sum"
"Create New Image" "create_new_image"
"Exit" "exit"
)
local num_items=$(( ${#menu_options[@]} ))
local height=10
while true; do
# Create the options array for whiptail
OPTIONS=()
n=1
for ((i = 0; i < num_items; i+=2)); do
OPTIONS+=("$n" "${menu_options[$i]}")
((n++))
done
# Show the menu with whiptail
CHOICE=$(whiptail --title "Debian ISO Creator" \
--menu "Choose an option" \
$((num_items / 2 + 7)) 60 $((num_items / 2)) \
"${OPTIONS[@]}" 3>&1 1>&2 2>&3)
# If the user canceled, exit
if [ $? -ne 0 ]; then
break
fi
# Find the corresponding function to call
for ((i = 0; i < num_items; i+=2)); do
if [[ "$((i / 2 + 1))" == "$CHOICE" ]]; then
FUNC="${menu_options[$((i + 1))]}" # Get the function name
break
fi
done
# Call the selected function if it's not "exit"
if [[ "$FUNC" != "exit" ]]; then
$FUNC
else
break
fi
done
}
# Main script execution
check_root
check_tools
main_menu
trap cleanup EXIT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment