diff --git a/src/answer.sh b/src/answer.sh index 0012bce4..7e086fb7 100644 --- a/src/answer.sh +++ b/src/answer.sh @@ -69,7 +69,7 @@ setXML() { CUSTOM_XML="" - removeGeneratedXML "$target" || return 1 + removeGeneratedXML "$target" || return 2 if [ -d "${custom_files[0]}" ]; then error "The bind ${custom_files[0]} maps to a file that does not exist!" @@ -98,7 +98,7 @@ setXML() { if [[ "${DETECTED,,}" == *"-eval" ]] && { [ ! -f "$file" ] || [ ! -s "$file" ]; }; then - generateEvalXML "$DETECTED" "$index" || return 1 + generateEvalXML "$DETECTED" "$index" || return $? file="$target" elif [ ! -f "$file" ] || [ ! -s "$file" ]; then @@ -107,7 +107,7 @@ setXML() { elif [[ "$file" != "$target" ]]; then - generateFallbackXML "$DETECTED" "$index" || return 1 + generateFallbackXML "$DETECTED" "$index" || return $? file="$target" fi @@ -340,12 +340,12 @@ generateEvalXML() { local target="/run/assets/$id.xml" local source="/run/assets/$normal.xml" - removeGeneratedXML "$source" || return 1 + removeGeneratedXML "$source" || return 2 if [ ! -s "$source" ]; then source="/run/assets/${normal%%-*}.xml" - removeGeneratedXML "$source" || return 1 + removeGeneratedXML "$source" || return 2 fi @@ -361,7 +361,7 @@ generateEvalXML() { esac fi - generateAnswerFile "$id" "$source" "$target" "$index" "evaluation" "$remove_selector" || return 1 + generateAnswerFile "$id" "$source" "$target" "$index" "evaluation" "$remove_selector" || return 2 return 0 } @@ -379,11 +379,11 @@ generateFallbackXML() { [ "$source" != "$target" ] || return 1 - removeGeneratedXML "$source" || return 1 + removeGeneratedXML "$source" || return 2 [ -s "$source" ] || return 1 - generateAnswerFile "$id" "$source" "$target" "$index" "fallback" "Y" || return 1 + generateAnswerFile "$id" "$source" "$target" "$index" "fallback" "Y" || return 2 return 0 } diff --git a/src/image.sh b/src/image.sh index 9dae8e4a..e9cc8063 100644 --- a/src/image.sh +++ b/src/image.sh @@ -796,28 +796,28 @@ detectLegacy() { # Legacy media is identified from setup marker files rather than WIM # metadata. The order is intentional because several releases share markers. - marker=$(find "$dir" -maxdepth 1 -type d -iname 'ia64' -print -quit) || return 1 + marker=$(find "$dir" -maxdepth 1 -type d -iname 'ia64' -print -quit) || return 2 if [ -n "$marker" ]; then error "Windows IA-64 (Itanium) images are not supported by this container!" exit 67 fi - marker=$(find "$dir" -maxdepth 1 -type d -iname WIN95 -print -quit) || return 1 + marker=$(find "$dir" -maxdepth 1 -type d -iname WIN95 -print -quit) || return 2 if [ -n "$marker" ]; then DETECTED="win95" return 0 fi - marker=$(find "$dir" -maxdepth 1 -type d -iname WIN98 -print -quit) || return 1 + marker=$(find "$dir" -maxdepth 1 -type d -iname WIN98 -print -quit) || return 2 if [ -n "$marker" ]; then DETECTED="win98" return 0 fi - marker=$(find "$dir" -maxdepth 1 -type d -iname WIN9X -print -quit) || return 1 + marker=$(find "$dir" -maxdepth 1 -type d -iname WIN9X -print -quit) || return 2 if [ -n "$marker" ]; then DETECTED="win9x" @@ -830,14 +830,14 @@ detectLegacy() { -iname CDROM_S.40 -o \ -iname CDROM_TS.40 \ \) \ - -print -quit) || return 1 + -print -quit) || return 2 if [ -n "$marker" ]; then DETECTED="winnt4" return 0 fi - marker=$(find "$dir" -maxdepth 1 -type f -iname CDROM_NT.5 -print -quit) || return 1 + marker=$(find "$dir" -maxdepth 1 -type f -iname CDROM_NT.5 -print -quit) || return 2 if [ -n "$marker" ]; then @@ -848,7 +848,7 @@ detectLegacy() { -iname CDROM_IP.5 -o \ -iname CDROM_IS.5 \ \) \ - -print -quit) || return 1 + -print -quit) || return 2 if [ -n "$marker" ]; then DETECTED="win2k" @@ -859,10 +859,10 @@ detectLegacy() { # WIN51 identifies the NT 5.1/5.2 media family; the companion marker then # distinguishes XP x86, XP x64, and Server 2003. - marker=$(find "$dir" -maxdepth 1 -iname WIN51 -print -quit) || return 1 + marker=$(find "$dir" -maxdepth 1 -iname WIN51 -print -quit) || return 2 [ -n "$marker" ] || return 1 - marker=$(find "$dir" -maxdepth 1 -type f -iname WIN51AP -print -quit) || return 1 + marker=$(find "$dir" -maxdepth 1 -type f -iname WIN51AP -print -quit) || return 2 if [ -n "$marker" ]; then DETECTED="winxpx64" @@ -875,7 +875,7 @@ detectLegacy() { -iname WIN51IP -o \ -iname setupxp.htm \ \) \ - -print -quit) || return 1 + -print -quit) || return 2 if [ -n "$marker" ]; then DETECTED="winxpx86" @@ -896,7 +896,7 @@ detectLegacy() { -iname WIN51MD -o \ -iname WIN51MP \ \) \ - -print -quit) || return 1 + -print -quit) || return 2 if [ -n "$marker" ]; then DETECTED="win2003r2" @@ -913,7 +913,7 @@ detectReactOS() { local marker marker=$(find "$dir" -maxdepth 2 -type f \ - \( -ipath '*/reactos/reactos.inf' -o -ipath '*/reactos/unattend.inf' \) -print -quit) || return 1 + \( -ipath '*/reactos/reactos.inf' -o -ipath '*/reactos/unattend.inf' \) -print -quit) || return 2 [ -n "$marker" ] || return 1 @@ -1183,7 +1183,7 @@ findImage() { local dir="$1" local name sources result - sources=$(find "$dir" -maxdepth 1 -type d -iname sources -print -quit) || return 1 + sources=$(find "$dir" -maxdepth 1 -type d -iname sources -print -quit) || return 2 if [ ! -d "$sources" ]; then warn "failed to locate 'sources' folder in ISO image, $FB" @@ -1191,7 +1191,7 @@ findImage() { fi for name in install.wim install.esd; do - result=$(find "$sources" -maxdepth 1 -type f -iname "$name" -print -quit) || return 1 + result=$(find "$sources" -maxdepth 1 -type f -iname "$name" -print -quit) || return 2 [ -n "$result" ] && break done @@ -1220,8 +1220,8 @@ readImageInfo() { } if [ -z "$result" ]; then - warn "failed to read Windows image information, $FB" - return 1 + error "Failed to read Windows image information!" + return 2 fi printf '%s' "$result" @@ -1261,16 +1261,21 @@ validateEdition() { unknownImage() { local msg="Failed to determine Windows version from image" + local rc=0 - # Unknown media can continue when a custom answer file or manual mode already - # provides the required installation path; otherwise force manual fallback. - if setXML "" || enabled "$MANUAL"; then + setXML "" || rc=$? + + if (( rc == 0 )) || enabled "$MANUAL"; then info "${msg}!" - else - MANUAL="Y" - warn "${msg}, $FB." + return 0 fi + # Only absence of a usable answer file is a supported manual fallback. + (( rc == 1 )) || return "$rc" + + MANUAL="Y" + warn "${msg}, $FB." + return 0 } @@ -1294,9 +1299,20 @@ configureImage() { local index="$1" local desc="$2" + local rc=0 + # Prefer the exact answer file, then a family-level fallback. Manual mode is - # the final supported path when neither can be generated. - setXML "" "$index" && return 0 + # the final supported path only when no usable template exists. + setXML "" "$index" || rc=$? + + if (( rc == 0 )); then + return 0 + fi + + enabled "$MANUAL" && return 0 + + # Generation or preparation errors must not be hidden by another fallback. + (( rc == 1 )) || return "$rc" if [[ "$DETECTED" == "win81x86"* || "$DETECTED" == "win10x86"* ]]; then error "The 32-bit version of $desc is not supported!" @@ -1306,15 +1322,19 @@ configureImage() { local msg="the answer file for $desc was not found ($DETECTED.xml)" local fallback="/run/assets/${DETECTED%%-*}.xml" - if setXML "$fallback" "$index"; then - if ! enabled "$MANUAL"; then - warn "${msg}." - fi + rc=0 + setXML "$fallback" "$index" || rc=$? + + if (( rc == 0 )); then + warn "${msg}." return 0 fi enabled "$MANUAL" && return 0 + # The family-level template was present but could not be generated/prepared. + (( rc == 1 )) || return "$rc" + MANUAL="Y" warn "${msg}, $FB." @@ -1361,14 +1381,18 @@ detectIsoImage() { local iso="$1" - local image header image_info - - # Return 1 when direct ISO inspection is unavailable so the caller may fall - # back to extraction; return 2 when metadata was read but configuration failed. + local image header image_info rc + # Return 1 only when no directly inspectable WIM/ESD payload is available so + # the caller may extract the media. Metadata parsing/configuration errors use 2. image=$(findIsoImage "$iso") || return 1 - header=$(readWimHeader "$iso" "$image") || return 1 - image_info=$(readIsoImageInfo "$iso" "$image" "$header") || return $? + header=$(readWimHeader "$iso" "$image") || return 2 + + image_info=$(readIsoImageInfo "$iso" "$image" "$header") || { + rc=$? + (( rc >= 129 )) && return "$rc" + return 2 + } info "Detecting version from ISO image..." detectImageInfo "$image_info" || return 2 diff --git a/src/install.sh b/src/install.sh index 41e7e6ac..345b8945 100644 --- a/src/install.sh +++ b/src/install.sh @@ -79,9 +79,7 @@ selectWindowsImage() { # Only code 1 indicates that extraction may recover detection. if (( detect_rc != 1 )); then - skipUnattended "$dir" "$iso" "$boot" || return 76 - handled=1 - return 0 + return 76 fi if ! extractImage "$iso" "$dir" "$VERSION"; then @@ -102,6 +100,10 @@ selectWindowsImage() { return "$detect_rc" fi + if (( detect_rc != 1 )); then + return 76 + fi + skipUnattended "$dir" "$iso" "$boot" || return 76 handled=1 @@ -116,11 +118,7 @@ configureMachine() { local desc - if ! desc=$(printVariant "$DETECTED" "$DETECTED"); then - skipUnattended "$dir" "$iso" "$boot" || return 78 - handled=1 - return 0 - fi + desc=$(printVariant "$DETECTED" "$DETECTED") || return 78 if ! checkMemory "$DETECTED" "$desc"; then if [ -n "${REUSED_ISO:-}" ]; then @@ -130,15 +128,11 @@ configureMachine() { fi if ! setMachine "$DETECTED" "$iso" "$dir" "$desc"; then - skipUnattended "$dir" "$iso" "$boot" || return 80 - handled=1 - return 0 + return 80 fi if ! restoreMachineState; then - skipUnattended "$dir" "$iso" "$boot" || return 82 - handled=1 - return 0 + return 82 fi if ! supportsUnattended "$DETECTED"; then @@ -160,9 +154,7 @@ prepareWindowsImage() { if supportsXML "$DETECTED"; then if ! createOverlay "$XML" "$LANGUAGE" "$TMP/setup"; then - skipUnattended "$dir" "$iso" "$boot" || return 84 - handled=1 - return 0 + return 84 fi if ! createSetupImage "$TMP/setup" "$STORAGE/setup.img"; then @@ -186,9 +178,7 @@ prepareWindowsImage() { fi if ! prepareImage "$iso" "$dir"; then - skipUnattended "$dir" "$iso" "$boot" || return 92 - handled=1 - return 0 + return 92 fi removeImage "$iso" || return 96 @@ -684,14 +674,19 @@ setImage() { supportsXML "${DETECTED,,}" || return 0 - setXML "" && return 0 + local rc=0 + + setXML "" || rc=$? + + if (( rc == 0 )); then + return 0 + fi + enabled "$MANUAL" && return 0 - # If a usable source template exists, setXML failed while preparing it. - # That is an installation error and must not fall back to manual setup. - hasAnswerFile "$DETECTED" && return 1 + # Only a genuinely missing answer file may fall back to manual setup. + (( rc == 1 )) || return "$rc" - # A genuinely missing answer file is a supported manual-install path. MANUAL="Y" local desc @@ -906,24 +901,39 @@ detectImage() { local dir="$1" - local desc + local desc detect_rc=0 info "Detecting version from ISO image..." # Marker-based legacy and ReactOS detection must run before looking for a WIM. - if detectLegacy "$dir" || detectReactOS "$dir"; then - desc=$(printEdition "$DETECTED" "$DETECTED" "Y") || return 1 + detectLegacy "$dir" || detect_rc=$? + + if (( detect_rc == 0 )); then + desc=$(printEdition "$DETECTED" "$DETECTED" "Y") || return 2 info "Detected: $desc" return 0 fi + (( detect_rc == 1 )) || return "$detect_rc" + + detect_rc=0 + detectReactOS "$dir" || detect_rc=$? + + if (( detect_rc == 0 )); then + desc=$(printEdition "$DETECTED" "$DETECTED" "Y") || return 2 + info "Detected: $desc" + return 0 + fi + + (( detect_rc == 1 )) || return "$detect_rc" + local wim - wim=$(findImage "$dir") || return 1 + wim=$(findImage "$dir") || return $? local image_info image_info=$(readImageInfo "$wim") || return $? - detectImageInfo "$image_info" + detectImageInfo "$image_info" || return 2 } prepareImage() {