#!/bin/bash # Purpose {{{ # This script will download Debian netboot installer for both AMD64 and i368 # 1. Debian oldStable (Bookworm) # 2. Debian oldStable (Bullseye) # 3. Debian Unstable (Sid) # and make a sample menu.cfg config file. # }}} # Vars {{{ readonly PROGNAME=$(basename "${0}") readonly NBARGS="${#}" [ -z "${DEBUG}" ] && DEBUG=1 ## Export DEBUG for sub-script export DEBUG # Default value for TFTP's directory if command -v in.tftpd > /dev/null; then source /etc/default/tftpd-hpa else TFTP_DIRECTORY="/srv/tftp" fi # Where to store Debian's installers DEBIAN_INSTALLER_DIR="${TFTP_DIRECTORY}/installer/debian" # tftp sample config file DEBIAN_CONFIG_PXE="${DEBIAN_INSTALLER_DIR}/menu.cfg.example" ## Colors readonly PURPLE='\033[1;35m' readonly RED='\033[0;31m' readonly RESET='\033[0m' readonly COLOR_DEBUG="${PURPLE}" # }}} usage() { # {{{ cat <<- EOF usage: $PROGNAME [-d|-h] This script will download "all" Debian's netboot installer for tftp server for both AMD64 and i368 architectures. EXAMPLES : - Download Debian's installers to default place (${TFTP_DIRECTORY}) ${PROGNAME} OPTIONS : -d,--debug Enable debug messages. -h,--help Print this help message. EOF } # }}} debug_message() { # {{{ local_message="${1}" ## Print message if DEBUG is enable (=0) [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6b\e[m\n' "DEBUG − ${PROGNAME} : ${local_message}" return 0 } # }}} error_message() { # {{{ local_error_message="${1}" local_error_code="${2}" ## Print message printf '%b\n' "ERROR − ${PROGNAME} : ${RED}${local_error_message}${RESET}" exit "${local_error_code:=66}" } # }}} download_file() { # {{{ local_url="${1}" local_dest_file="${2}" debug_message "download_file − \ Download ${local_url} to ${RED}${local_dest_file}${COLOR_DEBUG} ." wget --quiet "${local_url}" --output-document="${local_dest_file}" ## Unset variables unset local_url unset local_dest_file } # }}} is_file_empty() { # {{{ local_file="${1}" ## File is empty by default return_is_file_empty="0" ### Check if the file is empty if [ ! -s "${local_file}" ]; then return_is_file_empty="0" debug_message "is_file_empty − \ The file ${RED}${local_file}${COLOR_DEBUG} is empty or doesn't exists." else return_is_file_empty="1" debug_message "is_file_empty − \ The file ${RED}${local_file}${COLOR_DEBUG} exists and has a size greater than zero." fi ## Unset variables unset local_file return "${return_is_file_empty}" } # }}} main() { # {{{ # Create directories and config file debug_message "Main − \ Create ${DEBIAN_INSTALLER_DIR} tree." mkdir --parents -- "${DEBIAN_INSTALLER_DIR}" \ || error_message "Can't create ${DEBIAN_INSTALLER_DIR} directory." "1" debug_message "Main − \ (re)Create ${DEBIAN_CONFIG_PXE} sample config file." true > "${DEBIAN_CONFIG_PXE}" # Parse all Debian's distribution for DISTRO in bookworm bullseye sid; do # For "all" Debian's version ## Then parse architecture for ARCH in amd64 i386; do # For all classic architecture debug_message "Main FOR loop − \ Manage ${RED}${DISTRO}${COLOR_DEBUG} release with ${RED}${ARCH}${COLOR_DEBUG} architecture." ### Create destination directory mkdir --parents -- ${DEBIAN_INSTALLER_DIR}/${DISTRO}/${ARCH} \ || error_message "Can't create ${DEBIAN_INSTALLER_DIR}/${DISTRO}/${ARCH} tree." "1" ### Download linux file download_file "http://deb.debian.org/debian/dists/${DISTRO}/main/installer-${ARCH}/current/images/netboot/debian-installer/${ARCH}/linux" \ "${DEBIAN_INSTALLER_DIR}/${DISTRO}/${ARCH}/linux" is_file_empty "${DEBIAN_INSTALLER_DIR}/${DISTRO}/${ARCH}/linux" \ && error_message "${DEBIAN_INSTALLER_DIR}/${DISTRO}/${ARCH}/linux is empty !" "2" ### Download initrd.gz download_file "http://deb.debian.org/debian/dists/${DISTRO}/main/installer-${ARCH}/current/images/netboot/debian-installer/${ARCH}/initrd.gz" \ "${DEBIAN_INSTALLER_DIR}/${DISTRO}/${ARCH}/initrd.gz" is_file_empty "${DEBIAN_INSTALLER_DIR}/${DISTRO}/${ARCH}/initrd.gz" \ && error_message "${DEBIAN_INSTALLER_DIR}/${DISTRO}/${ARCH}/initrd.gz is empty !" "2" ### Config file debug_message "Main FOR loop − \ Add tftp config sample." /bin/cat >> "${DEBIAN_CONFIG_PXE}" << EOF label ${DISTRO}${ARCH} menu label Debian GNU/Linux ${DISTRO} ^${ARCH} bits kernel installer/debian/${DISTRO}/${ARCH}/linux append vga=normal initrd=installer/debian/${DISTRO}/${ARCH}/initrd.gz -- quiet EOF done # Config file /bin/cat >> "${DEBIAN_CONFIG_PXE}" << EOF label separator menu label --- EOF done # Config file /bin/cat >> "${DEBIAN_CONFIG_PXE}" << EOF label mainmenu menu label ^Back... menu exit EOF } # }}} # Manage arguments # {{{ # This code can't be in a function due to argument management if [ ! "${NBARGS}" -eq "0" ]; then manage_arg="0" ## If the first argument is not an option if ! printf -- '%s' "${1}" | grep -q -E -- "^-+"; then ## Print help message and exit printf '%b\n' "${RED}Invalid option: ${1}${RESET}" printf '%b\n' "---" usage exit 1 fi # Parse all options (start with a "-") one by one while printf -- '%s' "${1}" | grep -q -E -- "^-+"; do case "${1}" in -d|--debug ) ## debug DEBUG=0 ;; -h|--help ) ## help usage ## Exit after help informations exit 0 ;; * ) ## unknow option printf '%b\n' "${RED}Invalid option: ${1}${RESET}" printf '%b\n' "---" usage exit 1 ;; esac debug_message "Arguments management − \ ${RED}${1}${COLOR_DEBUG} option managed." ## Move to the next argument shift manage_arg=$((manage_arg+1)) done debug_message "Arguments management − \ ${RED}${manage_arg}${COLOR_DEBUG} argument(s) successfully managed." else debug_message "Arguments management − \ No arguments/options to manage." fi # }}} main exit 0