feat: Support pre-installed system images (#2134)

This commit is contained in:
Kroese
2026-08-13 23:10:56 +02:00
committed by GitHub
parent db6b085ae2
commit e832e705f9
+132 -48
View File
@@ -66,9 +66,8 @@ selectWindowsImage() {
local dir="$2" local dir="$2"
local boot="$3" local boot="$3"
local rc
XML="" XML=""
SYSTEM=""
FB="falling back to manual installation!" FB="falling back to manual installation!"
normalizeDetected || : normalizeDetected || :
@@ -80,8 +79,10 @@ selectWindowsImage() {
return 70 return 70
fi fi
if ! needsExtraction "$DETECTED" "$iso"; then if ! needsExtraction "$iso"; then
return 0
needsPreparation "$DETECTED" || return 0
fi fi
if ! extractImage "$iso" "$dir" "$VERSION"; then if ! extractImage "$iso" "$dir" "$VERSION"; then
@@ -96,11 +97,11 @@ selectWindowsImage() {
fi fi
# Inspect unknown bootable media directly before falling back to extraction. # Inspect unknown bootable media directly before falling back to extraction.
if isDirectImage "$iso"; then if ! needsExtraction "$iso"; then
detectIsoImage "$iso" && return 0 detectIsoImage "$iso" && return 0
rc=$? local rc=$?
if (( rc != 1 )); then if (( rc != 1 )); then
error "Failed to inspect the Windows installation ISO!" error "Failed to inspect the Windows installation ISO!"
return 76 return 76
@@ -124,7 +125,7 @@ selectWindowsImage() {
detectImage "$dir" && return 0 detectImage "$dir" && return 0
rc=$? local rc=$?
if (( rc != 1 )); then if (( rc != 1 )); then
error "Failed to detect the extracted Windows installation image!" error "Failed to detect the extracted Windows installation image!"
return 76 return 76
@@ -193,6 +194,23 @@ prepareWindowsImage() {
local dir="$2" local dir="$2"
local boot="$3" local boot="$3"
if [ -n "$SYSTEM" ]; then
hasImage "$SYSTEM" || {
error "Failed to find the generated Windows system image!"
return 94
}
removeImage "$iso" || {
error "Failed to remove the source installation image!"
return 96
}
BOOT="$SYSTEM"
return 0
fi
# Keep all run-specific automation on the setup image for XML-capable media. # Keep all run-specific automation on the setup image for XML-capable media.
if supportsXML "$DETECTED"; then if supportsXML "$DETECTED"; then
@@ -207,7 +225,7 @@ prepareWindowsImage() {
fi fi
# Bootable ISOs can be reused unchanged with the generated setup image. # Bootable ISOs can be reused unchanged with the generated setup image.
if (( ! extracted )) && isDirectImage "$iso"; then if (( ! extracted )); then
useOriginalImage "$iso" || { useOriginalImage "$iso" || {
error "Failed to preserve the original installation image!" error "Failed to preserve the original installation image!"
@@ -350,9 +368,9 @@ startInstall() {
(( rc > 1 )) && return "$rc" (( rc > 1 )) && return "$rc"
(( rc )) || return 1 (( rc )) || return 1
if [ -z "$previousBase" ] && hasData; then if [ -z "$previousBase" ] && hasInstalledDisk; then
if enabled "$SHUTDOWN" && [ ! -f "$STORAGE/windows.boot" ]; then if ! hasCompletedInstall && ! disabled "${SHUTDOWN:-}"; then
discardPrevious "" || return 50 discardPrevious "" || return 50
else else
if ! backupPrevious ""; then if ! backupPrevious ""; then
@@ -429,7 +447,7 @@ skipUnattended() {
# Standalone ESD files and nested archives are not directly bootable media, # Standalone ESD files and nested archives are not directly bootable media,
# so they cannot use the manual-install fallback. # so they cannot use the manual-install fallback.
if ! isDirectImage "$iso"; then if needsExtraction "$iso"; then
error "Failed to boot \"$iso\" because it is not a directly bootable ISO image!" error "Failed to boot \"$iso\" because it is not a directly bootable ISO image!"
return 1 return 1
fi fi
@@ -464,6 +482,7 @@ skipInstall() {
local iso="$1" local iso="$1"
local previousBase="$2" local previousBase="$2"
local marker="$STORAGE/windows.boot" local marker="$STORAGE/windows.boot"
local system
if [ -n "$previousBase" ]; then if [ -n "$previousBase" ]; then
@@ -487,7 +506,7 @@ skipInstall() {
# Older releases may have left a rebuilt custom ISO at its synthetic source # Older releases may have left a rebuilt custom ISO at its synthetic source
# identity. A completed installation no longer needs that installation media. # identity. A completed installation no longer needs that installation media.
if [[ "${previousBase,,}" == "windows."* ]] && hasData && [ -f "$marker" ]; then if [[ "${previousBase,,}" == "windows."* ]] && hasCompletedInstall; then
if ! rm -f -- "$STORAGE/$previousBase"; then if ! rm -f -- "$STORAGE/$previousBase"; then
error "Failed to remove obsolete ISO file \"$STORAGE/$previousBase\" !" error "Failed to remove obsolete ISO file \"$STORAGE/$previousBase\" !"
@@ -500,7 +519,7 @@ skipInstall() {
# existing installation, but discard stale media when no disk exists yet. # existing installation, but discard stale media when no disk exists yet.
if [[ "${STORAGE,,}/${previousBase,,}" != "${iso,,}" ]]; then if [[ "${STORAGE,,}/${previousBase,,}" != "${iso,,}" ]]; then
if ! hasData; then if ! hasInstalledDisk; then
if ! rm -f -- "$STORAGE/$previousBase"; then if ! rm -f -- "$STORAGE/$previousBase"; then
error "Failed to remove ISO file \"$STORAGE/$previousBase\" !" error "Failed to remove ISO file \"$STORAGE/$previousBase\" !"
@@ -521,7 +540,7 @@ skipInstall() {
else else
method="your custom .iso file was removed" method="your custom .iso file was removed"
if hasData && [ -f "$marker" ]; then if hasCompletedInstall; then
info "Detected that $method, will be ignored." info "Detected that $method, will be ignored."
return 0 return 0
fi fi
@@ -529,7 +548,7 @@ skipInstall() {
fi fi
fi fi
if enabled "$SHUTDOWN" && [ ! -f "$marker" ]; then if ! hasCompletedInstall && ! disabled "${SHUTDOWN:-}"; then
discardPrevious "$STORAGE/$previousBase" || return 50 discardPrevious "$STORAGE/$previousBase" || return 50
return 1 return 1
fi fi
@@ -545,6 +564,11 @@ skipInstall() {
fi fi
fi fi
if [ -n "$previousBase" ] && system=$(getSystemImage); then
BOOT="$system"
return 0
fi
hasData && [ -f "$marker" ] && return 0 hasData && [ -f "$marker" ] && return 0
return 1 return 1
@@ -624,6 +648,33 @@ finishInstall() {
return 1 return 1
} }
if [ -n "$SYSTEM" ]; then
if [[ "$SYSTEM" == "$TMP/"* ]]; then
if ! mv -f -- "$SYSTEM" "$STORAGE/windows.img"; then
error "Failed to finalize the Windows system image!"
return 1
fi
BOOT="$STORAGE/windows.img"
else
if ! hasImage "$SYSTEM"; then
error "Failed to find the Windows system image!"
return 1
fi
writeState "system" "$SYSTEM" || {
error "Failed to save the Windows system image!"
return 1
}
BOOT="$SYSTEM"
fi
fi
if ! rm -rf -- "$TMP"; then if ! rm -rf -- "$TMP"; then
error "Failed to remove directory \"$TMP\" !" error "Failed to remove directory \"$TMP\" !"
return 1 return 1
@@ -636,7 +687,7 @@ findFile() {
local fname="$1" local fname="$1"
local dir file base local dir file base
local boot="$STORAGE/windows.boot" local marker="$STORAGE/windows.boot"
dir=$(find / -maxdepth 1 -type d -iname "$fname" -print -quit) || return 1 dir=$(find / -maxdepth 1 -type d -iname "$fname" -print -quit) || return 1
@@ -645,7 +696,7 @@ findFile() {
fi fi
if [ -d "$dir" ]; then if [ -d "$dir" ]; then
if ! hasDisk || [ ! -f "$boot" ]; then if ! hasSystemImage && { ! hasDisk || [ ! -f "$marker" ]; }; then
error "The bind $dir maps to a file that does not exist!" && return 1 error "The bind $dir maps to a file that does not exist!" && return 1
fi fi
fi fi
@@ -723,11 +774,63 @@ hasImage() {
[ -f "$iso" ] && [ -s "$iso" ] [ -f "$iso" ] && [ -s "$iso" ]
} }
isDirectImage() { getSystemImage() {
local image
image=$(readState "system") || return 1
if [ -n "$image" ]; then
# Older development builds stored only the basename in windows.system.
[[ "$image" == /* ]] || image="$STORAGE/$image"
hasImage "$image" || return 1
echo "$image"
return 0
fi
image="$STORAGE/windows.img"
hasImage "$image" || return 1
echo "$image"
return 0
}
hasSystemImage() {
getSystemImage >/dev/null
}
hasInstalledDisk() {
hasData || hasSystemImage
}
hasCompletedInstall() {
hasSystemImage && return 0
hasData && [ -f "$STORAGE/windows.boot" ]
}
needsExtraction() {
local iso="$1" local iso="$1"
! enabled "${UNPACK:-}" && [[ "${iso,,}" != *.esd ]] enabled "${UNPACK:-}" || [[ "${iso,,}" == *.esd ]]
}
needsPreparation() {
local id="$1"
supportsSIF "$id" && return 0
case "${id,,}" in
"win9"* )
supportsUnattended "$id" && return 0 ;;
esac
return 1
} }
useOriginalImage() { useOriginalImage() {
@@ -736,16 +839,18 @@ useOriginalImage() {
if [ -n "$CUSTOM" ]; then if [ -n "$CUSTOM" ]; then
BOOT="$iso" BOOT="$iso"
return 0 elif [[ "$iso" != "$BOOT" ]]; then
fi
if [[ "$iso" != "$BOOT" ]]; then
if ! mv -f -- "$iso" "$BOOT"; then if ! mv -f -- "$iso" "$BOOT"; then
error "Failed to move ISO file: $iso" error "Failed to move ISO file: $iso"
return 1 return 1
fi fi
fi fi
# Keep SYSTEM pointing at the same image when preserving it changes its path.
if [[ "${SYSTEM:-}" == "$iso" ]]; then
SYSTEM="$BOOT"
fi
return 0 return 0
} }
@@ -789,30 +894,6 @@ setImage() {
return 0 return 0
} }
needsExtraction() {
local id="$1"
local iso="$2"
# Nested archives must be extracted before they can be prepared.
if ! isDirectImage "$iso"; then
return 0
fi
# Media without unattended support boots directly from the original ISO.
if ! supportsUnattended "$id"; then
return 1
fi
# SIF-based legacy installers must be extracted and rebuilt.
if ! supportsXML "$id"; then
return 0
fi
# Modern bootable ISOs can use the original media with a setup overlay.
return 1
}
detectImage() { detectImage() {
local dir="$1" local dir="$1"
@@ -924,6 +1005,10 @@ addFolder() {
local dest="$src/\$OEM\$/\$1/OEM" local dest="$src/\$OEM\$/\$1/OEM"
local install="$src/.overlay-install.bat" local install="$src/.overlay-install.bat"
if [ "$mode" = "win9x" ]; then
dest="$src/OEM"
fi
folder=$(getOemFolder) || return 1 folder=$(getOemFolder) || return 1
[ -z "$folder" ] && [ -z "$COMMAND" ] && return 0 [ -z "$folder" ] && [ -z "$COMMAND" ] && return 0
@@ -1057,7 +1142,6 @@ selectDrivers() {
viofs viofs
sriov sriov
smbus smbus
qxldod
viorng viorng
viostor viostor
viomem viomem