Files
omarchy-iso/bin/omarchy-iso-test-windows-disk
T

296 lines
7.5 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(dirname "$SCRIPT_DIR")"
TEST_DISK="${OMARCHY_ISO_TEST_WINDOWS_DISK:-/tmp/omarchy-iso-test-windows.qcow2}"
TEST_OVMF_VARS="${OMARCHY_ISO_TEST_WINDOWS_OVMF_VARS:-/tmp/OVMF_VARS.omarchy-iso-test-windows.fd}"
DISK_SIZE_GIB=96
MIN_FREE_GIB=64
RECREATE=0
ISO=""
ACTIVE_NBD=""
MOUNT_DIR=""
MOUNTED=0
TEMPORARY_DISK=""
usage() {
cat <<USAGE
Usage: omarchy-iso-test-windows-disk [--recreate] [release/omarchy.iso]
Creates or validates a synthetic Windows-style test disk with:
- a 512MiB EFI partition containing EFI/Microsoft
- an existing ext4 data partition with a preservation marker
- more than 64GiB of contiguous unallocated space for Omarchy
This exercises Windows partition detection and preservation; it is not a
bootable Windows installation.
Options:
--recreate Replace the existing test fixture
-h, --help Show this help
Paths can be overridden with:
OMARCHY_ISO_TEST_WINDOWS_DISK
OMARCHY_ISO_TEST_WINDOWS_OVMF_VARS
USAGE
}
while (( $# > 0 )); do
case "$1" in
--recreate)
RECREATE=1
shift
;;
-h|--help)
usage
exit 0
;;
-*)
echo "Unknown option: $1" >&2
usage >&2
exit 2
;;
*)
if [[ -n $ISO ]]; then
echo "Only one ISO may be specified." >&2
usage >&2
exit 2
fi
ISO="$1"
shift
;;
esac
done
cleanup_mount() {
if (( MOUNTED )); then
sudo umount "$MOUNT_DIR" >/dev/null 2>&1 || true
MOUNTED=0
fi
if [[ -n $MOUNT_DIR ]]; then
rmdir "$MOUNT_DIR" >/dev/null 2>&1 || true
MOUNT_DIR=""
fi
}
disconnect_disk() {
cleanup_mount
if [[ -n $ACTIVE_NBD ]]; then
sudo qemu-nbd --disconnect "$ACTIVE_NBD" >/dev/null 2>&1 || true
ACTIVE_NBD=""
fi
}
cleanup() {
disconnect_disk
[[ -z $TEMPORARY_DISK ]] || rm -f "$TEMPORARY_DISK"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
find_free_nbd() {
local device
for device in /sys/class/block/nbd*; do
[[ -e $device ]] || continue
[[ ! -e $device/pid ]] || continue
printf '/dev/%s\n' "${device##*/}"
return 0
done
return 1
}
connect_disk() {
local disk="$1" mode="${2:-read-write}"
local -a options=(--format=qcow2)
ACTIVE_NBD="$(find_free_nbd)" || {
echo "No unused NBD device is available." >&2
return 1
}
[[ $mode == read-only ]] && options+=(--read-only)
if ! sudo qemu-nbd "${options[@]}" --connect="$ACTIVE_NBD" "$disk"; then
ACTIVE_NBD=""
return 1
fi
if ! sudo udevadm settle; then
disconnect_disk
return 1
fi
}
mount_partition() {
local partition="$1"
MOUNT_DIR="$(mktemp -d)" || return 1
if ! sudo mount -o "${2:-defaults}" "$partition" "$MOUNT_DIR"; then
rmdir "$MOUNT_DIR" >/dev/null 2>&1 || true
MOUNT_DIR=""
return 1
fi
MOUNTED=1
}
largest_free_region() {
sudo parted -ms "$1" unit B print free </dev/null 2>/dev/null |
awk -F: '
$NF ~ /free/ {
size=$4
gsub(/B/, "", size)
if (size+0 > max+0) max=size
}
END { print max+0 }
'
}
validate_test_disk() {
local part_count pttype free_space_b min_free_b
local esp data valid=1
[[ -f $TEST_DISK ]] || return 1
qemu-img check -q "$TEST_DISK" >/dev/null 2>&1 || return 1
connect_disk "$TEST_DISK" read-only || return 1
esp="${ACTIVE_NBD}p1"
data="${ACTIVE_NBD}p2"
part_count=$(lsblk -nro TYPE "$ACTIVE_NBD" | awk '$1 == "part" { count++ } END { print count+0 }')
pttype=$(lsblk -dnro PTTYPE "$ACTIVE_NBD" 2>/dev/null || true)
free_space_b=$(largest_free_region "$ACTIVE_NBD")
min_free_b=$((MIN_FREE_GIB * 1024 * 1024 * 1024))
[[ $pttype == gpt ]] || valid=0
(( part_count == 2 )) || valid=0
(( free_space_b >= min_free_b )) || valid=0
[[ $(sudo blkid -s TYPE -o value "$esp" 2>/dev/null || true) == vfat ]] || valid=0
[[ $(sudo blkid -s LABEL -o value "$esp" 2>/dev/null || true) == WINDOWS_ESP ]] || valid=0
[[ $(sudo blkid -s TYPE -o value "$data" 2>/dev/null || true) == ext4 ]] || valid=0
[[ $(sudo blkid -s LABEL -o value "$data" 2>/dev/null || true) == WINDOWS_DATA ]] || valid=0
if (( valid )); then
mount_partition "$esp" ro || valid=0
if (( valid )); then
sudo test -d "$MOUNT_DIR/EFI/Microsoft" || valid=0
fi
cleanup_mount
fi
if (( valid )); then
mount_partition "$data" ro || valid=0
if (( valid )); then
sudo test -f "$MOUNT_DIR/OMARCHY-MUST-NOT-TOUCH.txt" || valid=0
fi
cleanup_mount
fi
disconnect_disk
(( valid ))
}
create_test_disk() {
local esp data
mkdir -p "$(dirname "$TEST_DISK")"
TEMPORARY_DISK="${TEST_DISK}.creating.$$"
rm -f "$TEMPORARY_DISK"
gum style --foreground 6 "Creating synthetic Windows test disk at $TEST_DISK"
qemu-img create -f qcow2 "$TEMPORARY_DISK" "${DISK_SIZE_GIB}G"
connect_disk "$TEMPORARY_DISK"
sudo parted --script "$ACTIVE_NBD" mklabel gpt
sudo parted --script "$ACTIVE_NBD" mkpart WINDOWS_ESP fat32 1MiB 513MiB
sudo parted --script "$ACTIVE_NBD" set 1 esp on
sudo parted --script "$ACTIVE_NBD" mkpart WINDOWS_DATA ext4 513MiB 20GiB
sudo partprobe "$ACTIVE_NBD"
sudo udevadm settle
esp="${ACTIVE_NBD}p1"
data="${ACTIVE_NBD}p2"
sudo mkfs.fat -F32 -n WINDOWS_ESP "$esp" >/dev/null
sudo mkfs.ext4 -F -L WINDOWS_DATA "$data" >/dev/null 2>&1
mount_partition "$esp"
sudo mkdir -p "$MOUNT_DIR/EFI/Microsoft/Boot"
printf '%s\n' 'Synthetic Windows ESP for Omarchy ISO testing.' |
sudo tee "$MOUNT_DIR/EFI/Microsoft/README.txt" >/dev/null
cleanup_mount
mount_partition "$data"
printf '%s\n' 'This existing partition must survive the Omarchy installation.' |
sudo tee "$MOUNT_DIR/OMARCHY-MUST-NOT-TOUCH.txt" >/dev/null
cleanup_mount
sync
disconnect_disk
mv -f "$TEMPORARY_DISK" "$TEST_DISK"
TEMPORARY_DISK=""
}
select_iso() {
local -a isos=()
if [[ -n $ISO ]]; then
[[ -f $ISO ]] || {
echo "ISO not found: $ISO" >&2
return 1
}
realpath "$ISO"
return 0
fi
mapfile -t isos < <(
find "$REPO_ROOT/release" -maxdepth 1 -type f -name '*.iso' -printf '%T@ %p\n' 2>/dev/null |
sort -nr |
cut -d' ' -f2-
)
(( ${#isos[@]} > 0 )) || {
echo "No ISO found under $REPO_ROOT/release." >&2
return 1
}
printf '%s\n' "${isos[@]}" | gum choose --header "Select ISO to install"
}
omarchy-pkg-add qemu-full edk2-ovmf parted dosfstools e2fsprogs
sudo modprobe nbd max_part=16
if [[ -f $TEST_DISK ]] && (( ! RECREATE )); then
gum style --foreground 6 "Verifying existing test disk at $TEST_DISK"
if validate_test_disk; then
gum style --foreground 2 "✓ Synthetic Windows test disk is ready"
elif gum confirm --default=false "The existing test disk is not a pristine fixture. Recreate it?"; then
create_test_disk
else
gum style "Left the existing disk untouched."
exit 0
fi
else
create_test_disk
fi
# The synthetic fixture has no real Windows bootloader, so reset OVMF state for
# every run. The ISO still sees EFI/Microsoft and must leave that ESP untouched.
mkdir -p "$(dirname "$TEST_OVMF_VARS")"
cp /usr/share/edk2/x64/OVMF_VARS.4m.fd "$TEST_OVMF_VARS"
gum style --border rounded --padding "0 1" --border-foreground 6 \
"Synthetic Windows disk ready" \
"Disk: $TEST_DISK" \
"Layout: 512MiB Windows ESP + existing data + 64GiB+ free"
if gum confirm "Start installation on this disk?"; then
ISO="$(select_iso)"
trap - EXIT INT TERM
exec "$SCRIPT_DIR/omarchy-iso-boot" \
--reuse \
--disk "$TEST_DISK" \
--ovmf-vars "$TEST_OVMF_VARS" \
"$ISO" \
-- -boot once=d,menu=on
fi