vmix.nix/lib/images/windows/helpers/makeImage.nix
Git Sagar 015714f713 vmix CLI, laptop images, SDL display
CLI (nix run .#):
- `vmix build` and `vmix copy` subcommands
- --image, --generalize key=val, --to-disk, --to-remote-disk
- SDL display auto-detected via DISPLAY temp file passthrough
- --print-build-logs for visible build progress
- -S 4k sparse writes for faster disk copy

Images:
- win10.laptop and win11.laptop bundles (no VirtIO, keeps defender/hibernation)
- templates.bundles.laptop shared template list
- win11 adds reg.disableUCPD on top

Build improvements:
- consistent === vmix: === log prefixes
- SDL display via /tmp/.vmix-display-$$ temp file

Env helpers:
- .env-export-vmix-cli-local: vmix alias for local flake

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-23 21:56:51 -03:00

80 lines
2.7 KiB
Nix

# Build a pre-installed Windows qcow2 image using QEMU unattended install.
# Boots into Audit Mode after install and shuts down.
# Apply templates via customizeImageFold to install software (auditScript)
# and customize registry (windowsRegistry), then generalize when done.
{ pkgs, lib, drivers, makeWinISO, makeAuditModeAutounattend, ... }:
{
name ? "windows",
upstreamISO,
productKey ? "",
imageIndex ? 1,
diskSize ? "64G",
bypassRequirements ? false,
locale ? "en-US",
efi ? true,
smp ? 4,
memSize ? 4096,
vncDisplay ? null, # e.g. ":10" to enable VNC on port 5910 for monitoring
windowsVersionForVirtioDrivers ? "w10", # "w10", "w11", "2k22", "2k19", etc.
}:
let
AutounattendedXml = makeAuditModeAutounattend {
inherit locale productKey imageIndex
efi bypassRequirements windowsVersionForVirtioDrivers;
diskIndex = 0;
virtioDriverLetter = "E";
};
iso = makeWinISO {
iso = upstreamISO;
inherit AutounattendedXml;
};
displayArg = if vncDisplay != null then "-vnc ${vncDisplay}" else null;
drv = pkgs.runCommand "${name}-vmix.qcow2" {
__noChroot = true;
requiredSystemFeatures = [ "kvm" ];
nativeBuildInputs = with pkgs; [ qemu ];
} ''
echo "=== vmix: creating ${diskSize} disk ==="
qemu-img create -f qcow2 disk.qcow2 ${diskSize}
cp ${pkgs.OVMF.fd}/FV/OVMF_VARS.fd vars.fd
chmod +w vars.fd
echo "=== vmix: installing ${name} (unattended, 5-10 min) ==="
VMIX_DISPLAY="-nographic"
${lib.optionalString (displayArg != null) ''VMIX_DISPLAY="${displayArg}"''}
${lib.optionalString (displayArg == null) ''
VMIX_DF=$(ls -t /tmp/.vmix-display-* 2>/dev/null | head -1)
if [ -n "$VMIX_DF" ]; then
export DISPLAY=$(cat "$VMIX_DF")
VMIX_DISPLAY="-display sdl"
fi
''}
# Windows installs unattended, reboots into Audit Mode,
# deletes cached Autounattend, shuts down QEMU exits.
timeout 3600 qemu-system-x86_64 \
$VMIX_DISPLAY \
-accel kvm \
-m ${toString memSize} \
-smp ${toString smp} \
-cpu host \
-machine type=q35 \
-drive if=pflash,format=raw,readonly=on,file=${pkgs.OVMF.fd}/FV/OVMF_CODE.fd \
-drive if=pflash,format=raw,file=vars.fd \
-rtc base=localtime,clock=host \
-device qemu-xhci -device usb-tablet \
-global ICH9-LMB.disable_s3=1 -global ICH9-LMB.disable_s4=1 \
-drive file=disk.qcow2,format=qcow2,if=virtio \
-drive file=${iso},media=cdrom,readonly=on \
-drive file=${drivers.virtio-iso},media=cdrom,readonly=on \
-nic user,model=virtio-net-pci
echo "=== vmix: ${name} install complete ==="
mv disk.qcow2 $out
'';
in drv // { _vmixOsType = "windows"; }