+64
-48
@@ -1,26 +1,30 @@
|
||||
#!/usr/bin/env /bin/bash
|
||||
declare -r TOP_BASEDIR="`pwd`"
|
||||
declare -r TOP_BASEDIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)"
|
||||
|
||||
# read global builder config
|
||||
[[ -f "${TOP_BASEDIR}/builder.config" ]] && {
|
||||
source "${TOP_BASEDIR}/builder.config" || exit $?
|
||||
}
|
||||
|
||||
#
|
||||
# ISO images
|
||||
#
|
||||
declare -r ISO_BASEDIR="/mnt/machines/iso"
|
||||
|
||||
# Windows installation ISO
|
||||
#declare -r INSTALL_ISO="${ISO_BASEDIR}/Win11_25H2_English_x64_v2.iso"
|
||||
#declare -r INSTALL_ISO="${ISO_BASEDIR}/nano11-25H2-English-Pro-2026-03-20.iso"
|
||||
declare -r INSTALL_ISO="${TOP_BASEDIR}/output/install-builder-amd64-20260601.iso"
|
||||
declare -r INSTALL_ISO="${ISO_BASEDIR}/nano11-base-25H2-Pro-Eng-amd64-20260526.iso"
|
||||
#declare -r INSTALL_ISO="${TOP_BASEDIR}/output/install-builder-amd64-20260601.iso"
|
||||
|
||||
# Unattended installation add-on ISO
|
||||
#declare -r UNATTEND_ISO="${TOP_BASEDIR}/output/unattend.iso"
|
||||
declare -r UNATTEND_CONFIG="${TOP_BASEDIR}/configs/autounattend-builder-amd64-20260604.xml"
|
||||
|
||||
declare -r VIRTIO_ISO="${ISO_BASEDIR}/virtio-win-0.1.285.iso"
|
||||
|
||||
#
|
||||
# Disk images
|
||||
#
|
||||
declare -r DISK_BASEDIR="/mnt/machines/qemu-machines"
|
||||
#declare -r DISK_IMG="${DISK_BASEDIR}/win11-builder-amd64.qcow2"
|
||||
declare -r DISK_IMG="${DISK_BASEDIR}/win11-builder-amd64.qcow2"
|
||||
declare -r DISK_SIZE="32G"
|
||||
|
||||
#
|
||||
@@ -67,11 +71,21 @@ declare -r ARM64_EFI_CODE_SIZE="64M"
|
||||
declare -r COMMAND="${1:-build}"
|
||||
shift
|
||||
|
||||
function has {
|
||||
local val="${1}"
|
||||
shift
|
||||
|
||||
for x in $@; do
|
||||
[[ "${x}" == "${val}" ]] && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
function detect_iso_arch {
|
||||
local iso_file="${1}"
|
||||
local fallback_arch="${2}"
|
||||
case "${iso_file@L}" in
|
||||
*-amd64-*|*-x64-*)
|
||||
*-amd64-*|*-x64-*|*_x64_*)
|
||||
echo "amd64" ;;
|
||||
*-arm64-*|*-aarch64-*)
|
||||
echo "arm64" ;;
|
||||
@@ -92,14 +106,14 @@ function detect_host_arch {
|
||||
# Detect host and guest architecture
|
||||
declare -r HOST_ARCH="$(detect_host_arch)"
|
||||
[[ -n "${HOST_ARCH}" ]] || {
|
||||
echo "Failed to detect host arch" >&2;
|
||||
exit 1;
|
||||
echo "Failed to detect host arch" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
declare -r GUEST_ARCH="$(detect_iso_arch "${INSTALL_ISO}" "${HOST_ARCH}")"
|
||||
[[ -n "${GUEST_ARCH}" ]] || {
|
||||
echo "Failed to detect guest arch" >&2;
|
||||
exit 1;
|
||||
echo "Failed to detect guest arch" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Setup locations
|
||||
@@ -201,7 +215,6 @@ function fileext_from_qemu_image_type {
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
function expand_size {
|
||||
local value="${1}"
|
||||
[[ "${value}" =~ ^[0-9]+$ ]] && {
|
||||
@@ -256,7 +269,6 @@ function resize_image {
|
||||
do_resize_image "${img_file}" "${img_type}" "${img_cur_size}" "${img_req_size}"
|
||||
}
|
||||
|
||||
|
||||
# Drivers for the WinPE early installation environment
|
||||
declare -r VIRTIO_WINPE_DRIVERS=(
|
||||
"NetKVM"
|
||||
@@ -265,12 +277,15 @@ declare -r VIRTIO_WINPE_DRIVERS=(
|
||||
"viogpudo"
|
||||
)
|
||||
|
||||
function has {
|
||||
local val="${1}"; shift
|
||||
for x in $@; do
|
||||
[[ "${x}" == "${val}" ]] && return 0
|
||||
done
|
||||
return 1
|
||||
function guest_to_virtio_arch {
|
||||
local arch="${1@L}"
|
||||
case "${arch}" in
|
||||
"arm64") echo "${arch@U}" ;;
|
||||
"amd64") echo "${arch}" ;;
|
||||
*)
|
||||
echo "ERROR: Failed to determine virtio arch from '${arch}'" >&2
|
||||
return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
#
|
||||
@@ -294,16 +309,11 @@ function qemu_fill_unattend_fs {
|
||||
< "${unattend_xml}" > "${destdir}/autounattend.xml" || return $?
|
||||
|
||||
#
|
||||
local virtio_arch="${GUEST_ARCH@L}"
|
||||
case "${GUEST_ARCH@L}" in
|
||||
"arm64")
|
||||
virtio_arch="${GUEST_ARCH@U}" ;;
|
||||
"amd64")
|
||||
virtio_arch="${GUEST_ARCH@L}" ;;
|
||||
*)
|
||||
echo "ERROR: " >&2
|
||||
return 1 ;;
|
||||
esac
|
||||
# Additional resources
|
||||
# $OEM$\$$ -> C:\Windows
|
||||
# $OEM$\$1 -> C:\
|
||||
#
|
||||
mkdir -p "${destdir}/\$OEM\$/\$\$" "${destdir}/\$OEM\$/\$1" || return $?
|
||||
|
||||
# Copy virtio drivers
|
||||
local virtio_iso="${3}"
|
||||
@@ -312,6 +322,7 @@ function qemu_fill_unattend_fs {
|
||||
return 1
|
||||
}
|
||||
|
||||
local virtio_arch="$(guest_to_virtio_arch "${GUEST_ARCH}")" || return $?
|
||||
local virtio_drivers_list="$(7z l -slt "${virtio_iso}" | sed -ne "/^Path = [^/]\+\/w11\/${virtio_arch}\$/{ s|^Path = \([^/]\+\)/.*|\1|; p }")"
|
||||
[[ -n "${virtio_drivers_list}" ]] || {
|
||||
echo "ERROR: No drivers found in VirtIO ISO image '${virtio_iso}'" >&2
|
||||
@@ -339,31 +350,36 @@ function qemu_fill_unattend_fs {
|
||||
function qemu_generate_unattend_iso {
|
||||
local destfile="${1}"
|
||||
|
||||
local destdir="${BASEDIR}/unattend.tmp"
|
||||
local isogen_path=""
|
||||
for x in "mkisofs" "genisoimage" "xorriso"; do
|
||||
isogen_path="$(type -p "${x}" 2>/dev/null)" && break
|
||||
done
|
||||
[[ -n "${isogen_path}" ]] || {
|
||||
echo "ERROR: Failed to find one of mkisofs | genisoimage | xorriso" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
local destdir="${BASEDIR}/unattend.${SRANDOM:-"tmp"}"
|
||||
mkdir -p "${destdir}" || return $?
|
||||
|
||||
qemu_fill_unattend_fs "${destdir}" "${2}" "${3}" || return $?
|
||||
|
||||
if type -p "mkisofs" &>/dev/null; then
|
||||
mkisofs \
|
||||
-iso-level 3 -J -l -D -N -U -joliet-long -relaxed-filenames -rational-rock \
|
||||
-V "win11-builder-unattend" -o "${destfile}" -quiet \
|
||||
"${destdir}" || return $?
|
||||
elif type -p "genisoimage" &>/dev/null; then
|
||||
genisoimage \
|
||||
-iso-level 3 -J -l -D -N -U -joliet-long -allow-limited-size -relaxed-filenames -rock \
|
||||
-V "win11-builder-unattend" -o "${destfile}" -quiet \
|
||||
"${destdir}" || return $?
|
||||
elif type -p "xorriso" &>/dev/null; then
|
||||
echo "ERROR: xorriso support is pending" >&2
|
||||
return 1
|
||||
else
|
||||
echo "ERROR: Failed to find one of mkisofs | genisofs | xorriso" >&2
|
||||
return 1
|
||||
fi
|
||||
local isogen_name="$(basename "${isogen_path}")"
|
||||
case "${isogen_name}" in
|
||||
"mkisofs")
|
||||
${isogen_path} -iso-level 3 -J -l -D -N -U -joliet-long -relaxed-filenames -rational-rock \
|
||||
-V "win11-builder-unattend" -o "${destfile}" -quiet "${destdir}" || return $? ;;
|
||||
"genisoimage")
|
||||
${isogen_path} -iso-level 3 -J -l -D -N -U -joliet-long -relaxed-filenames -rock -allow-limited-size \
|
||||
-V "win11-builder-unattend" -o "${destfile}" -quiet "${destdir}" || return $? ;;
|
||||
"xorriso")
|
||||
echo "ERROR: ${isogen_name} support is pending" >&2
|
||||
return 1 ;;
|
||||
esac
|
||||
|
||||
# cleanup
|
||||
find "${destdir}" -delete || return $?
|
||||
find "${destdir}" -delete 2>/dev/null
|
||||
return 0
|
||||
}
|
||||
|
||||
function qemu_prepare_disk {
|
||||
|
||||
Reference in New Issue
Block a user