tftpboot/scripts/download_debian.sh

295 lines
7.7 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# Purpose {{{
# This script will download Debian netboot installer and make a sample
# menu.cfg config file.
# 1. Debian Stable (Trixie) amd64
# 2. Debian oldStable (Bookworm) amd64, i386
# 3. Debian Unstable (Sid) amd64
#
# Note: i386 is no longer provided as an installation architecture from
# Trixie onwards, so the architecture list is per-suite.
# }}}
# 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"
# Debian suites to fetch
DEBIAN_SUITES="trixie bookworm sid"
## 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.
Architectures are selected per suite: i386 is no longer provided
as an installation architecture from Trixie onwards.
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}"
}
# }}}
get_arch_list() { # {{{
# Return the list of architectures available for a given Debian suite.
# i386 was dropped as an installation architecture starting with Trixie.
local_distro="${1}"
case "${local_distro}" in
trixie|sid|forky )
return_arch_list="amd64"
;;
* )
return_arch_list="amd64 i386"
;;
esac
debug_message "get_arch_list \
Architectures for ${RED}${local_distro}${COLOR_DEBUG} : ${RED}${return_arch_list}${COLOR_DEBUG} ."
## Unset variables
unset local_distro
printf '%s' "${return_arch_list}"
}
# }}}
download_file() { # {{{
# Download a file to a temporary location and move it into place only if
# the transfer succeeded. A failed download therefore never overwrites a
# working file with an empty one.
local_url="${1}"
local_dest_file="${2}"
debug_message "download_file \
Download ${local_url} to ${RED}${local_dest_file}${COLOR_DEBUG} ."
local_tmp_file="${local_dest_file}.part"
if wget --quiet "${local_url}" --output-document="${local_tmp_file}"; then
mv -- "${local_tmp_file}" "${local_dest_file}"
return_download_file="0"
else
rm --force -- "${local_tmp_file}"
debug_message "download_file \
Download of ${RED}${local_url}${COLOR_DEBUG} failed."
return_download_file="1"
fi
## Unset variables
unset local_url
unset local_dest_file
unset local_tmp_file
return "${return_download_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 ${DEBIAN_SUITES}; do # For "all" Debian's version
## Architecture list depends on the suite
ARCH_LIST=$(get_arch_list "${DISTRO}")
## Then parse architecture
for ARCH in ${ARCH_LIST}; do
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" \
|| error_message "Can't download linux for ${DISTRO}/${ARCH} !" "2"
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" \
|| error_message "Can't download initrd.gz for ${DISTRO}/${ARCH} !" "2"
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