module: add vmWithDisko output to system

This commit is contained in:
lassulus 2024-07-21 16:45:14 +02:00
parent 5a9f2498fb
commit a574d68d37
4 changed files with 121 additions and 0 deletions

17
docs/interactive-vm.md Normal file
View file

@ -0,0 +1,17 @@
# Running Interactive VMs with disko
disko now exports it's own flavor of interactive VMs (similiar to config.system.build.vm).
Simply import the disko module and build the vm runner with:
```
nix build -L '.#nixosConfigurations.mymachine.config.system.build.vmWithDisko'
```
afterwards you can run the interactive VM with:
```
result/bin/disko-vm
```
extraConfig that is set in disko.tests.extraConfig is also applied to the interactive VMs.
imageSize of the VMs will be determined by the imageSize in the disk type in your disko config.
memorySize is set by disko.memSize

View file

@ -16,6 +16,8 @@ let
# a version of makeDiskImage which runs outside of the store
makeDiskImagesScript = args: (import ./make-disk-image.nix ({ inherit diskoLib; } // args)).impure;
makeVMRunner = args: (import ./interactive-vm.nix ({ inherit diskoLib; } // args)).pure;
testLib = import ./tests.nix { inherit lib makeTest eval-config; };
# like lib.types.oneOf but instead of a list takes an attrset
# uses the field "type" to find the correct type in the attrset

88
lib/interactive-vm.nix Normal file
View file

@ -0,0 +1,88 @@
{ nixosConfig
, diskoLib
, pkgs ? nixosConfig.pkgs
, name ? "${nixosConfig.config.networking.hostName}-disko-images"
, extraConfig ? { }
}:
let
lib = pkgs.lib;
vm_disko = (diskoLib.testLib.prepareDiskoConfig nixosConfig.config diskoLib.testLib.devices).disko;
cfg_ = (lib.evalModules {
modules = lib.singleton {
# _file = toString input;
imports = lib.singleton { disko.devices = vm_disko.devices; };
options = {
disko.devices = lib.mkOption {
type = diskoLib.toplevel;
};
disko.testMode = lib.mkOption {
type = lib.types.bool;
default = true;
};
};
};
}).config;
disks = lib.attrValues cfg_.disko.devices.disk;
diskoImages = diskoLib.makeDiskImages {
nixosConfig = nixosConfig;
copyNixStore = false;
extraConfig = {
disko.devices = cfg_.disko.devices;
};
testMode = true;
};
rootDisk = {
name = "root";
file = ''"$tmp"/${(builtins.head disks).name}.qcow2'';
driveExtraOpts.cache = "writeback";
driveExtraOpts.werror = "report";
deviceExtraOpts.bootindex = "1";
deviceExtraOpts.serial = "root";
};
otherDisks = map
(disk: {
name = disk.name;
file = ''"$tmp"/${disk.name}.qcow2'';
driveExtraOpts.werror = "report";
})
(builtins.tail disks);
vm = (nixosConfig.extendModules {
modules = [
({ modulesPath, ... }: {
imports = [
(modulesPath + "/virtualisation/qemu-vm.nix")
];
})
{
virtualisation.useEFIBoot = nixosConfig.config.disko.tests.efi;
virtualisation.memorySize = nixosConfig.config.disko.memSize;
virtualisation.useDefaultFilesystems = false;
virtualisation.diskImage = null;
virtualisation.qemu.drives = [ rootDisk ] ++ otherDisks;
boot.zfs.devNodes = "/dev/disk/by-uuid"; # needed because /dev/disk/by-id is empty in qemu-vms
boot.zfs.forceImportAll = true;
}
{
# generated from disko config
virtualisation.fileSystems = cfg_.disko.devices._config.fileSystems;
boot = cfg_.disko.devices._config.boot or { };
swapDevices = cfg_.disko.devices._config.swapDevices or [ ];
}
nixosConfig.config.disko.tests.extraConfig
];
}).config.system.build.vm;
in
{
pure = pkgs.writeDashBin "disko-vm" ''
set -efux
export tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT
${lib.concatMapStringsSep "\n" (disk: ''
${pkgs.qemu}/bin/qemu-img create -f qcow2 \
-b ${diskoImages}/${disk.name}.raw \
-F raw "$tmp"/${disk.name}.qcow2
'') disks}
set +f
${vm}/bin/run-*-vm
'';
}

View file

@ -69,6 +69,15 @@ in
type = lib.types.bool;
default = false;
};
testMode = lib.mkOption {
internal = true;
description = ''
this is true if the system is being run in test mode.
like a vm test or an interactive vm
'';
type = lib.types.bool;
default = false;
};
tests = {
efi = lib.mkOption {
description = ''
@ -121,6 +130,11 @@ in
extraSystemConfig = cfg.tests.extraConfig;
extraTestScript = cfg.tests.extraChecks;
};
vmWithDisko = diskoLib.makeVMRunner {
inherit pkgs;
nixosConfig = args;
};
};