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>
This commit is contained in:
Git Sagar 2026-05-23 21:56:51 -03:00
parent 94f299bb81
commit 015714f713
8 changed files with 250 additions and 53 deletions

View file

@ -62,6 +62,8 @@
cdromArgs = lib.concatMapStringsSep " \\\n " (cd: "-drive file=${cd},media=cdrom,readonly=on") cdroms;
displayArg = if vncDisplay != null then "-vnc ${vncDisplay}" else null;
auditBootCommands = lib.optionalString hasAuditScript ''
echo "=== vmix: injecting audit script (${name}) ==="
@ -77,9 +79,19 @@
cp ${pkgs.OVMF.fd}/FV/OVMF_VARS.fd vars.fd
chmod +w vars.fd
echo "=== vmix: booting Audit Mode for ${name} (VNC: ${if vncDisplay != null then vncDisplay else "disabled"}) ==="
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
''}
echo "=== vmix: booting Audit Mode for ${name} ==="
timeout 1800 qemu-system-x86_64 \
${if vncDisplay != null then "-vnc ${vncDisplay}" else "-nographic"} \
$VMIX_DISPLAY \
-accel kvm \
-m ${toString memSize} \
-smp ${toString smp} \

View file

@ -30,24 +30,35 @@ let
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 ];
} ''
# create empty disk
echo "=== vmix: creating ${diskSize} disk ==="
qemu-img create -f qcow2 disk.qcow2 ${diskSize}
# writable UEFI NVRAM so boot order persists across reboots
cp ${pkgs.OVMF.fd}/FV/OVMF_VARS.fd vars.fd
chmod +w vars.fd
echo "=== Starting Windows unattended install (this takes 15-30 minutes) ==="
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 \
${if vncDisplay != null then "-vnc ${vncDisplay}" else "-nographic"} \
$VMIX_DISPLAY \
-accel kvm \
-m ${toString memSize} \
-smp ${toString smp} \
@ -63,7 +74,7 @@ let
-drive file=${drivers.virtio-iso},media=cdrom,readonly=on \
-nic user,model=virtio-net-pci
echo "=== Windows install complete (Audit Mode image) ==="
echo "=== vmix: ${name} install complete ==="
mv disk.qcow2 $out
'';
in drv // { _vmixOsType = "windows"; }

View file

@ -7,7 +7,7 @@
{ pkgs, lib, system, drivers, makeFilesISO, ... }:
let
args = { inherit pkgs lib system drivers makeFilesISO; };
in {
in rec {
# Essentials (drivers, runtimes, removals, performance)
essentials = {
virtioTools = import ./essentials/virtio-tools.nix args;
@ -40,4 +40,30 @@ in {
# Offline registry templates
reg = import ./registry args;
# Bundles — reusable template lists for common use cases
bundles = {
laptop = [
essentials.removeIE
essentials.removeWMP
essentials.removeEdge
essentials.vcppRuntimes
essentials.bestPerformance
reg.disableTelemetry
reg.disableErrorReporting
reg.disableUpdates
reg.disableSmartScreen
reg.disablePrivacyTracking
reg.disableAI
reg.disableConsumerFeatures
reg.performanceTweaks
apps.edgeWebview
apps.thorium
apps.sandboxie
apps.sevenZip
apps.vlc
apps.imageGlass
apps.office
];
};
}

View file

@ -31,4 +31,10 @@ with windows;
withAMDGPU = customizeImage basic templates.essentials.amdGpuDrivers;
};
laptop = customizeImageFold (makeImage {
name = "win10-ltsc-2021-laptop";
upstreamISO = upstreamISOs.win10-ltsc-2021;
productKey = "M7XTQ-FN8P6-TTKYV-9D4CC-J462D";
}) templates.bundles.laptop;
}

View file

@ -35,4 +35,12 @@ with windows;
withAMDGPU = customizeImage basic templates.essentials.amdGpuDrivers;
};
laptop = customizeImageFold (makeImage {
name = "win11-ltsc-2024-laptop";
upstreamISO = upstreamISOs.win11-ltsc-2024;
productKey = "M7XTQ-FN8P6-TTKYV-9D4CC-J462D";
bypassRequirements = true;
windowsVersionForVirtioDrivers = "w11";
}) (templates.bundles.laptop ++ [ templates.reg.disableUCPD ]);
}