nixfiles/lib/windows/readme.md
2024-01-08 07:51:19 +03:00

2.2 KiB
Executable file

Utils for Windows VMs provisioning and management (for fun)

The idea is first to create a base image with all the required software and then create a VM from it. Base system image is ephemeral and is reset on every boot. User data is stored in a separate persistent image, which is mounted as D: drive.

The downside of this approach is that it takes a lot of time to create a base image, and every software install requires basically reinstalling windows. The upside is that the system is always in a clean state and you can easily create a new VM from the base image.

Usage

  • Download Windows ISO from Microsoft
  • List available editions in the ISO:
    nix-shell -p wimlib
    mkdir isomnt
    sudo mount -o loop /etc/iso/win11.iso isomnt
    wiminfo ./mnt/sources/install.wim | grep "^Name:"
    sudo umount isomnt
    rm -rf isomnt
    
  • Create a base image:
    let 
      windows = import ./windows.nix { inherit pkgs; };
    in {
      some-image = windows.makeBaseImage { 
        windowsIso = /etc/iso/win11.iso;
        additionalFiles = [
          # optional, for ssh server
          windows.utils.openSshServerPackage
        ];
        unattendedParams = {
          users = {};
          administators = {
            "teidesu" = "0";
          };
          edition = "Windows 11 Pro";
        };
        preLoginScript = with windows.custom; compile [
          (system.withHostname "TEST")
          (network.withSshServer {
            keys = [
              ../ssh/teidesu.pub
            ];
          })
          # ...
        ];
      };
    }
    
  • Create a VM:
    systemd.services.windows = makeSystemdService {
      systemImage = some-image;
      name = "kyoko";
      userImageSize = "100G";
      qemuOptions = {
        macAddress = "00:16:D0:3B:E2:DC";
        extraFlags = [
          "-usbdevice tablet"
        ];
      };
    }
    

Networking

When the VM is booted for the first time to make the base image, it will use qemu dhcp server to get an ip address. This is done to avoid having issues with access to /dev/net/tun for nix builder.

After that, when running as a systemd service, the VM will use an automatically managed TAP. By default, it is configured to use br0.

Acknowledgements: