From cdf9fa1753f62037abab8255c2280164cf23be66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Tue, 19 Aug 2025 15:45:57 +0000 Subject: [PATCH] move vm configuration into a stand-alone module and include it in our test vms This hasn't reduced the extra deps we have to pass to our nixos build unfortunally, but maybe at least it can safe us a few in the future. --- nixosModules/clanCore/vm-base.nix | 116 ++++++++++++++++++ nixosModules/clanCore/vm.nix | 109 +--------------- nixosModules/flake-module.nix | 3 + pkgs/clan-cli/clan_cli/tests/flake-module.nix | 4 + 4 files changed, 125 insertions(+), 107 deletions(-) create mode 100644 nixosModules/clanCore/vm-base.nix diff --git a/nixosModules/clanCore/vm-base.nix b/nixosModules/clanCore/vm-base.nix new file mode 100644 index 000000000..739cf57b8 --- /dev/null +++ b/nixosModules/clanCore/vm-base.nix @@ -0,0 +1,116 @@ +# Standalone VM base module that can be imported independently +# This module contains the core VM configuration without the system extension +{ + lib, + config, + pkgs, + modulesPath, + ... +}: +let + # Flatten the list of state folders into a single list + stateFolders = lib.flatten ( + lib.mapAttrsToList (_item: attrs: attrs.folders) config.clan.core.state + ); +in +{ + imports = [ + (modulesPath + "/virtualisation/qemu-vm.nix") + ./serial.nix + ./waypipe.nix + ]; + + clan.core.state.HOME.folders = [ "/home" ]; + + clan.services.waypipe = { + inherit (config.clan.core.vm.inspect.waypipe) enable command; + }; + + # required for issuing shell commands via qga + services.qemuGuest.enable = true; + + # required to react to system_powerdown qmp command + # Some desktop managers like xfce override the poweroff signal and therefore + # make it impossible to handle it via 'logind' directly. + services.acpid.enable = true; + services.acpid.handlers.power.event = "button/power.*"; + services.acpid.handlers.power.action = "poweroff"; + + # only works on x11 + services.spice-vdagentd.enable = config.services.xserver.enable; + + boot.initrd.systemd.enable = true; + + boot.initrd.systemd.storePaths = [ + pkgs.util-linux + pkgs.e2fsprogs + ]; + boot.initrd.systemd.emergencyAccess = true; + + # userborn would be faster because it doesn't need perl, but it cannot create normal users + services.userborn.enable = true; + users.mutableUsers = false; + users.allowNoPasswordLogin = true; + + boot.initrd.kernelModules = [ "virtiofs" ]; + virtualisation.writableStore = false; + virtualisation.fileSystems = lib.mkForce ( + { + "/nix/store" = { + device = "nix-store"; + options = [ + "x-systemd.requires=systemd-modules-load.service" + "ro" + ]; + fsType = "virtiofs"; + }; + + "/" = { + device = "/dev/vda"; + fsType = "ext4"; + options = [ + "defaults" + "x-systemd.makefs" + "nobarrier" + "noatime" + "nodiratime" + "data=writeback" + "discard" + ]; + }; + + "/vmstate" = { + device = "/dev/vdb"; + options = [ + "x-systemd.makefs" + "noatime" + "nodiratime" + "discard" + ]; + noCheck = true; + fsType = "ext4"; + }; + + ${config.clan.core.facts.secretUploadDirectory} = { + device = "secrets"; + fsType = "9p"; + neededForBoot = true; + options = [ + "trans=virtio" + "version=9p2000.L" + "cache=loose" + ]; + }; + } + // lib.listToAttrs ( + map ( + folder: + lib.nameValuePair folder { + device = "/vmstate${folder}"; + fsType = "none"; + options = [ "bind" ]; + } + ) stateFolders + ) + ); +} diff --git a/nixosModules/clanCore/vm.nix b/nixosModules/clanCore/vm.nix index c3c6c73ac..bcd2efac8 100644 --- a/nixosModules/clanCore/vm.nix +++ b/nixosModules/clanCore/vm.nix @@ -4,116 +4,11 @@ pkgs, options, extendModules, - modulesPath, ... }: let - # Flatten the list of state folders into a single list - stateFolders = lib.flatten ( - lib.mapAttrsToList (_item: attrs: attrs.folders) config.clan.core.state - ); - - vmModule = { - imports = [ - (modulesPath + "/virtualisation/qemu-vm.nix") - ./serial.nix - ./waypipe.nix - ]; - - clan.core.state.HOME.folders = [ "/home" ]; - - clan.services.waypipe = { - inherit (config.clan.core.vm.inspect.waypipe) enable command; - }; - - # required for issuing shell commands via qga - services.qemuGuest.enable = true; - - # required to react to system_powerdown qmp command - # Some desktop managers like xfce override the poweroff signal and therefore - # make it impossible to handle it via 'logind' directly. - services.acpid.enable = true; - services.acpid.handlers.power.event = "button/power.*"; - services.acpid.handlers.power.action = "poweroff"; - - # only works on x11 - services.spice-vdagentd.enable = config.services.xserver.enable; - - boot.initrd.systemd.enable = true; - - boot.initrd.systemd.storePaths = [ - pkgs.util-linux - pkgs.e2fsprogs - ]; - boot.initrd.systemd.emergencyAccess = true; - - # userborn would be faster because it doesn't need perl, but it cannot create normal users - services.userborn.enable = true; - users.mutableUsers = false; - users.allowNoPasswordLogin = true; - - boot.initrd.kernelModules = [ "virtiofs" ]; - virtualisation.writableStore = false; - virtualisation.fileSystems = lib.mkForce ( - { - "/nix/store" = { - device = "nix-store"; - options = [ - "x-systemd.requires=systemd-modules-load.service" - "ro" - ]; - fsType = "virtiofs"; - }; - - "/" = { - device = "/dev/vda"; - fsType = "ext4"; - options = [ - "defaults" - "x-systemd.makefs" - "nobarrier" - "noatime" - "nodiratime" - "data=writeback" - "discard" - ]; - }; - - "/vmstate" = { - device = "/dev/vdb"; - options = [ - "x-systemd.makefs" - "noatime" - "nodiratime" - "discard" - ]; - noCheck = true; - fsType = "ext4"; - }; - - ${config.clan.core.facts.secretUploadDirectory} = { - device = "secrets"; - fsType = "9p"; - neededForBoot = true; - options = [ - "trans=virtio" - "version=9p2000.L" - "cache=loose" - ]; - }; - } - // lib.listToAttrs ( - map ( - folder: - lib.nameValuePair folder { - device = "/vmstate${folder}"; - fsType = "none"; - options = [ "bind" ]; - } - ) stateFolders - ) - ); - }; + # Import the standalone VM base module + vmModule = import ./vm-base.nix; # We cannot simply merge the VM config into the current system config, because # it is not necessarily a VM. diff --git a/nixosModules/flake-module.nix b/nixosModules/flake-module.nix index 0662361db..3d82fec62 100644 --- a/nixosModules/flake-module.nix +++ b/nixosModules/flake-module.nix @@ -34,4 +34,7 @@ in flake.nixosModules.clanCore = clanCore; flake.darwinModules.clanCore = clanCore; + + # Standalone VM base module that can be imported for VM testing + flake.nixosModules.clan-vm-base = ./clanCore/vm-base.nix; } diff --git a/pkgs/clan-cli/clan_cli/tests/flake-module.nix b/pkgs/clan-cli/clan_cli/tests/flake-module.nix index a60bf8e37..c37b075ff 100644 --- a/pkgs/clan-cli/clan_cli/tests/flake-module.nix +++ b/pkgs/clan-cli/clan_cli/tests/flake-module.nix @@ -25,6 +25,8 @@ test-vm-persistence = { config, ... }: { + imports = [ self.nixosModules.clan-vm-base ]; + system.stateVersion = config.system.nixos.release; # Disable services that might cause issues in tests @@ -62,6 +64,8 @@ test-vm-deployment = { config, lib, ... }: { + imports = [ self.nixosModules.clan-vm-base ]; + system.stateVersion = config.system.nixos.release; # Disable services that might cause issues in tests