diff --git a/scripts/test-vm.sh b/scripts/test-vm.sh new file mode 100755 index 0000000..d1577d9 --- /dev/null +++ b/scripts/test-vm.sh @@ -0,0 +1,92 @@ +#!/bin/bash +# ============================================================ +# test-vm.sh — VM de test pour gameboot + dual-boot Windows, SANS RISQUE. +# +# Reproduit la machine cible : UEFI (OVMF, avec vars persistantes pour les +# entrées de boot), TPM 2.0 (swtpm), 3 disques NVMe virtuels (vide FWS / faux +# disque « jeux » / cible Windows). Disques qcow2 CREUX → coût disque réel = ce +# qui est écrit, pas la taille nominale. Aucune donnée réelle touchée. +# +# CE QUE ÇA VALIDE : build/boot de l'ISO, spoke « Dual-boot Windows », contrôle +# de conflit du récap, garde-fous fail-closed (choisir le disque FWS comme +# cible Windows → doit ABORTER), carve, wimlib apply, injection unattend, BCD +# (voie WinPE), OOBE Windows + auto-login + FirstBoot, l'aller-retour hibernate. +# CE QUE ÇA NE VALIDE PAS (→ vrai matériel) : resume du GPU RTX 5090, activation +# Secure Boot au firmware réel, et surtout VANGUARD (qui refuse justement la VM). +# +# Usage : +# scripts/test-vm.sh [ISO_FWS] [ISO_WINDOWS] +# ISO_FWS : défaut = la plus récente dans out/ (REBUILD d'abord : ./build-offi.sh !) +# ISO_WINDOWS : optionnelle, montée en 2e CD pour tester le déploiement Windows. +# +# Prérequis (Arch) : sudo pacman -S --needed qemu-full edk2-ovmf swtpm +# ============================================================ +set -euo pipefail + +REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +WORK="$REPO/out/test-vm" +mkdir -p "$WORK" + +# --- ISO FWS (rebuild indispensable pour avoir la feature gameboot) --------- +ISO_FWS="${1:-}" +if [ -z "$ISO_FWS" ]; then + ISO_FWS="$(find "$REPO/out" -name '*.iso' -not -path '*/test-vm/*' -printf '%T@ %p\n' 2>/dev/null \ + | sort -rn | head -1 | cut -d' ' -f2-)" +fi +[ -n "$ISO_FWS" ] && [ -f "$ISO_FWS" ] || { echo "ISO FWS introuvable — lance d'abord ./build-offi.sh"; exit 1; } +echo "==> ISO FWS : $ISO_FWS" +echo " (⚠ vérifie que c'est un build RÉCENT, avec gameboot — pas une vieille ISO de out/)" +ISO_WIN="${2:-}" + +# --- Outils --- +command -v qemu-system-x86_64 >/dev/null || { echo "installe : sudo pacman -S --needed qemu-full edk2-ovmf swtpm"; exit 1; } + +# --- OVMF (firmware UEFI) : code RO + vars RW par-VM ------------------------ +OVMF_CODE=""; OVMF_VARS_SRC="" +for c in /usr/share/edk2/x64/OVMF_CODE.4m.fd /usr/share/edk2/x64/OVMF_CODE.fd \ + /usr/share/OVMF/OVMF_CODE.fd /usr/share/edk2-ovmf/x64/OVMF_CODE.fd; do + [ -f "$c" ] && { OVMF_CODE="$c"; break; }; done +for v in /usr/share/edk2/x64/OVMF_VARS.4m.fd /usr/share/edk2/x64/OVMF_VARS.fd \ + /usr/share/OVMF/OVMF_VARS.fd /usr/share/edk2-ovmf/x64/OVMF_VARS.fd; do + [ -f "$v" ] && { OVMF_VARS_SRC="$v"; break; }; done +[ -n "$OVMF_CODE" ] && [ -n "$OVMF_VARS_SRC" ] || { echo "OVMF introuvable — sudo pacman -S edk2-ovmf"; exit 1; } +[ -f "$WORK/OVMF_VARS.fd" ] || cp "$OVMF_VARS_SRC" "$WORK/OVMF_VARS.fd" + +# --- Disques NVMe virtuels CREUX (recréés si absents) ----------------------- +# nvme0 = FWS (install) · nvme1 = faux « jeux » (doit rester intact) · +# nvme2 = cible Windows (assez grand : swap 96 Gio + NTFS + ESP). +mk(){ [ -f "$WORK/$1" ] || qemu-img create -f qcow2 "$WORK/$1" "$2" >/dev/null; } +mk fws.qcow2 64G +mk games.qcow2 32G +mk win.qcow2 300G +echo "==> Disques : $WORK/{fws,games,win}.qcow2 (creux)" + +# --- TPM 2.0 (swtpm) -------------------------------------------------------- +TPMDIR="$WORK/tpm"; mkdir -p "$TPMDIR" +swtpm socket --tpmstate dir="$TPMDIR" --ctrl type=unixio,path="$TPMDIR/sock" \ + --tpm2 --terminate & +SWTPM_PID=$! +trap 'kill "$SWTPM_PID" 2>/dev/null || true' EXIT +sleep 1 + +# --- CD Windows optionnel --------------------------------------------------- +WINCD=() +if [ -n "$ISO_WIN" ] && [ -f "$ISO_WIN" ]; then + WINCD=(-drive file="$ISO_WIN",media=cdrom,readonly=on) + echo "==> ISO Windows montée en 2e CD (dans le live : la monter, puis la pointer dans le spoke)." +fi + +echo "==> Lancement de la VM (UEFI + TPM2 + 3 NVMe). Ferme la fenêtre pour quitter." +exec qemu-system-x86_64 \ + -machine q35,smm=on,accel=kvm -cpu host -smp 4 -m 8G \ + -drive if=pflash,format=raw,readonly=on,file="$OVMF_CODE" \ + -drive if=pflash,format=raw,file="$WORK/OVMF_VARS.fd" \ + -chardev socket,id=chrtpm,path="$TPMDIR/sock" \ + -tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-crb,tpmdev=tpm0 \ + -drive file="$WORK/fws.qcow2",if=none,id=d0 -device nvme,drive=d0,serial=FWS0 \ + -drive file="$WORK/games.qcow2",if=none,id=d1 -device nvme,drive=d1,serial=GAMES1 \ + -drive file="$WORK/win.qcow2",if=none,id=d2 -device nvme,drive=d2,serial=WIN2 \ + -cdrom "$ISO_FWS" "${WINCD[@]}" \ + -boot menu=on \ + -netdev user,id=n0 -device virtio-net,netdev=n0 \ + -vga virtio -display gtk,gl=on