#!/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