diff --git a/lib/config/custom-build-vm.nix b/lib/config/custom-build-vm.nix index bbdd00f..74f1504 100644 --- a/lib/config/custom-build-vm.nix +++ b/lib/config/custom-build-vm.nix @@ -2,6 +2,7 @@ let packageName = "custom-nixos-vm"; + # Determine `system.build` configuration without this file's influence mergedBuildOption = with options.system; lib.mergeDefinitions @@ -15,10 +16,12 @@ let build.definitionsWithLocations) (item: { inherit (item) file value; })); + # Get vanilla `config.system.build.vm` vanillaVM = mergedBuildOption.mergedValue.vm; in { options = let + # Add new options to `config.virtualisation.vmVariant` and `config.virtualisation.vmVariantWithBootLoader` vmVariantOptions = { virtualisation = { runAsRoot = lib.mkOption { @@ -70,11 +73,14 @@ in { let extendVMConfig = vmVariant: { + # Prevent GRUB2 errors in `nixos-rebuild build-vm-with-bootloader` boot.loader.efi.efiSysMountPoint = lib.mkVMOverride "/boot"; virtualisation = { + # Enable root permissions to get access to the `/etc/ssh` directory runAsRoot = lib.mkIf vmVariant.virtualisation.sharedHostKeys true; + # Enable spice and run QEMU in background to let `remote-viewer` take over qemu = { spice.enable = lib.mkIf vmVariant.virtualisation.virt-viewer true; runInBackground = lib.mkIf vmVariant.virtualisation.virt-viewer true; @@ -93,6 +99,7 @@ in { ]))); }; + # Map SSH keys into the vm if necessary sharedDirectories = lib.optionalAttrs (vmVariant.virtualisation.sharedHostKeys) { hostKeys = let @@ -111,7 +118,6 @@ in { vmVariantWithBootLoader = extendVMConfig virtualisation.vmVariantWithBootLoader; }; - # Replace native `qemu` with `remote-viewer` system.build = { vm = lib.mkForce ( @@ -124,6 +130,7 @@ in { let originalCommand = "${vm}/bin/run-${config.system.name}-vm"; + # Have the command run in background if requested suffix = lib.concatStringsSep " " ( lib.optional config.virtualisation.qemu.runInBackground "&"); @@ -135,18 +142,21 @@ in { "${originalCommand} ${suffix}" ] ++ ( let - spice = config.virtualisation.qemu.spice; + # Run `remote-viewer` as normal user to limit access viewerPrefix = "sudo -Eu\"#$SUDO_UID\" "; + spice = config.virtualisation.qemu.spice; in ( lib.optionals config.virtualisation.virt-viewer [ "${viewerPrefix}${pkgs.virt-viewer}/bin/remote-viewer spice://${lib.escapeShellArg spice.bindAddress}:${toString spice.port}" + # Kill QEMU after `remote-viewer` finished running "kill %1" ]))); }; + # Run VM as root if requested wrapped = if !config.virtualisation.runAsRoot then