vmix.nix/nixos/vms/submoduleOptions.nix
Git Sagar ed92e36456 add nicModel option, restore MAS activation with LTSC key fix
- Add nicModel option (default: virtio-net-pci) to allow e1000 for
  images without VirtIO drivers
- Restore MAS activation with slmgr /ipk to switch back from IoT
  Enterprise S to Enterprise LTSC (which has native RDP server)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-08 14:04:08 +05:30

320 lines
9.9 KiB
Nix

{ config, pkgs, lib, vmixLib, ... }:
with lib;
{
options = {
autostart = mkOption {
type = types.bool;
default = false;
description = "Start VM on host boot.";
};
enable = mkOption {
type = types.bool;
default = true;
description = "Enable/disable VM service creation.";
};
vnc = {
enable = mkOption {
type = types.bool;
default = false;
description = "Enable VNC.";
};
addr = mkOption {
type = types.str;
default = "0.0.0.0";
description = "VNC bind address inside the VM namespace.";
};
port = mkOption {
type = types.ints.between 5900 5999;
default = 5900;
description = "VNC TCP port inside the VM namespace.";
};
forwardHostPort = mkOption {
type = types.nullOr types.port;
default = null;
description = "Optional host TCP port to auto-forward to this VM VNC port.";
};
websocketPort = mkOption {
type = types.nullOr types.port;
default = null;
description = "Optional websocket port for VNC (for noVNC-style clients).";
};
passwordFile = mkOption {
type = types.nullOr types.str;
default = null;
description = "Path to a runtime file containing the VNC password. When set, VNC auth is enabled via password-secret.";
};
sharePolicy = mkOption {
type = types.enum [ "allow-exclusive" "force-shared" "ignore" ];
default = "allow-exclusive";
description = "VNC client sharing policy.";
};
};
spice = {
enable = mkOption {
type = types.bool;
default = false;
description = "Enable SPICE display server.";
};
port = mkOption {
type = types.int;
default = 5930;
description = "SPICE TCP port inside the VM namespace.";
};
forwardHostPort = mkOption {
type = types.nullOr types.port;
default = null;
description = "Optional host TCP port to auto-forward to this VM SPICE port.";
};
addr = mkOption {
type = types.str;
default = "0.0.0.0";
description = "SPICE bind address inside the VM namespace.";
};
passwordFile = mkOption {
type = types.nullOr types.str;
default = null;
description = "Path to a runtime file containing SPICE password. When set, ticketing is enabled automatically, otherwise ticketing is disabled.";
};
agent.enable = mkOption {
type = types.bool;
default = true;
description = "Enable SPICE guest agent channel (clipboard/resolution helpers).";
};
usbRedir = {
enable = mkOption {
type = types.bool;
default = false;
description = "Enable SPICE USB redirection channels.";
};
channels = mkOption {
type = types.ints.between 1 16;
default = 4;
description = "Number of SPICE USB redirection channels to expose.";
};
};
displayDevice = mkOption {
type = types.enum [ "virtio" "qxl" "std" "none" ];
default = "qxl";
description = "QEMU -vga type to use with SPICE (qxl, virtio, std, none).";
};
vgamem = mkOption {
type = types.nullOr types.int;
default = null;
description = "Video memory in MB for QXL device. When set, uses -device qxl-vga instead of -vga qxl.";
};
};
nographic = mkOption {
type = types.bool;
default = true;
description = "Run QEMU without a graphical window (-nographic).";
};
cpu.cores = mkOption {
type = types.int;
default = 2;
description = "Number of CPU cores.";
};
cpu.model = mkOption {
type = types.str;
default = "host";
description = "CPU model.";
};
cpu.hideVirtualized = mkOption {
type = types.bool;
default = true;
description = "Hide hypervisor from guest. Prevents GPU driver Code 43 errors by stripping hypervisor CPUID leaf.";
};
kvm = mkOption {
type = types.bool;
default = true;
description = "Enable KVM.";
};
arch = mkOption {
type = types.str;
default = "x86_64";
description = "Architecture of the VM.";
};
pc.type = mkOption {
type = types.str;
default = "q35";
description = "PC type.";
};
bios.efi = mkOption {
type = types.bool;
default = true;
description = "Enable EFI BIOS.";
};
bios.tpm = mkOption {
type = types.bool;
default = false;
description = "Enable TPM BIOS.";
};
mem.size = mkOption {
type = types.int;
default = 1024;
description = "Memory size in MB.";
};
mem.balloon = mkOption {
type = types.bool;
default = false;
description = "Enable memory ballooning.";
};
disks.os.file = mkOption {
type = types.nullOr types.path;
default = null;
description = "Path to the OS disk image. Null for ISO-only VMs. For Windows, use a vmixLib.windows.* image config auto-detects via _vmixOsType metadata.";
};
disks.os.persist = mkOption {
type = types.bool;
default = false;
description = "Persist OS disk changes. The store image is copied to persistPath on first boot and QEMU writes to that mutable copy.";
};
disks.os.persistPath = mkOption {
type = types.str;
default = "";
description = "Mutable path for the persistent OS disk (e.g. /storage/vms/myvm/os.qcow2). Required when persist = true.";
};
disks.iso.file = mkOption {
type = types.nullOr (types.either types.path types.str);
description = "Path to the ISO file. Can be a Nix store path or a string path to a local file.";
default = null;
};
disks.add = mkOption {
default = {};
type = types.attrsOf (types.submodule {
options = {
file = mkOption {
type = types.str;
description = "String literal path to the additional disk.";
};
format = mkOption {
type = types.str;
description = "raw/qcow2 etc";
};
mounts = mkOption {
type = types.attrsOf types.str;
description = "Mount points for the additional disk.";
};
opts = mkOption {
type = types.str;
description = "additional options in QEMU args for this disk";
};
};
});
description = "Additional disks.";
};
shares = mkOption {
default = {};
type = types.attrsOf (types.submodule {
options = {
source = mkOption {
type = types.path;
description = "Source path for the shared directory.";
};
target = mkOption {
type = types.str;
description = "Target path inside the VM for the shared directory.";
};
};
});
description = "Shared directories.";
};
disks.bus = mkOption {
type = types.str;
default = "virtio";
description = "Bus type for the disks.";
};
boot.order = mkOption {
type = types.listOf (types.enum [ "os" "iso" "net" "floppy" ]);
description = "Boot order.";
default = [ "os" "iso" ];
};
boot.menu = mkOption {
type = types.bool;
default = false;
description = "Enable boot menu.";
};
nicModel = mkOption {
type = types.str;
default = "virtio-net-pci";
description = "QEMU NIC device model (e.g. virtio-net-pci, e1000).";
};
windows = {
enable = mkOption {
type = types.bool;
default = false;
description = "Enable Windows-optimized QEMU flags. Auto-enabled when disks.os.file carries _vmixOsType = \"windows\" metadata.";
};
};
tpm = {
stateDir = mkOption {
type = types.str;
default = "/tmp";
description = "Directory for TPM state persistence. Set to a /storage path for persistence across reboots.";
};
};
pci.passthrough = mkOption {
type = types.listOf types.str;
default = [];
description = "PCI device addresses to passthrough via VFIO (e.g. [\"0000:03:00.0\" \"0000:03:00.1\"]).";
};
pci.romFile = mkOption {
type = types.nullOr types.path;
default = null;
description = "GPU VBIOS ROM file for the first passthrough device. Required when GPU PCI ROM BAR doesn't expose the full VBIOS (common with AMD Navi+).";
};
usb.hostDevices = mkOption {
default = [];
type = types.listOf (types.submodule {
options = {
vendorId = mkOption { type = types.str; description = "USB vendor ID (e.g. \"1d6b\")."; };
productId = mkOption { type = types.str; description = "USB product ID (e.g. \"0104\")."; };
};
});
description = "USB host devices to passthrough to the VM.";
};
networks.user.enable = mkOption {
type = types.bool;
default = false;
description = "enable qemu user networking";
};
networks.lans = mkOption {
default = {};
type = types.attrsOf (types.submodule {
options = {
mac = mkOption {
type = types.str;
description = "MAC address for the LAN interface.";
};
ip = mkOption {
type = types.nullOr (types.strMatching vmixLib.network.regex.ipv4);
default = null;
description = "assign static IP from the lan pool.";
};
};
});
description = "LAN interfaces.";
};
networks.macvtaps = mkOption {
default = {};
type = types.attrsOf (types.submodule {
options = {
mac = mkOption {
type = types.nullOr types.str;
default = null;
description = "MAC address for the MACVTap interface.";
};
};
});
description = "MACVTap interfaces.";
};
};
}