From: Christian Heller Date: Tue, 19 Aug 2025 02:27:53 +0000 (+0200) Subject: Fixes. X-Git-Url: https://plomlompom.com/repos/blog?a=commitdiff_plain;h=32662f463246710ed64ddbfdf9136c299fb9c059;p=config Fixes. --- diff --git a/trixie/scripts/lib/apt_digested.sh b/trixie/scripts/lib/apt_digested.sh new file mode 100644 index 0000000..a6abe64 --- /dev/null +++ b/trixie/scripts/lib/apt_digested.sh @@ -0,0 +1,205 @@ +. lib/prefixed_msg.sh + +# NB: to avoid confusing the IFS handling, ensure none of the lines is empty – +# even if ignored! +apt_digested_SEDS=$(cat << "DELIMITER" +Get: +Get:[[:digit:]]+ (.*) +\1 +-------------------- +Hit: +Hit:[[:digit:]]+ (.*) +\1 +-------------------- +. +Generation complete. +IGNORE +-------------------- +. +Preconfiguring packages \.\.\. +IGNORE +-------------------- +. +Preparing to unpack [[:print:]]+ \.\.\. +IGNORE +-------------------- +. +Unpacking [[:print:]]+ \([[:print:]]+\)( over \([[:print:]]+\))? \.\.\. +IGNORE +-------------------- +Adding diversion(s): +Adding 'diversion of ([[:print:]]+) to ([[:print:]]+) by ([[:print:]]+)' + \3:[\1 → \2] +-------------------- +Created symlink(s): +Created symlink '([[:print:]]+)' → '([[:print:]]+)'\. + [\1 → \2] +-------------------- +Installing new version of config file(s): +Installing new version of config file ([[:print:]]+) \.\.\. +\1 +-------------------- +Processing triggers for: +Processing triggers for ([[:print:]]+) \([[:print:]]+\) \.\.\. +\1 +-------------------- +Purging configuration files: +Purging configuration files for ([[:print:]]+) \([[:print:]]+\) \.\.\. +\1 +-------------------- +Removing: +Removing ([[:print:]]+) \([[:print:]]+\) \.\.\. +\1 +-------------------- +Removing diversion(s): +Removing 'diversion of ([[:print:]]+) to ([[:print:]]+) by ([[:print:]]+) + \3:[\1 → \2] +-------------------- +Removing obsolete conffile(s): +Removing obsolete conffile ([[:print:]]+) \.\.\. +\1 +-------------------- +Selecting previously unselected: +Selecting previously unselected package ([[:print:]]+)\. +\1 +-------------------- +Setting up: +Setting up ([[:print:]]+) \([[:print:]]+\) \.\.\. +\1 +-------------------- +Updating to current default: +Updating ([[:print:]]+) to current default. +\1 +-------------------- +disabled or static unit, so not starting: +([[:print:]]+) is a disabled or a static unit, not starting it\. +\1 +-------------------- + +disabled or static unit not running, so not starting: +([[:print:]]+) is a disabled or a static unit not running, not starting it\. +\1 +-------------------- +dpkg warns: unable to delete old directories (not empty): +dpkg: warning: unable to delete old directory '"'"'([[:print:]]+)'"'"': Directory not empty +\1 +-------------------- +update-alternatives: providing in auto mode: +update-alternatives: using ([[:print:]]+) to provide ([[:print:]]+) \(([[:print:]]+)\) in auto mode + [\1 → \2 (\3)] +-------------------- +Warning: Problem unlinking files (Remove Caches/13: Permission denied): +Warning: Problem unlinking the file ([[:print:]]+) - RemoveCaches \(13: Permission denied\) +\1 +-------------------- +. +\(Reading database \.\.\. .* +IGNORE +-------------------- +. +WARNING: apt does not have a stable CLI interface.* +IGNORE +-------------------- +Warning: Problem unlinking files (Remove Caches/13: Permission denied): +Warning: Problem unlinking the file ([[:print:]]+) - RemoveCaches \(13: Permission denied\) +\1 +-------------------- +FOLLOW_PREFIX +([[:print:]]+) depends on ([[:print:]]+)( \([>=]+ [[:print:]]+\))?\. +[\2 → \1] +-------------------- +BECOME_NEXT_PREFIX +dpkg: ([[:print:]]+): dependency problems, but removing anyway as you requested: +dpkg warns: removing \1 despite dependency problems: +-------------------- +DELIMITER +) + +apt_digested() { + prefixed_msg_init 'apt_digested' + local APT_GET_EXIT_CODE + local FINISH_LINE='apt_digested_FINISH_LINE' + + run_apt() { + set +e + DEBIAN_FRONTEND=noninteractive apt -y "$@" + APT_GET_EXIT_CODE=$? + set -e + echo "${FINISH_LINE} ${APT_GET_EXIT_CODE}" + } + + local OUR_NEWLINE='\r' # be \n\r except on 1st run, so no empty 1st line + local LAST_PREFIX= + local LEADER_PREFIX + local APT_LINE + run_apt "$@" 2>&1 | while read -r APT_LINE; do + APT_LINE=$(printf '%s' "${APT_LINE}" | tr -d '\r') + if [ -z "${APT_LINE}" ]; then + continue + else + local FIRST_FIELD + FIRST_FIELD=$(echo "${APT_LINE}" | cut -d' ' -f1) + if [ "${FIRST_FIELD}" = "${FINISH_LINE}" ]; then + printf '%s' "${OUR_NEWLINE}" + local EXIT_CODE + EXIT_CODE=$(echo "${APT_LINE}" | cut -d' ' -f2) + if [ "${EXIT_CODE}" != "0" ]; then + false + fi + break + fi + fi + local COMPRESSED_ITEM= + local PREFIX + local PATTERN + local REPLACEMENT + local I=0 + local LINE + local OLD_IFS=${IFS} + local IFS + IFS=$(printf '\n\r') + for LINE in ${apt_digested_SEDS}; do + I=$((1 + "$I")) + if [ "$I" -eq 1 ]; then + PREFIX="${LINE}" + continue + elif [ "$I" -eq 2 ]; then + PATTERN="${LINE}" + continue + elif [ "$I" -eq 3 ]; then + REPLACEMENT="${LINE}" + continue + elif [ "$I" -eq 4 ]; then + I=0 + fi + if printf '%s' "${APT_LINE}" | grep -E "${PATTERN}" > /dev/null; then + COMPRESSED_ITEM=$(printf '%s' "${APT_LINE}" | sed -E "s|${PATTERN}|${REPLACEMENT}|") + #if [ "${PREFIX}" = "BECOME_NEXT_PREFIX" ]; then + # LEADER_PREFIX="${COMPRESSED_ITEM}" + # COMPRESSED_ITEM=IGNORE + #elif [ "${PREFIX}" = "FOLLOW_PREFIX" ]; then + # PREFIX="${LEADER_PREFIX}" + #fi + break + fi + done + IFS=${OLD_IFS} + if [ "${COMPRESSED_ITEM}" = 'IGNORE' ]; then + continue + elif [ -z "${COMPRESSED_ITEM}" ]; then + printf '%s' "${OUR_NEWLINE}" + prefixed_msg_no_nl "${APT_LINE}" + LAST_PREFIX= + else + if [ "${PREFIX}" != "${LAST_PREFIX}" ]; then + printf '%s' "${OUR_NEWLINE}" + prefixed_msg_no_nl "# ${PREFIX}" + LAST_PREFIX="${PREFIX}" + fi + printf ' %s' "${COMPRESSED_ITEM}" + fi + OUR_NEWLINE='\n\r' + done + + prefixed_msg_exit +} diff --git a/trixie/scripts/lib/apt_get_digested.sh b/trixie/scripts/lib/apt_get_digested.sh deleted file mode 100644 index df4baa7..0000000 --- a/trixie/scripts/lib/apt_get_digested.sh +++ /dev/null @@ -1,205 +0,0 @@ -. lib/prefixed_msg.sh - -# NB: to avoid confusing the IFS handling, ensure none of the lines is empty – -# even if ignored! -apt_get_digested_SEDS=$(cat << "DELIMITER" -Get: -Get:[[:digit:]]+ (.*) -\1 --------------------- -Hit: -Hit:[[:digit:]]+ (.*) -\1 --------------------- -. -Generation complete. -IGNORE --------------------- -. -Preconfiguring packages \.\.\. -IGNORE --------------------- -. -Preparing to unpack [[:print:]]+ \.\.\. -IGNORE --------------------- -. -Unpacking [[:print:]]+ \([[:print:]]+\)( over \([[:print:]]+\))? \.\.\. -IGNORE --------------------- -Adding diversion(s): -Adding 'diversion of ([[:print:]]+) to ([[:print:]]+) by ([[:print:]]+)' - \3:[\1 → \2] --------------------- -Created symlink(s): -Created symlink '([[:print:]]+)' → '([[:print:]]+)'\. - [\1 → \2] --------------------- -Installing new version of config file(s): -Installing new version of config file ([[:print:]]+) \.\.\. -\1 --------------------- -Processing triggers for: -Processing triggers for ([[:print:]]+) \([[:print:]]+\) \.\.\. -\1 --------------------- -Purging configuration files: -Purging configuration files for ([[:print:]]+) \([[:print:]]+\) \.\.\. -\1 --------------------- -Removing: -Removing ([[:print:]]+) \([[:print:]]+\) \.\.\. -\1 --------------------- -Removing diversion(s): -Removing 'diversion of ([[:print:]]+) to ([[:print:]]+) by ([[:print:]]+) - \3:[\1 → \2] --------------------- -Removing obsolete conffile(s): -Removing obsolete conffile ([[:print:]]+) \.\.\. -\1 --------------------- -Selecting previously unselected: -Selecting previously unselected package ([[:print:]]+)\. -\1 --------------------- -Setting up: -Setting up ([[:print:]]+) \([[:print:]]+\) \.\.\. -\1 --------------------- -Updating to current default: -Updating ([[:print:]]+) to current default. -\1 --------------------- -disabled or static unit, so not starting: -([[:print:]]+) is a disabled or a static unit, not starting it\. -\1 --------------------- - -disabled or static unit not running, so not starting: -([[:print:]]+) is a disabled or a static unit not running, not starting it\. -\1 --------------------- -dpkg warns: unable to delete old directories (not empty): -dpkg: warning: unable to delete old directory '"'"'([[:print:]]+)'"'"': Directory not empty -\1 --------------------- -update-alternatives: providing in auto mode: -update-alternatives: using ([[:print:]]+) to provide ([[:print:]]+) \(([[:print:]]+)\) in auto mode - [\1 → \2 (\3)] --------------------- -Warning: Problem unlinking files (Remove Caches/13: Permission denied): -Warning: Problem unlinking the file ([[:print:]]+) - RemoveCaches \(13: Permission denied\) -\1 --------------------- -. -\(Reading database \.\.\. .* -IGNORE --------------------- -. -WARNING: apt does not have a stable CLI interface.* -IGNORE --------------------- -Warning: Problem unlinking files (Remove Caches/13: Permission denied): -Warning: Problem unlinking the file ([[:print:]]+) - RemoveCaches \(13: Permission denied\) -\1 --------------------- -FOLLOW_PREFIX -([[:print:]]+) depends on ([[:print:]]+)( \([>=]+ [[:print:]]+\))?\. -[\2 → \1] --------------------- -BECOME_NEXT_PREFIX -dpkg: ([[:print:]]+): dependency problems, but removing anyway as you requested: -dpkg warns: removing \1 despite dependency problems: --------------------- -DELIMITER -) - -apt_get_digested() { - prefixed_msg_init 'apt_get_digested' - local APT_GET_EXIT_CODE - local FINISH_LINE='apt_get_digested_FINISH_LINE' - - run_apt() { - set +e - DEBIAN_FRONTEND=noninteractive apt -y "$@" - APT_GET_EXIT_CODE=$? - set -e - echo "${FINISH_LINE} ${APT_GET_EXIT_CODE}" - } - - local OUR_NEWLINE='\r' # be \n\r except on 1st run, so no empty 1st line - local LAST_PREFIX= - local LEADER_PREFIX - local APT_LINE - run_apt "$@" 2>&1 | while read -r APT_LINE; do - APT_LINE=$(printf '%s' "${APT_LINE}" | tr -d '\r') - if [ -z "${APT_LINE}" ]; then - continue - else - local FIRST_FIELD - FIRST_FIELD=$(echo "${APT_LINE}" | cut -d' ' -f1) - if [ "${FIRST_FIELD}" = "${FINISH_LINE}" ]; then - printf '%s' "${OUR_NEWLINE}" - local EXIT_CODE - EXIT_CODE=$(echo "${APT_LINE}" | cut -d' ' -f2) - if [ "${EXIT_CODE}" != "0" ]; then - false - fi - break - fi - fi - local COMPRESSED_ITEM= - local PREFIX - local PATTERN - local REPLACEMENT - local I=0 - local LINE - local OLD_IFS=${IFS} - local IFS - IFS=$(printf '\n\r') - for LINE in ${apt_get_digested_SEDS}; do - I=$((1 + "$I")) - if [ "$I" -eq 1 ]; then - PREFIX="${LINE}" - continue - elif [ "$I" -eq 2 ]; then - PATTERN="${LINE}" - continue - elif [ "$I" -eq 3 ]; then - REPLACEMENT="${LINE}" - continue - elif [ "$I" -eq 4 ]; then - I=0 - fi - if printf '%s' "${APT_LINE}" | grep -E "${PATTERN}" > /dev/null; then - COMPRESSED_ITEM=$(printf '%s' "${APT_LINE}" | sed -E "s|${PATTERN}|${REPLACEMENT}|") - #if [ "${PREFIX}" = "BECOME_NEXT_PREFIX" ]; then - # LEADER_PREFIX="${COMPRESSED_ITEM}" - # COMPRESSED_ITEM=IGNORE - #elif [ "${PREFIX}" = "FOLLOW_PREFIX" ]; then - # PREFIX="${LEADER_PREFIX}" - #fi - break - fi - done - IFS=${OLD_IFS} - if [ "${COMPRESSED_ITEM}" = 'IGNORE' ]; then - continue - elif [ -z "${COMPRESSED_ITEM}" ]; then - printf '%s' "${OUR_NEWLINE}" - prefixed_msg_no_nl "${APT_LINE}" - LAST_PREFIX= - else - if [ "${PREFIX}" != "${LAST_PREFIX}" ]; then - printf '%s' "${OUR_NEWLINE}" - prefixed_msg_no_nl "# ${PREFIX}" - LAST_PREFIX="${PREFIX}" - fi - printf ' %s' "${COMPRESSED_ITEM}" - fi - OUR_NEWLINE='\n\r' - done - - prefixed_msg_exit -} diff --git a/trixie/scripts/lib/expect_n_args.sh b/trixie/scripts/lib/expect_n_args.sh deleted file mode 120000 index 7430ba5..0000000 --- a/trixie/scripts/lib/expect_n_args.sh +++ /dev/null @@ -1 +0,0 @@ -../../../bookworm/scripts/lib/expect_n_args.sh \ No newline at end of file diff --git a/trixie/scripts/lib/expect_n_args.sh b/trixie/scripts/lib/expect_n_args.sh new file mode 100644 index 0000000..11a26ea --- /dev/null +++ b/trixie/scripts/lib/expect_n_args.sh @@ -0,0 +1,21 @@ +. lib/abort.sh + +expect_n_args() { + _N_MIN_ARGS="$1" + _N_MAX_ARGS="$2" + _USAGE="$3" + shift 3 + _ABORT_MSG= + if [ "$#" -lt "${_N_MIN_ARGS}" ]; then + _ABORT_MSG="missing arguments (got $# instead of ${_N_MIN_ARGS})." + elif [ "$#" -gt "${_N_MAX_ARGS}" ]; then + shift "${_N_MAX_ARGS}" + _ABORT_MSG="unexpected arguments beyond expected number (${_N_MAX_ARGS}): $*." + fi + if [ -n "${_ABORT_MSG}" ]; then + if [ -n "${_USAGE}" ]; then + _ABORT_MSG="${_ABORT_MSG} Expected arguments: ${_USAGE}" + fi + abort "Aborting due to ${_ABORT_MSG}" + fi +} diff --git a/trixie/scripts/lib/get_mountable_device_path.sh b/trixie/scripts/lib/get_mountable_device_path.sh index 8af2a89..8405944 100644 --- a/trixie/scripts/lib/get_mountable_device_path.sh +++ b/trixie/scripts/lib/get_mountable_device_path.sh @@ -1,11 +1,16 @@ . lib/abort.sh get_mountable_device_path() { - _PATH_DEV="/dev/$1" - if [ ! -b "${_PATH_DEV}" ]; then - abort "No block device at ${_PATH_DEV}." - elif [ $(mount | grep -E "^${_PATH_DEV}" | wc -l) -gt 0 ]; then - abort "${_PATH_DEV} already mounted." + local PATH_DEV + PATH_DEV="/dev/$1" + if [ ! -b "${PATH_DEV}" ]; then + abort "No block device at ${PATH_DEV}." + else + local COUNT + COUNT=$(mount | grep -cE "^${PATH_DEV}") + if [ "${COUNT}" -gt 0 ]; then + abort "${PATH_DEV} already mounted." + fi fi - printf "${_PATH_DEV}" + printf '%s' "${PATH_DEV}" } diff --git a/trixie/scripts/lib/path_tmp_timestamped.sh b/trixie/scripts/lib/path_tmp_timestamped.sh index 7ae63cd..4d1488a 100644 --- a/trixie/scripts/lib/path_tmp_timestamped.sh +++ b/trixie/scripts/lib/path_tmp_timestamped.sh @@ -1,3 +1,3 @@ path_tmp_timestamped () { - printf "/tmp/${1}_$(date +'%s')" + printf '/tmp/%s_%s' "$1" "$(date +'%s')" } diff --git a/trixie/scripts/lib/trapp.sh b/trixie/scripts/lib/trapp.sh deleted file mode 120000 index 23d49a5..0000000 --- a/trixie/scripts/lib/trapp.sh +++ /dev/null @@ -1 +0,0 @@ -../../../bookworm/scripts/lib/trapp.sh \ No newline at end of file diff --git a/trixie/scripts/lib/trapp.sh b/trixie/scripts/lib/trapp.sh new file mode 100644 index 0000000..c36568f --- /dev/null +++ b/trixie/scripts/lib/trapp.sh @@ -0,0 +1,7 @@ +trapp() { + local COMMAND="$*" + if [ -z "${COMMAND}" ]; then + COMMAND='-' + fi + trap "${COMMAND}" EXIT TERM HUP INT +} diff --git a/trixie/scripts/make_writable_installer.sh b/trixie/scripts/make_writable_installer.sh index dc8dedd..6505bdf 100755 --- a/trixie/scripts/make_writable_installer.sh +++ b/trixie/scripts/make_writable_installer.sh @@ -1,7 +1,8 @@ -#!/bin/sh +#!/usr/bin/env dash # based on set -eu -cd $(dirname "$0") +PARENT_DIR=$(dirname "$0") +cd "${PARENT_DIR}" . lib/INSTALLER_VERSION.sh . lib/abort.sh . lib/abort_if_command_unknown.sh @@ -13,40 +14,45 @@ cd $(dirname "$0") . lib/path_tmp_timestamped.sh . lib/trapp.sh -expect_n_args 1 2 'DEVICE (e.g. "sdb") [PATH_FILE_ISO]' $@ +FILENAME_ISO="debian-${INSTALLER_VERSION}-amd64-netinst.iso" +URL_ISO="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/${FILENAME_ISO}" +PATH_MNT_ISO=/mnt/iso + +expect_n_args 1 2 'DEVICE (e.g. "sdb") [PATH_FILE_ISO]' "$@" abort_if_not_user root abort_if_command_unknown mkfs.vfat abort_if_command_unknown parted abort_if_command_unknown rsync abort_if_command_unknown wget -FILENAME_ISO="debian-${INSTALLER_VERSION}-amd64-netinst.iso" + if [ -z "$2" ]; then + echo "No file path set, so will try to retrieve image online from ${URL_ISO}." abort_if_offline else + echo "With file path set, checking if we can use file at ${PATH_FILE_ISO}." PATH_FILE_ISO=$(realpath "$2") - if [ ! "${FILENAME_ISO}" = $(basename "${PATH_FILE_ISO}") ]; then + BASENAME_FILE_ISO=$(basename "${PATH_FILE_ISO}") + if [ ! "${FILENAME_ISO}" = "${BASENAME_FILE_ISO}" ]; then abort "basename of PATH_FILE_ISO != expected ${FILENAME_ISO}" elif [ ! -f "${PATH_FILE_ISO}" ]; then abort 'no file found at PATH_FILE_ISO' fi fi -PATH_DEV="$(get_mountable_device_path $1)" -PATH_MNT_ISO=/mnt/iso +PATH_DEV=$(get_mountable_device_path "$1") PATH_PROCESSING="$(path_tmp_timestamped make_writable_installer)" -RM_PROCESSING="rm -rf ${PATH_PROCESSING}" echo "Setting up processing directory at ${PATH_PROCESSING} …" +RM_PROCESSING="rm -rf ${PATH_PROCESSING}" mkdir "${PATH_PROCESSING}" trapp "${RM_PROCESSING}" cd "${PATH_PROCESSING}" if [ -z "${PATH_FILE_ISO}" ]; then echo "Retrieving ${FILENAME_ISO} …" - URL_ISO="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/${FILENAME_ISO}" wget --quiet --output-document "${FILENAME_ISO}" "${URL_ISO}" else echo "Linking to ${PATH_FILE_ISO} …" - ln -s "${PATH_FILE_ISO}" + ln -s "${PATH_FILE_ISO}" . fi echo "Preparing partition/filesystem on ${PATH_DEV} …" @@ -79,9 +85,9 @@ if [ "${RESULT}" != "0" ]; then echo 'RSYNC ERRORS:' cat "${FILENAME_RSYNC_ERRORS}" echo '\nrsync encountered errors, see above – continue? (Y/N)' - read ANSWER + read -r ANSWER FIRST_CHAR=$(echo "${ANSWER}" | cut -c1) - if ! [ "${FIRST_CHAR}" = 'y' -o "${FIRST_CHAR}" = 'Y' ]; then + if ! [ "${FIRST_CHAR}" = 'y' ] || [ "${FIRST_CHAR}" = 'Y' ]; then abort 'as requested' fi fi