diff --git a/wfvm/autounattend.nix b/wfvm/autounattend.nix index 66744b7..6033b21 100644 --- a/wfvm/autounattend.nix +++ b/wfvm/autounattend.nix @@ -13,7 +13,8 @@ , timeZone ? "UTC" , services ? {} , impureShellCommands ? [] -, driveLetter ? "E:" +, driveLetter ? "D:" +, efi ? true , ... }: @@ -144,12 +145,12 @@ let 1 - EFI - 100 + ${if efi then "EFI" else "Primary"} + 300 2 - MSR + ${if efi then "MSR" else "Primary"} 16 @@ -161,7 +162,7 @@ let 1 - FAT32 + ${if efi then "FAT32" else "NTFS"} 1 diff --git a/wfvm/utils.nix b/wfvm/utils.nix index 4084eca..de605ac 100644 --- a/wfvm/utils.nix +++ b/wfvm/utils.nix @@ -1,4 +1,4 @@ -{ pkgs, baseRtc ? "2020-04-20T14:21:42", cores ? "4", qemuMem ? "4G" }: +{ pkgs, baseRtc ? "2020-04-20T14:21:42", cores ? "4", qemuMem ? "4G", efi ? true }: rec { # qemu_test is a smaller closure only building for a single system arch @@ -9,10 +9,12 @@ rec { "-cpu host" "-smp ${cores}" "-m ${qemuMem}" - "-bios ${pkgs.OVMF.fd}/FV/OVMF.fd" + "-M q35" "-rtc base=${baseRtc}" - "-device piix3-usb-uhci" + "-device qemu-xhci" "-device e1000,netdev=n1" + ] ++ pkgs.lib.optionals efi [ + "-bios ${pkgs.OVMF.fd}/FV/OVMF.fd" ] ++ extraFlags; # Pass empty config file to prevent ssh from failing to create ~/.ssh diff --git a/wfvm/win.nix b/wfvm/win.nix index 395ee8c..9ee442b 100644 --- a/wfvm/win.nix +++ b/wfvm/win.nix @@ -5,12 +5,15 @@ , impureMode ? false , installCommands ? [] , users ? {} +# autounattend always installs index 1, so this default is backward-compatible +, imageSelection ? "1" +, efi ? true , ... }@attrs: let lib = pkgs.lib; - utils = import ./utils.nix { inherit pkgs; }; + utils = import ./utils.nix { inherit pkgs efi; }; libguestfs = pkgs.libguestfs-with-appliance; # p7zip on >20.03 has known vulns but we have no better option @@ -83,7 +86,7 @@ let "usb-storage,drive=virtio-win" # USB boot "-drive" - "id=win-install,file=usbimage.img,if=none,format=raw,readonly=on" + "id=win-install,file=${if efi then "usb" else "cd"}image.img,if=none,format=raw,readonly=on,media=${if efi then "disk" else "cdrom"}" "-device" "usb-storage,drive=win-install" # Output image @@ -96,7 +99,7 @@ let '' #!${pkgs.runtimeShell} set -euxo pipefail - export PATH=${lib.makeBinPath [ p7zip utils.qemu libguestfs ]}:$PATH + export PATH=${lib.makeBinPath [ p7zip utils.qemu libguestfs pkgs.wimlib ]}:$PATH # Create a bootable "USB" image # Booting in USB mode circumvents the "press any key to boot from cdrom" prompt @@ -106,9 +109,27 @@ let mkdir -p win/nix-win 7z x -y ${windowsIso} -owin + # Extract desired variant from install.wim + # This is useful if the install.wim contains multiple Windows + # versions (e.g., Home, Pro, ..), because the autounattend file + # will always select index 1. With this mechanism, a variant different + # from the first one can be automatically selected. + # imageSelection can be either an index (1-N) or the image name + # wiminfo can list all images contained in a given WIM file + wimexport win/sources/install.wim "${imageSelection}" win/sources/install_selected.wim + rm win/sources/install.wim + + # Split image so it fits in FAT32 partition + wimsplit win/sources/install_selected.wim win/sources/install.swm 4096 + rm win/sources/install_selected.wim + cp ${autounattend.autounattendXML} win/autounattend.xml + ${if efi then '' virt-make-fs --partition --type=fat win/ usbimage.img + '' else '' + ${pkgs.cdrkit}/bin/mkisofs -iso-level 4 -l -R -udf -D -b boot/etfsboot.com -no-emul-boot -boot-load-size 8 -hide boot.catalog -eltorito-alt-boot -o cdimage.img win/ + ''} rm -rf win # Qemu requires files to be rw