#!/bin/bash # Purpose {{{ # This script will download Clonezilla Stable installer for both AMD64 and i368 # 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 CZ_INSTALLER_DIR="${TFTP_DIRECTORY}/installer/clonezilla" CZ_CONFIG_PXE="${CZ_INSTALLER_DIR}/menu.cfg.example" # Get latest version from https://clonezilla.org CZ_VERSION_DEFAULT="$(curl --no-progress-meter https://clonezilla.org/downloads.php | sed --silent 's;.*stable.*\(.*\).*;\1;p')" ## 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|-v] This script will download Clonezilla Stable for both AMD64 and i368 architectures. EXAMPLES : - Download Clonezilla's to default place (${TFTP_DIRECTORY}). ${PROGNAME} - Download a specific version of Clonezilla (default : ${CZ_VERSION_DEFAULT}). ${PROGNAME} --version "2.7.1" OPTIONS : -v,--version Define the version of Clonezilla to download. -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}" } # }}} define_vars() { # {{{ # If cz_version wasn't defined (argument) {{{ if [ -z "${cz_version}" ]; then ## Use default value cz_version="${CZ_VERSION_DEFAULT}" fi # }}} } # }}} is_var_empty() { # {{{ ## Return False by default return_var_empty="1" ## Total number of variables to test local_total_var="${#}" loop_count_var_empty="0" ## While it remains a variable to test while [ "${local_total_var}" -gt "${loop_count_var_empty}" ]; do debug_message "is_var_empty − \ Test var: ${1}." ### Test if this is empty and set return value to True [ -z "${1}" ] && return_var_empty="0" ### Increase the number of tested variables loop_count_var_empty=$((loop_count_var_empty+1)) ### Shift to the next variable shift done return "${return_var_empty}" } # }}} is_file_absent() { # {{{ local_file_absent="${1}" ## File exists by default return_is_file_absent="1" ### Check if the file exists # shellcheck disable=SC2086 if find ${local_file_absent} > /dev/null 2>&1; then return_is_file_absent="1" debug_message "is_file_absent − \ The file ${RED}${local_file_absent}${COLOR_DEBUG} exists." else return_is_file_absent="0" debug_message "is_file_absent − \ The file ${RED}${local_file_absent}${COLOR_DEBUG} doesn't exist." fi return "${return_is_file_absent}" } # }}} 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() { # {{{ # Define all vars define_vars # If cz_version is empty {{{ # Exit with error is_var_empty "${cz_version}" \ && error_message "Clonezilla version variable is empty" 6 # }}} # Create directories and config file debug_message "Main − \ Create ${CZ_INSTALLER_DIR} tree." mkdir --parents -- "${CZ_INSTALLER_DIR}" \ || error_message "Can't create ${CZ_INSTALLER_DIR}/ directory." 1 true > "${CZ_CONFIG_PXE}" for ARCH in amd64 i686; do # For available classic architectures #CZ_URL="https://osdn.jp/dl/clonezilla/clonezilla-live-${cz_version}-${ARCH}.zip" CZ_URL="https://sourceforge.net/projects/clonezilla/files/clonezilla_live_stable/${cz_version}/clonezilla-live-${cz_version}-${ARCH}.zip/download" CZ_TEMP_FILE="/tmp/clonezilla-live-${cz_version}-${ARCH}.zip" ## If this version is not already present on the system if is_file_absent "${CZ_INSTALLER_DIR}/${ARCH}/${cz_version}"; then ### Recreate directory and go rm --recursive --force -- "${CZ_INSTALLER_DIR}/${ARCH}" mkdir --parents -- "${CZ_INSTALLER_DIR}/${ARCH}" \ || error_message "Can't create ${CZ_INSTALLER_DIR}/${ARCH}/ directory." 1 pushd "${CZ_INSTALLER_DIR}/${ARCH}" > /dev/null \ || error_message "Can't move to ${CZ_INSTALLER_DIR}/${ARCH} temp directory." 2 ### Download and extract only PXE files {{{ download_file "${CZ_URL}" "${CZ_TEMP_FILE}" is_file_empty "${CZ_TEMP_FILE}" \ && error_message "${CZ_TEMP_FILE} is empty." 3 debug_message "FOR loop − ${ARCH} − \ Uncompress PXE files from ${CZ_TEMP_FILE} ." unzip -qq -j "${CZ_TEMP_FILE}" live/vmlinuz live/initrd.img live/filesystem.squashfs -d . \ || error_message "Can't properly extract ${CZ_TEMP_FILE} archive." ### }}} ### Remove temp file rm --force -- "${CZ_TEMP_FILE}" \ || error_message "Can't remove ${CZ_TEMP_FILE} temp file." ### Add flag file to know that this version is available true > "${CZ_INSTALLER_DIR}/${ARCH}/${cz_version}" popd > /dev/null \ || error_message "Can't move back from ${CZ_INSTALLER_DIR}/${ARCH}/ directory." 2 fi ## Add informations to sample config file /bin/cat >> "${CZ_CONFIG_PXE}" << EOF label live${ARCH} menu label Clonezilla Live ^${ARCH} kernel installer/clonezilla/${ARCH}/vmlinuz APPEND initrd=installer/clonezilla/${ARCH}/initrd.img boot=live username=user union=overlay config components quiet noswap edd=on nomodeset nodmraid locales= keyboard-layouts= ocs_live_run="ocs-live-general" ocs_live_extra_param="" ocs_live_batch=no net.ifnames=0 nosplash noprompt fetch=tftp://129.20.203.27/installer/clonezilla/${ARCH}/filesystem.squashfs EOF done # Add separator and menu to sample config file /bin/cat >> "${CZ_CONFIG_PXE}" << EOF label separator menu label ----- 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 -v|--version ) ## Define cz_version ## Move to the next argument shift ## Define var readonly cz_version="${1}" ;; -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