fix: Propagate command substitution failures (#2039)

This commit is contained in:
Kroese
2026-08-04 11:45:31 +02:00
committed by GitHub
parent 9d01d237c2
commit 0c2dbdf98a
4 changed files with 76 additions and 50 deletions
+3 -4
View File
@@ -685,7 +685,6 @@ normalizeEdition() {
local edition local edition
source="${source//evaluation/}" source="${source//evaluation/}"
source=$(printf '%s' "$source" | source=$(printf '%s' "$source" |
uconv -x 'Any-Latin; Latin-ASCII' 2>/dev/null) || return 1 uconv -x 'Any-Latin; Latin-ASCII' 2>/dev/null) || return 1
@@ -704,7 +703,7 @@ normalizeEditionID() {
local edition base local edition base
local id="$2" local id="$2"
edition=$(normalizeEdition "$1") edition=$(normalizeEdition "$1") || return 1
case "$edition" in case "$edition" in
"pro" | "professional" | "business" ) "pro" | "professional" | "business" )
@@ -768,7 +767,7 @@ getEditionID() {
* ) return 1 ;; * ) return 1 ;;
esac esac
edition=$(normalizeEditionID "$edition" "$id") edition=$(normalizeEditionID "$edition" "$id") || return 1
echo "$edition" echo "$edition"
return 0 return 0
@@ -856,7 +855,7 @@ getServerEditionID() {
* ) return 1 ;; * ) return 1 ;;
esac esac
edition=$(normalizeServerEditionID "$edition") edition=$(normalizeServerEditionID "$edition") || return 1
echo "$edition" echo "$edition"
return 0 return 0
+14 -8
View File
@@ -1189,17 +1189,16 @@ parseWimHeader() {
findImage() { findImage() {
local dir="$1" local dir="$1"
local sources result local sources result
sources=$(find "$dir" -maxdepth 1 -type d -iname sources -print -quit) sources=$(find "$dir" -maxdepth 1 -type d -iname sources -print -quit) || return 1
if [ ! -d "$sources" ]; then if [ ! -d "$sources" ]; then
warn "failed to locate 'sources' folder in ISO image, $FB" warn "failed to locate 'sources' folder in ISO image, $FB"
return 1 return 1
fi fi
result=$(find "$sources" -maxdepth 1 -type f \( -iname install.wim -or -iname install.esd \) -print -quit) result=$(find "$sources" -maxdepth 1 -type f \( -iname install.wim -or -iname install.esd \) -print -quit) || return 1
if [ ! -f "$result" ]; then if [ ! -f "$result" ]; then
warn "failed to locate 'install.wim' or 'install.esd' in ISO image, $FB" warn "failed to locate 'install.wim' or 'install.esd' in ISO image, $FB"
@@ -1213,8 +1212,7 @@ findImage() {
readImageInfo() { readImageInfo() {
local wim="$1" local wim="$1"
local result=""
local result
result=$(wimlib-imagex info -xml "$wim" | iconv -f UTF-16LE -t UTF-8) || { result=$(wimlib-imagex info -xml "$wim" | iconv -f UTF-16LE -t UTF-8) || {
local rc=$? local rc=$?
@@ -1223,9 +1221,13 @@ readImageInfo() {
exit "$rc" exit "$rc"
fi fi
result=""
}
if [ -z "$result" ]; then
warn "failed to read Windows image information, $FB" warn "failed to read Windows image information, $FB"
return 1 return 1
} fi
printf '%s' "$result" printf '%s' "$result"
return 0 return 0
@@ -1283,8 +1285,8 @@ describeImage() {
local index="$2" local index="$2"
local result local result
result=$(printEdition "$DETECTED" "$DETECTED" "Y") || return 1 result=$(printEdition "$DETECTED" "$DETECTED" "Y") || return 1
detectLanguage "$info_xml" "$index" || return 1 detectLanguage "$info_xml" "$index" || return 1
if [[ "${LANGUAGE,,}" != "en" && "${LANGUAGE,,}" != "en-"* ]]; then if [[ "${LANGUAGE,,}" != "en" && "${LANGUAGE,,}" != "en-"* ]]; then
@@ -1723,7 +1725,11 @@ buildImage() {
return 1 return 1
fi fi
size=$(du -b --max-depth=0 "$dir" | cut -f1) if ! size=$(du -b --max-depth=0 "$dir" | cut -f1); then
error "Failed to calculate the size of directory \"$dir\"!"
return 1
fi
checkFreeSpace "$TMP" "$size" || return 1 checkFreeSpace "$TMP" "$size" || return 1
/run/progress.sh "$out" "$size" "$msg ([P])..." & /run/progress.sh "$out" "$size" "$msg ([P])..." &
+51 -34
View File
@@ -49,7 +49,7 @@ selectWindowsImage() {
if resolveImage "$VERSION"; then if resolveImage "$VERSION"; then
if ! setImage; then if ! setImage; then
abortInstall "$dir" "$iso" "$boot" || return 70 skipUnattended "$dir" "$iso" "$boot" || return 70
handled=1 handled=1
return 0 return 0
fi fi
@@ -77,7 +77,7 @@ selectWindowsImage() {
# Only code 1 indicates that extraction may recover detection. # Only code 1 indicates that extraction may recover detection.
if (( detect_rc != 1 )); then if (( detect_rc != 1 )); then
abortInstall "$dir" "$iso" "$boot" || return 76 skipUnattended "$dir" "$iso" "$boot" || return 76
handled=1 handled=1
return 0 return 0
fi fi
@@ -93,7 +93,7 @@ selectWindowsImage() {
return 0 return 0
fi fi
abortInstall "$dir" "$iso" "$boot" || return 76 skipUnattended "$dir" "$iso" "$boot" || return 76
handled=1 handled=1
return 0 return 0
} }
@@ -107,25 +107,25 @@ configureMachine() {
local desc local desc
if ! desc=$(printVariant "$DETECTED" "$DETECTED"); then if ! desc=$(printVariant "$DETECTED" "$DETECTED"); then
abortInstall "$dir" "$iso" "$boot" || return 78 skipUnattended "$dir" "$iso" "$boot" || return 78
handled=1 handled=1
return 0 return 0
fi fi
if ! setMachine "$DETECTED" "$iso" "$dir" "$desc"; then if ! setMachine "$DETECTED" "$iso" "$dir" "$desc"; then
abortInstall "$dir" "$iso" "$boot" || return 80 skipUnattended "$dir" "$iso" "$boot" || return 80
handled=1 handled=1
return 0 return 0
fi fi
if ! restoreMachineState; then if ! restoreMachineState; then
abortInstall "$dir" "$iso" "$boot" || return 82 skipUnattended "$dir" "$iso" "$boot" || return 82
handled=1 handled=1
return 0 return 0
fi fi
if ! supportsUnattended "$DETECTED"; then if ! supportsUnattended "$DETECTED"; then
abortInstall "$dir" "$iso" "$boot" || return 83 skipUnattended "$dir" "$iso" "$boot" || return 83
handled=1 handled=1
return 0 return 0
fi fi
@@ -143,7 +143,7 @@ prepareWindowsImage() {
if canUseSetupImage "$DETECTED" "$iso"; then if canUseSetupImage "$DETECTED" "$iso"; then
if ! stageSetup "$XML" "$LANGUAGE" "$TMP/setup"; then if ! stageSetup "$XML" "$LANGUAGE" "$TMP/setup"; then
abortInstall "$dir" "$iso" "$boot" || return 84 skipUnattended "$dir" "$iso" "$boot" || return 84
handled=1 handled=1
return 0 return 0
fi fi
@@ -166,13 +166,13 @@ prepareWindowsImage() {
fi fi
if ! prepareImage "$iso" "$dir"; then if ! prepareImage "$iso" "$dir"; then
abortInstall "$dir" "$iso" "$boot" || return 92 skipUnattended "$dir" "$iso" "$boot" || return 92
handled=1 handled=1
return 0 return 0
fi fi
if ! updateImage "$dir" "$XML" "$LANGUAGE"; then if ! updateImage "$dir" "$XML" "$LANGUAGE"; then
abortInstall "$dir" "$iso" "$boot" || return 94 skipUnattended "$dir" "$iso" "$boot" || return 94
handled=1 handled=1
return 0 return 0
fi fi
@@ -307,7 +307,7 @@ startInstall() {
return 0 return 0
} }
abortInstall() { skipUnattended() {
local dir="$1" local dir="$1"
local iso="$2" local iso="$2"
@@ -324,14 +324,11 @@ abortInstall() {
# whether it can still be booted manually using legacy firmware. # whether it can still be booted manually using legacy firmware.
if [[ "${PLATFORM,,}" == "x64" ]] && [ -d "$dir" ]; then if [[ "${PLATFORM,,}" == "x64" ]] && [ -d "$dir" ]; then
efi=$(find "$dir" -maxdepth 1 -type d -iname efi -print -quit) efi=$(find "$dir" -maxdepth 1 -type d -iname efi -print -quit) || return 1
efi32=$(find "$dir" -maxdepth 3 -type f \ efi32=$(find "$dir" -maxdepth 3 -type f -ipath '*/efi/boot/bootia32.efi' -print -quit) || return 1
-ipath '*/efi/boot/bootia32.efi' -print -quit) efi64=$(find "$dir" -maxdepth 3 -type f -ipath '*/efi/boot/bootx64.efi' -print -quit) || return 1
efi64=$(find "$dir" -maxdepth 3 -type f \
-ipath '*/efi/boot/bootx64.efi' -print -quit)
if [ -z "$efi" ] || if [ -z "$efi" ] || { [ -n "$efi32" ] && [ -z "$efi64" ]; }; then
{ [ -n "$efi32" ] && [ -z "$efi64" ]; }; then
writeState "mode" "windows_legacy" || return 1 writeState "mode" "windows_legacy" || return 1
restoreBootMode || return 1 restoreBootMode || return 1
@@ -502,8 +499,11 @@ findFile() {
local dir file base local dir file base
local boot="$STORAGE/windows.boot" local boot="$STORAGE/windows.boot"
dir=$(find / -maxdepth 1 -type d -iname "$fname" -print -quit) dir=$(find / -maxdepth 1 -type d -iname "$fname" -print -quit) || return 1
[ ! -d "$dir" ] && dir=$(find "$STORAGE" -maxdepth 1 -type d -iname "$fname" -print -quit)
if [ ! -d "$dir" ]; then
dir=$(find "$STORAGE" -maxdepth 1 -type d -iname "$fname" -print -quit) || return 1
fi
if [ -d "$dir" ]; then if [ -d "$dir" ]; then
if ! hasData || [ ! -f "$boot" ]; then if ! hasData || [ ! -f "$boot" ]; then
@@ -511,8 +511,11 @@ findFile() {
fi fi
fi fi
file=$(find / -maxdepth 1 -type f -iname "$fname" -print -quit) file=$(find / -maxdepth 1 -type f -iname "$fname" -print -quit) || return 1
[ ! -s "$file" ] && file=$(find "$STORAGE" -maxdepth 1 -type f -iname "$fname" -print -quit)
if [ ! -s "$file" ]; then
file=$(find "$STORAGE" -maxdepth 1 -type f -iname "$fname" -print -quit) || return 1
fi
if [ ! -s "$file" ] && [[ "${VERSION,,}" != "http"* ]]; then if [ ! -s "$file" ] && [[ "${VERSION,,}" != "http"* ]]; then
base=$(basename "$VERSION") base=$(basename "$VERSION")
@@ -524,7 +527,7 @@ findFile() {
fi fi
local size local size
size="$(stat -c%s "$file")" size=$(stat -c%s "$file") || return 1
if [ -z "$size" ] || [[ "$size" == "0" ]]; then if [ -z "$size" ] || [[ "$size" == "0" ]]; then
return 0 return 0
@@ -602,13 +605,22 @@ checkFreeSpace() {
local dir="$1" local dir="$1"
local size="$2" local size="$2"
local size_gb space space_gb local space size_gb space_gb
size_gb=$(formatBytes "$size") space=$(df --output=avail -B 1 "$dir" | tail -n 1) || return 1
space=$(df --output=avail -B 1 "$dir" | tail -n 1)
space_gb=$(formatBytes "$space") [[ "$space" =~ ^[[:space:]]*[0-9]+[[:space:]]*$ ]] || {
error "Failed to determine available disk space for $dir!"
return 1
}
space="${space//[[:space:]]/}"
if (( size > space )); then if (( size > space )); then
size_gb=$(formatBytes "$size")
space_gb=$(formatBytes "$space")
error "Not enough free space in $STORAGE, have $space_gb available but need at least $size_gb." error "Not enough free space in $STORAGE, have $space_gb available but need at least $size_gb."
return 1 return 1
fi fi
@@ -839,10 +851,13 @@ extractImage() {
return 1 return 1
fi fi
size=$(stat -c%s "$iso") if ! size=$(stat -c%s "$iso"); then
error "Failed to determine ISO file size: $iso"
return 1
fi
if (( size < 10000000 )); then if (( size < 10000000 )); then
error "Invalid ISO file: Size is smaller than 10 MB" && return 1 error "Invalid ISO file: Size of \"$iso\" is smaller than 10 MB" && return 1
fi fi
checkFreeSpace "$dir" "$size" || return 1 checkFreeSpace "$dir" "$size" || return 1
@@ -867,17 +882,19 @@ extractImage() {
else else
# UNPACK archives contain another ISO. Extract the nested ISO, then # Locate and extract the ISO nested inside the downloaded archive
# preserve it as the actual source media for subsequent processing. if ! file=$(find "$dir" -maxdepth 1 -type f -iname "*.iso" -print -quit); then
file=$(find "$dir" -maxdepth 1 -type f -iname "*.iso" -print -quit) error "Failed to search for a nested ISO in the extracted archive!"
return 1
fi
if [ -z "$file" ]; then if [ -z "$file" ]; then
error "Failed to find any .iso file in archive!" error "Failed to find any nested ISO files in the archive!"
return 1 return 1
fi fi
if ! 7z x "$file" -o"$dir" > /dev/null; then if ! 7z x "$file" -o"$dir" > /dev/null; then
error "Failed to extract archive!" error "Failed to extract nested ISO file: $file"
return 1 return 1
fi fi
+8 -4
View File
@@ -1022,15 +1022,19 @@ downloadFile() {
local web_desc="$5" local web_desc="$5"
local connections="${6:-1}" local connections="${6:-1}"
local domain dots local domain parent
local msg="Downloading $web_desc" local msg="Downloading $web_desc"
local console_msg="Downloading $desc" local console_msg="Downloading $desc"
# Keep mirror messages concise by reducing subdomains to the final two # Keep mirror messages concise by reducing subdomains to the final two
# labels, while Microsoft downloads retain the generic description. # labels, while Microsoft downloads retain the generic description.
domain=$(echo "$url" | awk -F/ '{print $3}') domain="${url#*://}"
dots=$(echo "$domain" | tr -cd '.' | wc -c) domain="${domain%%/*}"
(( dots > 1 )) && domain=$(expr "$domain" : '.*\.\(.*\..*\)')
if [[ "$domain" == *.*.* ]]; then
parent="${domain#*.}"
[ -n "$parent" ] && domain="$parent"
fi
if [ -n "$domain" ] && [[ "${domain,,}" != *"microsoft.com" ]]; then if [ -n "$domain" ] && [[ "${domain,,}" != *"microsoft.com" ]]; then
console_msg="Downloading $desc from $domain" console_msg="Downloading $desc from $domain"