- Add WGU Windows VM helper script + virtualization module (KVM/libvirt) - Fix create-wgu-vn: mkdir before use, CPU topology, detect OS variant - Add Webex, ZapZap, qalculate-gtk, libqalculate, tigervnc packages - Add n97-mini VNC alias, switch nr to local flake path - Tune trackpad (0.44) and TrackPoint (160/120) sensitivity - Reduce mouse sensitivity to -0.2 - Move zapzap from desktop.nix alphabetically - Remove OVMFFull from virtualisation (handled by swtpm/OVMF default) - Bump flake inputs (home-manager, nixos-hardware, nixpkgs, pi-mono)
167 lines
4.9 KiB
Bash
167 lines
4.9 KiB
Bash
#!/usr/bin/env bash
|
|
# Create a Windows VM for WGU Guardian browser (proctored testing)
|
|
# Usage: create-wgu-vm [windows-iso-path]
|
|
#
|
|
# If no ISO path given, scans ~/Downloads for Windows ISOs automatically.
|
|
# If none found, downloads Windows 10 22H2 from Microsoft.
|
|
# Always downloads VirtIO drivers.
|
|
#
|
|
# After creation, manage the VM: virt-manager
|
|
# Connect to the console: virt-viewer wgu-win
|
|
|
|
set -euo pipefail
|
|
|
|
VM_NAME="wgu-win"
|
|
RAM_MB=4096
|
|
CPUS=2
|
|
DISK_GB=64
|
|
VM_DIR="${HOME}/vms/${VM_NAME}"
|
|
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
info() { echo -e "${GREEN}==>${NC} $*"; }
|
|
warn() { echo -e "${YELLOW}==>${NC} $*"; }
|
|
err() { echo -e "${RED}==>${NC} $*" >&2; }
|
|
|
|
# --- Prerequisites ---
|
|
if ! command -v virsh &>/dev/null; then
|
|
err "libvirt not found. Run: nr"
|
|
err "Then log out and back in (for libvirtd group)."
|
|
exit 1
|
|
fi
|
|
|
|
if ! groups | grep -q libvirtd; then
|
|
warn "You're not in the libvirtd group. Run: nr"
|
|
warn "Then log out and back in."
|
|
fi
|
|
|
|
# --- Check if VM already exists ---
|
|
if virsh dominfo "$VM_NAME" &>/dev/null; then
|
|
info "VM '$VM_NAME' already exists."
|
|
echo ""
|
|
echo " Start it: virsh start $VM_NAME"
|
|
echo " Console: virt-viewer $VM_NAME"
|
|
echo " Manage: virt-manager"
|
|
exit 0
|
|
fi
|
|
|
|
# --- Find or download Windows ISO ---
|
|
WINDOWS_ISO="${1:-}"
|
|
|
|
# If no path given, scan ~/Downloads for Windows ISOs
|
|
if [ -z "$WINDOWS_ISO" ]; then
|
|
FOUND_ISOS=()
|
|
while IFS= read -r -d '' f; do
|
|
FOUND_ISOS+=("$f")
|
|
done < <(find "${HOME}/Downloads" -maxdepth 1 -iname 'Win*.iso' -print0 2>/dev/null)
|
|
|
|
if [ "${#FOUND_ISOS[@]}" -gt 0 ]; then
|
|
if [ "${#FOUND_ISOS[@]}" -eq 1 ]; then
|
|
WINDOWS_ISO="${FOUND_ISOS[0]}"
|
|
info "Using existing ISO: $(basename "$WINDOWS_ISO")"
|
|
else
|
|
echo ""
|
|
echo "Multiple Windows ISOs found in ~/Downloads:"
|
|
for i in "${!FOUND_ISOS[@]}"; do
|
|
echo " [$i] $(basename "${FOUND_ISOS[$i]}")"
|
|
done
|
|
read -rp "Choose one [0]: " CHOICE
|
|
CHOICE="${CHOICE:-0}"
|
|
WINDOWS_ISO="${FOUND_ISOS[$CHOICE]}"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Still nothing? try VM_DIR cache, then download Win10
|
|
if [ -z "$WINDOWS_ISO" ]; then
|
|
mkdir -p "$VM_DIR"
|
|
WINDOWS_ISO="${VM_DIR}/Win10_22H2_English_x64.iso"
|
|
if [ ! -f "$WINDOWS_ISO" ]; then
|
|
info "No local ISO found. Downloading Windows 10 22H2 from Microsoft..."
|
|
info "URL: https://go.microsoft.com/fwlink/?LinkID=2151180"
|
|
warn "This is ≈6 GB — go make some coffee."
|
|
curl -L -o "$WINDOWS_ISO" \
|
|
"https://go.microsoft.com/fwlink/?LinkID=2151180&clcid=0x409&culture=en-us&country=us" \
|
|
--progress-bar
|
|
fi
|
|
fi
|
|
|
|
if [ ! -f "$WINDOWS_ISO" ]; then
|
|
err "Windows ISO not found at: $WINDOWS_ISO"
|
|
exit 1
|
|
fi
|
|
|
|
# --- Detect Windows version for os-variant ---
|
|
IS_NAME=$(basename "$WINDOWS_ISO")
|
|
case "$IS_NAME" in
|
|
*1[0-9]*|*Win10*|*win10*|*WINDOWS_10*)
|
|
OS_VARIANT="win10" ;;
|
|
*1[12]*|*Win11*|*win11*|*WINDOWS_11*)
|
|
OS_VARIANT="win11" ;;
|
|
*)
|
|
OS_VARIANT="win10" ;;
|
|
esac
|
|
info "Detected OS variant: $OS_VARIANT"
|
|
|
|
# --- Ensure VM directory exists ---
|
|
mkdir -p "$VM_DIR"
|
|
|
|
# --- VirtIO drivers ISO ---
|
|
VIRTIO_ISO="${VM_DIR}/virtio-win.iso"
|
|
if [ ! -f "$VIRTIO_ISO" ]; then
|
|
info "Downloading VirtIO drivers..."
|
|
curl -L -o "$VIRTIO_ISO" \
|
|
"https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso" \
|
|
--progress-bar
|
|
fi
|
|
|
|
# --- Disk image ---
|
|
DISK_IMG="${VM_DIR}/disk.qcow2"
|
|
if [ ! -f "$DISK_IMG" ]; then
|
|
info "Creating ${DISK_GB}G qcow2 disk image..."
|
|
qemu-img create -f qcow2 "$DISK_IMG" "${DISK_GB}G"
|
|
fi
|
|
|
|
# --- Create VM ---
|
|
info "Creating VM '$VM_NAME' (${OS_VARIANT})..."
|
|
sudo virt-install \
|
|
--name "$VM_NAME" \
|
|
--ram "$RAM_MB" \
|
|
--vcpus $CPUS,sockets=1,cores=$CPUS,threads=1 \
|
|
--cpu host-passthrough \
|
|
--os-variant "$OS_VARIANT" \
|
|
--disk path="$DISK_IMG",format=qcow2,bus=virtio \
|
|
--cdrom "$WINDOWS_ISO" \
|
|
--disk path="$VIRTIO_ISO",device=cdrom \
|
|
--network network=default,model=virtio \
|
|
--graphics spice,listen=none \
|
|
--video virtio \
|
|
--sound ich9 \
|
|
--channel spicevmc \
|
|
--tpm backend.type=emulator,model=tpm-crb,version=2.0 \
|
|
--boot uefi \
|
|
--noautoconsole
|
|
|
|
echo ""
|
|
info "VM created! Next steps:"
|
|
echo ""
|
|
echo " 1. Connect to the VM console:"
|
|
echo " virt-viewer $VM_NAME"
|
|
echo ""
|
|
echo " 2. During Windows install, when it can't find drives:"
|
|
echo " Browse → Load Driver → virtio-win ISO → vioscsi → ${OS_VARIANT} → amd64 → OK"
|
|
echo " Then select the visible disk and continue installation."
|
|
echo ""
|
|
echo " 3. After Windows installs, install Spice Guest Tools:"
|
|
echo " Open the virtio-win ISO in Windows → run virtio-win-guest-tools.exe"
|
|
echo " This gives you clipboard sharing, auto-resize, and better performance."
|
|
echo ""
|
|
echo " 4. Install the Guardian browser inside the VM for proctored WGU tests."
|
|
echo ""
|
|
echo " Manage: virt-manager"
|
|
echo " Start: virsh start $VM_NAME"
|
|
echo " Stop: virsh shutdown $VM_NAME"
|
|
echo " Console: virt-viewer $VM_NAME"
|