diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 7bc42039f2a3..9d01b75516f7 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -942,7 +942,7 @@ in lomiri-system-settings = runTest ./lomiri-system-settings.nix; lorri = handleTest ./lorri/default.nix { }; luks = runTest ./luks.nix; - lvm2 = handleTest ./lvm2 { }; + lvm2 = import ./lvm2 { inherit pkgs runTest; }; lxc = runTestOn [ "x86_64-linux" "aarch64-linux" ] ./lxc; lxd-image-server = runTest ./lxd-image-server.nix; lxqt = runTest ./lxqt.nix; @@ -1849,7 +1849,7 @@ in zammad = runTest ./zammad.nix; zenohd = runTest ./zenohd.nix; zeronet-conservancy = runTest ./zeronet-conservancy.nix; - zfs = handleTest ./zfs.nix { }; + zfs = import ./zfs.nix { inherit system pkgs runTest; }; zigbee2mqtt = runTest ./zigbee2mqtt.nix; zipline = runTest ./zipline.nix; zoneminder = runTest ./zoneminder.nix; diff --git a/nixos/tests/initrd-luks-empty-passphrase.nix b/nixos/tests/initrd-luks-empty-passphrase.nix index 56a92a827ff4..2153e2dfab55 100644 --- a/nixos/tests/initrd-luks-empty-passphrase.nix +++ b/nixos/tests/initrd-luks-empty-passphrase.nix @@ -61,47 +61,63 @@ in }; }; - testScript = '' - # Encrypt key with empty key so boot should try keyfile and then fallback to empty passphrase + testScript = + { nodes, ... }: + let + toplevel = nodes.machine.system.build.toplevel; + boot-luks-missing-keyfile = + nodes.machine.specialisation.boot-luks-missing-keyfile.configuration.system.build.toplevel; + boot-luks-wrong-keyfile = + nodes.machine.specialisation.boot-luks-wrong-keyfile.configuration.system.build.toplevel; + in + # python + '' + # Encrypt key with empty key so boot should try keyfile and then fallback to empty passphrase - def grub_select_boot_luks_wrong_key_file(): - """ - Selects "boot-luks" from the GRUB menu - to trigger a login request. - """ - machine.send_monitor_command("sendkey down") - machine.send_monitor_command("sendkey down") - machine.send_monitor_command("sendkey ret") + def grub_select_boot_luks_wrong_key_file(): + """ + Selects "boot-luks" from the GRUB menu + to trigger a login request. + """ + machine.send_monitor_command("sendkey down") + machine.send_monitor_command("sendkey down") + machine.send_monitor_command("sendkey ret") - def grub_select_boot_luks_missing_key_file(): - """ - Selects "boot-luks" from the GRUB menu - to trigger a login request. - """ - machine.send_monitor_command("sendkey down") - machine.send_monitor_command("sendkey ret") + def grub_select_boot_luks_missing_key_file(): + """ + Selects "boot-luks" from the GRUB menu + to trigger a login request. + """ + machine.send_monitor_command("sendkey down") + machine.send_monitor_command("sendkey ret") - # Create encrypted volume - machine.wait_for_unit("multi-user.target") - machine.succeed("echo "" | cryptsetup luksFormat /dev/vdb --batch-mode") - machine.succeed("echo "" | cryptsetup luksOpen /dev/vdb cryptroot") - machine.succeed("mkfs.ext4 /dev/mapper/cryptroot") - machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks-wrong-keyfile.conf") - machine.succeed("sync") - machine.crash() + # Create encrypted volume + machine.wait_for_unit("multi-user.target") + machine.succeed("echo "" | cryptsetup luksFormat /dev/vdb --batch-mode") + machine.succeed("echo "" | cryptsetup luksOpen /dev/vdb cryptroot") + machine.succeed("mkfs.ext4 /dev/mapper/cryptroot") + machine.succeed("${boot-luks-wrong-keyfile}/bin/switch-to-configuration boot") + machine.succeed("sync") + machine.crash() - # Check if rootfs is on /dev/mapper/cryptroot - machine.wait_for_unit("multi-user.target") - assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount") + # Check if rootfs is on /dev/mapper/cryptroot + machine.wait_for_unit("multi-user.target") + assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount") - # Choose boot-luks-missing-keyfile specialisation - machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks-missing-keyfile.conf") - machine.succeed("sync") - machine.crash() + # Choose boot-luks-missing-keyfile specialisation + machine.succeed( + "mkdir -p /nix/var/nix/profiles", + "ln -sfn ${toplevel} /nix/var/nix/profiles/system-1-link", + "ln -sfn system-1-link /nix/var/nix/profiles/system", + ) - # Check if rootfs is on /dev/mapper/cryptroot - machine.wait_for_unit("multi-user.target") - assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount") - ''; + machine.succeed("${boot-luks-missing-keyfile}/bin/switch-to-configuration boot") + machine.succeed("sync") + machine.crash() + + # Check if rootfs is on /dev/mapper/cryptroot + machine.wait_for_unit("multi-user.target") + assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount") + ''; } diff --git a/nixos/tests/luks.nix b/nixos/tests/luks.nix index db2672eefdc0..08f465c006d1 100644 --- a/nixos/tests/luks.nix +++ b/nixos/tests/luks.nix @@ -1,6 +1,6 @@ # Tests LUKS specifically with scripted stage 1. Remove in 26.11. -{ lib, pkgs, ... }: +{ lib, ... }: { name = "luks"; @@ -47,41 +47,59 @@ enableOCR = true; - testScript = '' - # Create encrypted volume - machine.wait_for_unit("multi-user.target") - machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -") - machine.succeed("echo -n supersecret | cryptsetup luksOpen -q /dev/vdb cryptroot") - machine.succeed("mkfs.ext4 /dev/mapper/cryptroot") + testScript = + { nodes, ... }: + let + toplevel = nodes.machine.system.build.toplevel; + boot-luks = nodes.machine.specialisation.boot-luks.configuration.system.build.toplevel; + boot-luks-custom-keymap = + nodes.machine.specialisation.boot-luks-custom-keymap.configuration.system.build.toplevel; + in + # python + '' + # Create encrypted volume + machine.wait_for_unit("multi-user.target") + machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -") + machine.succeed("echo -n supersecret | cryptsetup luksOpen -q /dev/vdb cryptroot") + machine.succeed("mkfs.ext4 /dev/mapper/cryptroot") - machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdc -") - machine.succeed("echo -n supersecret | cryptsetup luksOpen -q /dev/vdc cryptroot2") - machine.succeed("mkfs.ext4 /dev/mapper/cryptroot2") + machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdc -") + machine.succeed("echo -n supersecret | cryptsetup luksOpen -q /dev/vdc cryptroot2") + machine.succeed("mkfs.ext4 /dev/mapper/cryptroot2") - # Boot from the encrypted disk - machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks.conf") - machine.succeed("sync") - machine.crash() + # Boot from the encrypted disk + machine.succeed("${boot-luks}/bin/switch-to-configuration boot") + machine.succeed("sync") + machine.crash() - # Boot and decrypt the disk - machine.start() - machine.wait_for_text("Passphrase for") - machine.send_chars("supersecret\n") - machine.wait_for_unit("multi-user.target") + # Boot and decrypt the disk + machine.start() + machine.wait_for_text("Passphrase for") + machine.send_chars("supersecret\n") + machine.wait_for_unit("multi-user.target") - assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount") + assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount") - # Boot from the encrypted disk with custom keymap - machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks-custom-keymap.conf") - machine.succeed("sync") - machine.crash() + # The new root is empty, so it has no /nix/var/nix/profiles. Without a + # system profile, systemd-boot-builder finds zero generations and + # bails. So we manually create the one profile link that we need. + machine.succeed( + "mkdir -p /nix/var/nix/profiles", + "ln -sfn ${toplevel} /nix/var/nix/profiles/system-1-link", + "ln -sfn system-1-link /nix/var/nix/profiles/system", + ) - # Boot and decrypt the disk - machine.start() - machine.wait_for_text("Passphrase for") - machine.send_chars("havfkhfrkfl\n") - machine.wait_for_unit("multi-user.target") + # Boot from the encrypted disk with custom keymap + machine.succeed("${boot-luks-custom-keymap}/bin/switch-to-configuration boot") + machine.succeed("sync") + machine.crash() - assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount") - ''; + # Boot and decrypt the disk + machine.start() + machine.wait_for_text("Passphrase for") + machine.send_chars("havfkhfrkfl\n") + machine.wait_for_unit("multi-user.target") + + assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount") + ''; } diff --git a/nixos/tests/lvm2/default.nix b/nixos/tests/lvm2/default.nix index dfdd3ae6a9a2..55e12bb39aef 100644 --- a/nixos/tests/lvm2/default.nix +++ b/nixos/tests/lvm2/default.nix @@ -1,8 +1,6 @@ { - system ? builtins.currentSystem, - config ? { }, - pkgs ? import ../../.. { inherit system config; }, - lib ? pkgs.lib, + pkgs, + runTest, kernelVersionsToTest ? [ "5.10" "5.15" @@ -15,38 +13,36 @@ # For quickly running a test, the nixosTests.lvm2.lvm-thinpool-linux-latest attribute is recommended let - tests = - let - callTest = p: lib.flip (import p) { inherit system pkgs; }; - in - { - thinpool = { - test = callTest ./thinpool.nix; - kernelFilter = lib.id; - }; - # we would like to test all versions, but the kernel module currently does not compile against the other versions - vdo = { - test = callTest ./vdo.nix; - kernelFilter = lib.filter (v: v == "latest"); - }; + inherit (pkgs) lib; - # systemd in stage 1 - raid-sd-stage-1 = { - test = callTest ./systemd-stage-1.nix; - kernelFilter = lib.filter (v: v != "5.15"); - flavour = "raid"; - }; - thinpool-sd-stage-1 = { - test = callTest ./systemd-stage-1.nix; - kernelFilter = lib.id; - flavour = "thinpool"; - }; - vdo-sd-stage-1 = { - test = callTest ./systemd-stage-1.nix; - kernelFilter = lib.filter (v: v == "latest"); - flavour = "vdo"; - }; + tests = { + thinpool = { + test = ./thinpool.nix; + kernelFilter = lib.id; }; + # we would like to test all versions, but the kernel module currently does not compile against the other versions + vdo = { + test = ./vdo.nix; + kernelFilter = lib.filter (v: v == "latest"); + }; + + # systemd in stage 1 + raid-sd-stage-1 = { + test = ./systemd-stage-1.nix; + kernelFilter = lib.filter (v: v != "5.15"); + flavour = "raid"; + }; + thinpool-sd-stage-1 = { + test = ./systemd-stage-1.nix; + kernelFilter = lib.id; + flavour = "thinpool"; + }; + vdo-sd-stage-1 = { + test = ./systemd-stage-1.nix; + kernelFilter = lib.filter (v: v == "latest"); + flavour = "vdo"; + }; + }; in lib.listToAttrs ( lib.filter (x: x.value != { }) ( @@ -61,18 +57,17 @@ lib.listToAttrs ( lib.flip lib.mapAttrsToList tests ( name: t: lib.nameValuePair "lvm-${name}-linux-${v'}" ( - lib.optionalAttrs (builtins.elem version (t.kernelFilter kernelVersionsToTest)) ( - t.test ( - { - kernelPackages = pkgs."linuxPackages_${v'}"; - inherit mkXfsFlags; - } - // removeAttrs t [ - "test" - "kernelFilter" - ] - ) - ) + lib.optionalAttrs (builtins.elem version (t.kernelFilter kernelVersionsToTest)) (runTest { + imports = [ t.test ]; + _module.args = { + kernelPackages = pkgs."linuxPackages_${v'}"; + inherit mkXfsFlags; + } + // removeAttrs t [ + "test" + "kernelFilter" + ]; + }) ) ) ) diff --git a/nixos/tests/lvm2/systemd-stage-1.nix b/nixos/tests/lvm2/systemd-stage-1.nix index c6c68ae64c1c..c6aed70675e2 100644 --- a/nixos/tests/lvm2/systemd-stage-1.nix +++ b/nixos/tests/lvm2/systemd-stage-1.nix @@ -1,7 +1,9 @@ { + lib, kernelPackages ? null, flavour, mkXfsFlags ? "", + ... }: let preparationCode = @@ -66,57 +68,61 @@ let .${flavour}; in -import ../make-test-python.nix ( - { pkgs, lib, ... }: - { - name = "lvm2-${flavour}-systemd-stage-1"; - meta.maintainers = with lib.maintainers; [ - das_j - helsinki-Jo - ]; +{ + name = "lvm2-${flavour}-systemd-stage-1"; + meta.maintainers = with lib.maintainers; [ + das_j + helsinki-Jo + ]; - nodes.machine = - { pkgs, lib, ... }: - { - imports = [ extraConfig ]; - # Use systemd-boot - virtualisation = { - emptyDiskImages = [ - 8192 - 8192 - ]; - useBootLoader = true; - useEFIBoot = true; - # To boot off the LVM disk, we need to have a init script which comes from the Nix store. - mountHostNixStore = true; - }; - boot.loader.systemd-boot.enable = true; - boot.loader.efi.canTouchEfiVariables = true; - - environment.systemPackages = with pkgs; [ xfsprogs ]; - boot = { - initrd.systemd = { - enable = true; - emergencyAccess = true; - }; - initrd.services.lvm.enable = true; - kernelPackages = lib.mkIf (kernelPackages != null) kernelPackages; - }; - - specialisation.boot-lvm.configuration.virtualisation = { - useDefaultFilesystems = false; - fileSystems = { - "/" = { - device = "/dev/test_vg/test_lv"; - fsType = "xfs"; - }; - }; - - rootDevice = "/dev/test_vg/test_lv"; + nodes.machine = + { pkgs, lib, ... }: + { + imports = [ extraConfig ]; + # Use systemd-boot + virtualisation = { + emptyDiskImages = [ + 8192 + 8192 + ]; + useBootLoader = true; + useEFIBoot = true; + # To boot off the LVM disk, we need to have a init script which comes from the Nix store. + mountHostNixStore = true; + }; + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + environment.systemPackages = with pkgs; [ xfsprogs ]; + boot = { + initrd.systemd = { + enable = true; + emergencyAccess = true; }; + initrd.services.lvm.enable = true; + kernelPackages = lib.mkIf (kernelPackages != null) kernelPackages; }; - testScript = '' + specialisation.boot-lvm.configuration.virtualisation = { + useDefaultFilesystems = false; + fileSystems = { + "/" = { + device = "/dev/test_vg/test_lv"; + fsType = "xfs"; + }; + }; + + rootDevice = "/dev/test_vg/test_lv"; + }; + }; + + testScript = + { nodes, ... }: + let + boot-lvm = nodes.machine.specialisation.boot-lvm.configuration.system.build.toplevel; + in + # python + '' machine.wait_for_unit("multi-user.target") # Create a VG for the root ${preparationCode} @@ -124,7 +130,7 @@ import ../make-test-python.nix ( machine.succeed("mkdir -p /mnt && mount /dev/test_vg/test_lv /mnt && echo hello > /mnt/test && umount /mnt") # Boot from LVM - machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-lvm.conf") + machine.succeed("${boot-lvm}/bin/switch-to-configuration boot") machine.succeed("sync") machine.crash() machine.wait_for_unit("multi-user.target") @@ -135,5 +141,4 @@ import ../make-test-python.nix ( assert "hello" in machine.succeed("cat /test") ${extraCheck} ''; - } -) +} diff --git a/nixos/tests/lvm2/thinpool.nix b/nixos/tests/lvm2/thinpool.nix index 8c7471d46f28..02d081f6b38c 100644 --- a/nixos/tests/lvm2/thinpool.nix +++ b/nixos/tests/lvm2/thinpool.nix @@ -1,49 +1,48 @@ { + lib, kernelPackages ? null, mkXfsFlags ? "", + ... }: -import ../make-test-python.nix ( - { pkgs, lib, ... }: - { - name = "lvm2-thinpool"; - meta.maintainers = with lib.maintainers; [ - das_j - helsinki-Jo - ]; +{ + name = "lvm2-thinpool"; + meta.maintainers = with lib.maintainers; [ + das_j + helsinki-Jo + ]; - nodes.machine = - { pkgs, lib, ... }: - { - virtualisation.emptyDiskImages = [ 4096 ]; - services.lvm = { - boot.thin.enable = true; - dmeventd.enable = true; - }; - environment.systemPackages = with pkgs; [ xfsprogs ]; - environment.etc."lvm/lvm.conf".text = '' - activation/thin_pool_autoextend_percent = 10 - activation/thin_pool_autoextend_threshold = 80 - ''; - boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; }; + nodes.machine = + { pkgs, lib, ... }: + { + virtualisation.emptyDiskImages = [ 4096 ]; + services.lvm = { + boot.thin.enable = true; + dmeventd.enable = true; }; - - testScript = - let - mkXfsFlags = - lib.optionalString (lib.versionOlder kernelPackages.kernel.version "5.10") " -m bigtime=0 -m inobtcount=0 " - + lib.optionalString (lib.versionOlder kernelPackages.kernel.version "5.19") " -i nrext64=0 "; - in - '' - machine.succeed("vgcreate test_vg /dev/vdb") - machine.succeed("lvcreate -L 512M -T test_vg/test_thin_pool") - machine.succeed("lvcreate -n test_lv -V 16G --thinpool test_thin_pool test_vg") - machine.succeed("mkfs.xfs ${mkXfsFlags} /dev/test_vg/test_lv") - machine.succeed("mkdir /mnt; mount /dev/test_vg/test_lv /mnt") - assert "/dev/mapper/test_vg-test_lv" == machine.succeed("findmnt -no SOURCE /mnt").strip() - machine.succeed("dd if=/dev/zero of=/mnt/empty.file bs=1M count=1024") - machine.succeed("journalctl -u dm-event.service | grep \"successfully resized\"") - machine.succeed("umount /mnt") - machine.succeed("vgchange -a n") + environment.systemPackages = with pkgs; [ xfsprogs ]; + environment.etc."lvm/lvm.conf".text = '' + activation/thin_pool_autoextend_percent = 10 + activation/thin_pool_autoextend_threshold = 80 ''; - } -) + boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; }; + }; + + testScript = + let + mkXfsFlags = + lib.optionalString (lib.versionOlder kernelPackages.kernel.version "5.10") " -m bigtime=0 -m inobtcount=0 " + + lib.optionalString (lib.versionOlder kernelPackages.kernel.version "5.19") " -i nrext64=0 "; + in + '' + machine.succeed("vgcreate test_vg /dev/vdb") + machine.succeed("lvcreate -L 512M -T test_vg/test_thin_pool") + machine.succeed("lvcreate -n test_lv -V 16G --thinpool test_thin_pool test_vg") + machine.succeed("mkfs.xfs ${mkXfsFlags} /dev/test_vg/test_lv") + machine.succeed("mkdir /mnt; mount /dev/test_vg/test_lv /mnt") + assert "/dev/mapper/test_vg-test_lv" == machine.succeed("findmnt -no SOURCE /mnt").strip() + machine.succeed("dd if=/dev/zero of=/mnt/empty.file bs=1M count=1024") + machine.succeed("journalctl -u dm-event.service | grep \"successfully resized\"") + machine.succeed("umount /mnt") + machine.succeed("vgchange -a n") + ''; +} diff --git a/nixos/tests/lvm2/vdo.nix b/nixos/tests/lvm2/vdo.nix index ee65aa7d828f..94894f64377b 100644 --- a/nixos/tests/lvm2/vdo.nix +++ b/nixos/tests/lvm2/vdo.nix @@ -1,35 +1,34 @@ { + lib, kernelPackages ? null, mkXfsFlags ? "", + ... }: -import ../make-test-python.nix ( - { pkgs, lib, ... }: - { - name = "lvm2-vdo"; - meta.maintainers = [ ]; +{ + name = "lvm2-vdo"; + meta.maintainers = [ ]; - nodes.machine = - { pkgs, lib, ... }: - { - # Minimum required size for VDO volume: 5063921664 bytes - virtualisation.emptyDiskImages = [ 8192 ]; - services.lvm = { - boot.vdo.enable = true; - dmeventd.enable = true; - }; - environment.systemPackages = with pkgs; [ xfsprogs ]; - boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; }; + nodes.machine = + { pkgs, lib, ... }: + { + # Minimum required size for VDO volume: 5063921664 bytes + virtualisation.emptyDiskImages = [ 8192 ]; + services.lvm = { + boot.vdo.enable = true; + dmeventd.enable = true; }; + environment.systemPackages = with pkgs; [ xfsprogs ]; + boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; }; + }; - testScript = '' - machine.succeed("vgcreate test_vg /dev/vdb") - machine.succeed("lvcreate --type vdo -n vdo_lv -L 6G -V 12G test_vg/vdo_pool_lv") - machine.succeed("mkfs.xfs ${mkXfsFlags} -K /dev/test_vg/vdo_lv") - machine.succeed("mkdir /mnt; mount /dev/test_vg/vdo_lv /mnt") - assert "/dev/mapper/test_vg-vdo_lv" == machine.succeed("findmnt -no SOURCE /mnt").strip() - machine.succeed("umount /mnt") - machine.succeed("vdostats") - machine.succeed("vgchange -a n") - ''; - } -) + testScript = '' + machine.succeed("vgcreate test_vg /dev/vdb") + machine.succeed("lvcreate --type vdo -n vdo_lv -L 6G -V 12G test_vg/vdo_pool_lv") + machine.succeed("mkfs.xfs ${mkXfsFlags} -K /dev/test_vg/vdo_lv") + machine.succeed("mkdir /mnt; mount /dev/test_vg/vdo_lv /mnt") + assert "/dev/mapper/test_vg-vdo_lv" == machine.succeed("findmnt -no SOURCE /mnt").strip() + machine.succeed("umount /mnt") + machine.succeed("vdostats") + machine.succeed("vgchange -a n") + ''; +} diff --git a/nixos/tests/systemd-initrd-btrfs-raid.nix b/nixos/tests/systemd-initrd-btrfs-raid.nix index 1aa21fc326cd..05caa522b0d7 100644 --- a/nixos/tests/systemd-initrd-btrfs-raid.nix +++ b/nixos/tests/systemd-initrd-btrfs-raid.nix @@ -1,4 +1,4 @@ -{ lib, pkgs, ... }: +{ lib, ... }: { name = "systemd-initrd-btrfs-raid"; @@ -33,21 +33,27 @@ }; }; - testScript = '' - # Create RAID - machine.succeed("mkfs.btrfs -d raid0 /dev/vdb /dev/vdc") - machine.succeed("mkdir -p /mnt && mount /dev/vdb /mnt && echo hello > /mnt/test && umount /mnt") + testScript = + { nodes, ... }: + let + boot-btrfs-raid = nodes.machine.specialisation.boot-btrfs-raid.configuration.system.build.toplevel; + in + # python + '' + # Create RAID + machine.succeed("mkfs.btrfs -d raid0 /dev/vdb /dev/vdc") + machine.succeed("mkdir -p /mnt && mount /dev/vdb /mnt && echo hello > /mnt/test && umount /mnt") - # Boot from the RAID - machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-btrfs-raid.conf") - machine.succeed("sync") - machine.crash() - machine.wait_for_unit("multi-user.target") + # Boot from the RAID + machine.succeed("${boot-btrfs-raid}/bin/switch-to-configuration boot") + machine.succeed("sync") + machine.crash() + machine.wait_for_unit("multi-user.target") - # Ensure we have successfully booted from the RAID - assert "(initrd)" in machine.succeed("systemd-analyze") # booted with systemd in stage 1 - assert "/dev/vdb on / type btrfs" in machine.succeed("mount") - assert "hello" in machine.succeed("cat /test") - assert "Total devices 2" in machine.succeed("btrfs filesystem show") - ''; + # Ensure we have successfully booted from the RAID + assert "(initrd)" in machine.succeed("systemd-analyze") # booted with systemd in stage 1 + assert "/dev/vdb on / type btrfs" in machine.succeed("mount") + assert "hello" in machine.succeed("cat /test") + assert "Total devices 2" in machine.succeed("btrfs filesystem show") + ''; } diff --git a/nixos/tests/systemd-initrd-luks-fido2.nix b/nixos/tests/systemd-initrd-luks-fido2.nix index a38c97e8b0dd..783b9d7426e7 100644 --- a/nixos/tests/systemd-initrd-luks-fido2.nix +++ b/nixos/tests/systemd-initrd-luks-fido2.nix @@ -1,6 +1,5 @@ { lib, - pkgs, hostPkgs, ... }: @@ -43,19 +42,25 @@ }; }; - testScript = '' - # Create encrypted volume - machine.wait_for_unit("multi-user.target") - machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -") - machine.succeed("PASSWORD=supersecret SYSTEMD_LOG_LEVEL=debug systemd-cryptenroll --fido2-device=auto /dev/vdb |& systemd-cat") + testScript = + { nodes, ... }: + let + boot-luks = nodes.machine.specialisation.boot-luks.configuration.system.build.toplevel; + in + # python + '' + # Create encrypted volume + machine.wait_for_unit("multi-user.target") + machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -") + machine.succeed("PASSWORD=supersecret SYSTEMD_LOG_LEVEL=debug systemd-cryptenroll --fido2-device=auto /dev/vdb |& systemd-cat") - # Boot from the encrypted disk - machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks.conf") - machine.succeed("sync") - machine.crash() + # Boot from the encrypted disk + machine.succeed("${boot-luks}/bin/switch-to-configuration boot") + machine.succeed("sync") + machine.crash() - # Boot and decrypt the disk - machine.wait_for_unit("multi-user.target") - assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount") - ''; + # Boot and decrypt the disk + machine.wait_for_unit("multi-user.target") + assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount") + ''; } diff --git a/nixos/tests/systemd-initrd-luks-keyfile.nix b/nixos/tests/systemd-initrd-luks-keyfile.nix index 8b7f28947f72..b12e504a107a 100644 --- a/nixos/tests/systemd-initrd-luks-keyfile.nix +++ b/nixos/tests/systemd-initrd-luks-keyfile.nix @@ -42,20 +42,26 @@ in }; }; - testScript = '' - # Create encrypted volume - machine.wait_for_unit("multi-user.target") - machine.succeed("cryptsetup luksFormat -q --iter-time=1 -d ${keyfile} /dev/vdb") - machine.succeed("cryptsetup luksOpen --key-file ${keyfile} /dev/vdb cryptroot") - machine.succeed("mkfs.ext4 /dev/mapper/cryptroot") + testScript = + { nodes, ... }: + let + boot-luks = nodes.machine.specialisation.boot-luks.configuration.system.build.toplevel; + in + # python + '' + # Create encrypted volume + machine.wait_for_unit("multi-user.target") + machine.succeed("cryptsetup luksFormat -q --iter-time=1 -d ${keyfile} /dev/vdb") + machine.succeed("cryptsetup luksOpen --key-file ${keyfile} /dev/vdb cryptroot") + machine.succeed("mkfs.ext4 /dev/mapper/cryptroot") - # Boot from the encrypted disk - machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks.conf") - machine.succeed("sync") - machine.crash() + # Boot from the encrypted disk + machine.succeed("${boot-luks}/bin/switch-to-configuration boot") + machine.succeed("sync") + machine.crash() - # Boot and decrypt the disk - machine.wait_for_unit("multi-user.target") - assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount") - ''; + # Boot and decrypt the disk + machine.wait_for_unit("multi-user.target") + assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount") + ''; } diff --git a/nixos/tests/systemd-initrd-luks-password.nix b/nixos/tests/systemd-initrd-luks-password.nix index a77fe16ea453..8eeb9b178fa1 100644 --- a/nixos/tests/systemd-initrd-luks-password.nix +++ b/nixos/tests/systemd-initrd-luks-password.nix @@ -1,4 +1,4 @@ -{ lib, pkgs, ... }: +{ lib, ... }: { name = "systemd-initrd-luks-password"; @@ -39,30 +39,36 @@ }; }; - testScript = '' - # Create encrypted volume - machine.wait_for_unit("multi-user.target") + testScript = + { nodes, ... }: + let + boot-luks = nodes.machine.specialisation.boot-luks.configuration.system.build.toplevel; + in + # python + '' + # Create encrypted volume + machine.wait_for_unit("multi-user.target") - machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -") - machine.succeed("echo -n supersecret | cryptsetup luksOpen -q /dev/vdb cryptroot") - machine.succeed("mkfs.ext4 /dev/mapper/cryptroot") + machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -") + machine.succeed("echo -n supersecret | cryptsetup luksOpen -q /dev/vdb cryptroot") + machine.succeed("mkfs.ext4 /dev/mapper/cryptroot") - machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdc -") - machine.succeed("echo -n supersecret | cryptsetup luksOpen -q /dev/vdc cryptroot2") - machine.succeed("mkfs.ext4 /dev/mapper/cryptroot2") + machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdc -") + machine.succeed("echo -n supersecret | cryptsetup luksOpen -q /dev/vdc cryptroot2") + machine.succeed("mkfs.ext4 /dev/mapper/cryptroot2") - # Boot from the encrypted disk - machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks.conf") - machine.succeed("sync") - machine.crash() + # Boot from the encrypted disk + machine.succeed("${boot-luks}/bin/switch-to-configuration boot") + machine.succeed("sync") + machine.crash() - # Boot and decrypt the disk - machine.start() - machine.wait_for_console_text("Please enter passphrase for disk cryptroot") - machine.send_console("supersecret\n") - machine.wait_for_unit("multi-user.target") + # Boot and decrypt the disk + machine.start() + machine.wait_for_console_text("Please enter passphrase for disk cryptroot") + machine.send_console("supersecret\n") + machine.wait_for_unit("multi-user.target") - assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount"), "/dev/mapper/cryptroot do not appear in mountpoints list" - assert "/dev/mapper/cryptroot2 on /cryptroot2 type ext4" in machine.succeed("mount") - ''; + assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount"), "/dev/mapper/cryptroot do not appear in mountpoints list" + assert "/dev/mapper/cryptroot2 on /cryptroot2 type ext4" in machine.succeed("mount") + ''; } diff --git a/nixos/tests/systemd-initrd-luks-tpm2.nix b/nixos/tests/systemd-initrd-luks-tpm2.nix index 931959f05464..8628fc2b8a01 100644 --- a/nixos/tests/systemd-initrd-luks-tpm2.nix +++ b/nixos/tests/systemd-initrd-luks-tpm2.nix @@ -35,21 +35,27 @@ }; }; - testScript = '' - # Create encrypted volume - machine.wait_for_unit("multi-user.target") - machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -") - machine.succeed("echo -n supersecret | cryptsetup luksOpen -q /dev/vdb cryptroot") - machine.succeed("mkfs.ext4 /dev/mapper/cryptroot") - machine.succeed("PASSWORD=supersecret SYSTEMD_LOG_LEVEL=debug systemd-cryptenroll --tpm2-pcrs= --tpm2-device=auto /dev/vdb |& systemd-cat") + testScript = + { nodes, ... }: + let + boot-luks = nodes.machine.specialisation.boot-luks.configuration.system.build.toplevel; + in + # python + '' + # Create encrypted volume + machine.wait_for_unit("multi-user.target") + machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -") + machine.succeed("echo -n supersecret | cryptsetup luksOpen -q /dev/vdb cryptroot") + machine.succeed("mkfs.ext4 /dev/mapper/cryptroot") + machine.succeed("PASSWORD=supersecret SYSTEMD_LOG_LEVEL=debug systemd-cryptenroll --tpm2-pcrs= --tpm2-device=auto /dev/vdb |& systemd-cat") - # Boot from the encrypted disk - machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks.conf") - machine.succeed("sync") - machine.crash() + # Boot from the encrypted disk + machine.succeed("${boot-luks}/bin/switch-to-configuration boot") + machine.succeed("sync") + machine.crash() - # Boot and decrypt the disk - machine.wait_for_unit("multi-user.target") - assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount") - ''; + # Boot and decrypt the disk + machine.wait_for_unit("multi-user.target") + assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount") + ''; } diff --git a/nixos/tests/systemd-initrd-luks-unl0kr.nix b/nixos/tests/systemd-initrd-luks-unl0kr.nix index 6844357a729f..b48bd2d1588f 100644 --- a/nixos/tests/systemd-initrd-luks-unl0kr.nix +++ b/nixos/tests/systemd-initrd-luks-unl0kr.nix @@ -82,33 +82,39 @@ in }; }; - testScript = '' - machine.wait_for_unit("multi-user.target") + testScript = + { nodes, ... }: + let + boot-luks = nodes.machine.specialisation.boot-luks.configuration.system.build.toplevel; + in + # python + '' + machine.wait_for_unit("multi-user.target") - machine.succeed("echo -n ${passphrase} | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -") - machine.succeed("echo -n ${passphrase} | cryptsetup luksOpen -q /dev/vdb cryptroot") - machine.succeed("mkfs.ext4 /dev/mapper/cryptroot") + machine.succeed("echo -n ${passphrase} | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -") + machine.succeed("echo -n ${passphrase} | cryptsetup luksOpen -q /dev/vdb cryptroot") + machine.succeed("mkfs.ext4 /dev/mapper/cryptroot") - machine.succeed("echo -n ${passphrase} | cryptsetup luksFormat -q --iter-time=1 /dev/vdc -") - machine.succeed("echo -n ${passphrase} | cryptsetup luksOpen -q /dev/vdc cryptroot2") - machine.succeed("mkfs.ext4 /dev/mapper/cryptroot2") + machine.succeed("echo -n ${passphrase} | cryptsetup luksFormat -q --iter-time=1 /dev/vdc -") + machine.succeed("echo -n ${passphrase} | cryptsetup luksOpen -q /dev/vdc cryptroot2") + machine.succeed("mkfs.ext4 /dev/mapper/cryptroot2") - # Boot from the encrypted disk - machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks.conf") - machine.succeed("sync") - machine.crash() + # Boot from the encrypted disk + machine.succeed("${boot-luks}/bin/switch-to-configuration boot") + machine.succeed("sync") + machine.crash() - # Boot and decrypt the disk. This part of the test is SLOW. - machine.start() - machine.wait_for_unit("unl0kr-agent.service") - machine.screenshot("prompt") - machine.send_chars("${passphrase}") - machine.screenshot("pw") - machine.send_chars("\n") - machine.switch_root() - machine.wait_for_unit("multi-user.target") + # Boot and decrypt the disk. This part of the test is SLOW. + machine.start() + machine.wait_for_unit("unl0kr-agent.service") + machine.screenshot("prompt") + machine.send_chars("${passphrase}") + machine.screenshot("pw") + machine.send_chars("\n") + machine.switch_root() + machine.wait_for_unit("multi-user.target") - assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount"), "/dev/mapper/cryptroot do not appear in mountpoints list" - assert "/dev/mapper/cryptroot2 on /cryptroot2 type ext4" in machine.succeed("mount") - ''; + assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount"), "/dev/mapper/cryptroot do not appear in mountpoints list" + assert "/dev/mapper/cryptroot2 on /cryptroot2 type ext4" in machine.succeed("mount") + ''; } diff --git a/nixos/tests/systemd-initrd-swraid.nix b/nixos/tests/systemd-initrd-swraid.nix index 997235ecfcd1..01fc9141997e 100644 --- a/nixos/tests/systemd-initrd-swraid.nix +++ b/nixos/tests/systemd-initrd-swraid.nix @@ -1,4 +1,4 @@ -{ lib, pkgs, ... }: +{ lib, ... }: { name = "systemd-initrd-swraid"; @@ -41,30 +41,36 @@ specialisation.build-old-initrd.configuration.boot.initrd.systemd.enable = lib.mkForce false; }; - testScript = '' - # Create RAID - machine.succeed("mdadm --create --force /dev/md0 -n 2 --level=raid1 /dev/vdb /dev/vdc --metadata=0.90 --bitmap=internal") - machine.succeed("mkfs.ext4 -L testraid /dev/md0") - machine.succeed("mkdir -p /mnt && mount /dev/md0 /mnt && echo hello > /mnt/test && umount /mnt") + testScript = + { nodes, ... }: + let + boot-swraid = nodes.machine.specialisation.boot-swraid.configuration.system.build.toplevel; + in + # python + '' + # Create RAID + machine.succeed("mdadm --create --force /dev/md0 -n 2 --level=raid1 /dev/vdb /dev/vdc --metadata=0.90 --bitmap=internal") + machine.succeed("mkfs.ext4 -L testraid /dev/md0") + machine.succeed("mkdir -p /mnt && mount /dev/md0 /mnt && echo hello > /mnt/test && umount /mnt") - # Boot from the RAID - machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-swraid.conf") - machine.succeed("sync") - machine.crash() - machine.wait_for_unit("multi-user.target") + # Boot from the RAID + machine.succeed("${boot-swraid}/bin/switch-to-configuration boot") + machine.succeed("sync") + machine.crash() + machine.wait_for_unit("multi-user.target") - # Ensure we have successfully booted from the RAID - assert "(initrd)" in machine.succeed("systemd-analyze") # booted with systemd in stage 1 - assert "/dev/md0 on / type ext4" in machine.succeed("mount") - assert "hello" in machine.succeed("cat /test") - assert "md0" in machine.succeed("cat /proc/mdstat") + # Ensure we have successfully booted from the RAID + assert "(initrd)" in machine.succeed("systemd-analyze") # booted with systemd in stage 1 + assert "/dev/md0 on / type ext4" in machine.succeed("mount") + assert "hello" in machine.succeed("cat /test") + assert "md0" in machine.succeed("cat /proc/mdstat") - # Verify the RAID array was properly auto-detected and assembled - detail = machine.succeed("mdadm --detail /dev/md0") - assert "raid1" in detail, f"Expected raid1 in mdadm detail output: {detail}" - assert "/dev/vdb" in detail, f"Expected /dev/vdb in array: {detail}" - assert "/dev/vdc" in detail, f"Expected /dev/vdc in array: {detail}" + # Verify the RAID array was properly auto-detected and assembled + detail = machine.succeed("mdadm --detail /dev/md0") + assert "raid1" in detail, f"Expected raid1 in mdadm detail output: {detail}" + assert "/dev/vdb" in detail, f"Expected /dev/vdb in array: {detail}" + assert "/dev/vdc" in detail, f"Expected /dev/vdc in array: {detail}" - machine.wait_for_unit("mdmonitor.service") - ''; + machine.wait_for_unit("mdmonitor.service") + ''; } diff --git a/nixos/tests/zfs.nix b/nixos/tests/zfs.nix index 418d7aeeda9b..fc5eb975226c 100644 --- a/nixos/tests/zfs.nix +++ b/nixos/tests/zfs.nix @@ -1,12 +1,11 @@ { - system ? builtins.currentSystem, - config ? { }, - pkgs ? import ../.. { inherit system config; }, + system, + pkgs, + runTest, }: -with import ../lib/testing-python.nix { inherit system pkgs; }; - let + inherit (pkgs) lib; makeZfsTest = { @@ -15,11 +14,9 @@ let zfsPackage, extraTest ? "", }: - makeTest { + runTest { name = zfsPackage.kernelModuleAttribute; - meta = with pkgs.lib.maintainers; { - maintainers = [ elvishjerricco ]; - }; + meta.maintainers = with lib.maintainers; [ elvishjerricco ]; nodes.machine = { @@ -124,82 +121,90 @@ let }; }; - testScript = '' - machine.wait_for_unit("multi-user.target") - machine.succeed( - "zpool status", - "parted --script /dev/vdb mklabel msdos", - "parted --script /dev/vdb -- mkpart primary 1024M -1s", - "parted --script /dev/vdc mklabel msdos", - "parted --script /dev/vdc -- mkpart primary 1024M -1s", - ) + testScript = + { nodes, ... }: + let + samba = nodes.machine.specialisation.samba.configuration.system.build.toplevel; + encryption = nodes.machine.specialisation.encryption.configuration.system.build.toplevel; + forcepool = nodes.machine.specialisation.forcepool.configuration.system.build.toplevel; + in + # python + '' + machine.wait_for_unit("multi-user.target") + machine.succeed( + "zpool status", + "parted --script /dev/vdb mklabel msdos", + "parted --script /dev/vdb -- mkpart primary 1024M -1s", + "parted --script /dev/vdc mklabel msdos", + "parted --script /dev/vdc -- mkpart primary 1024M -1s", + ) - with subtest("sharesmb works"): - machine.succeed( - "zpool create rpool /dev/vdb1", - "zfs create -o mountpoint=legacy rpool/root", - # shared datasets cannot have legacy mountpoint - "zfs create rpool/shared_smb", - "bootctl set-default nixos-generation-1-specialisation-samba.conf", - "sync", - ) - machine.crash() - machine.wait_for_unit("multi-user.target") - machine.succeed("zfs set sharesmb=on rpool/shared_smb") - machine.succeed( - "smbclient -gNL localhost | grep rpool_shared_smb", - "umount /tmp/mnt", - "zpool destroy rpool", - ) + with subtest("sharesmb works"): + machine.succeed( + "zpool create rpool /dev/vdb1", + "zfs create -o mountpoint=legacy rpool/root", + # shared datasets cannot have legacy mountpoint + "zfs create rpool/shared_smb", + "${samba}/bin/switch-to-configuration boot", + "sync", + ) + machine.crash() + machine.wait_for_unit("multi-user.target") + machine.succeed("zfs set sharesmb=on rpool/shared_smb") + machine.succeed( + "smbclient -gNL localhost | grep rpool_shared_smb", + "umount /tmp/mnt", + "zpool destroy rpool", + ) - with subtest("encryption works"): - machine.succeed( - 'echo password | zpool create -O mountpoint=legacy ' - + "-O encryption=aes-256-gcm -O keyformat=passphrase automatic /dev/vdb1", - "zpool create -O mountpoint=legacy manual /dev/vdc1", - "echo otherpass | zfs create " - + "-o encryption=aes-256-gcm -o keyformat=passphrase manual/encrypted", - "zfs create -o encryption=aes-256-gcm -o keyformat=passphrase " - + "-o keylocation=http://localhost/zfskey manual/httpkey", - "bootctl set-default nixos-generation-1-specialisation-encryption.conf", - "sync", - "zpool export automatic", - "zpool export manual", - ) - machine.crash() - machine.start() - machine.wait_for_console_text("Starting password query on") - machine.send_console("password\n") - machine.wait_for_unit("multi-user.target") - machine.succeed( - "zfs get -Ho value keystatus manual/encrypted | grep -Fx unavailable", - "echo otherpass | zfs load-key manual/encrypted", - "systemctl start manual-encrypted.mount", - "zfs load-key manual/httpkey", - "systemctl start manual-httpkey.mount", - "umount /automatic /manual/encrypted /manual/httpkey /manual", - "zpool destroy automatic", - "zpool destroy manual", - ) + with subtest("encryption works"): + machine.succeed( + 'echo password | zpool create -O mountpoint=legacy ' + + "-O encryption=aes-256-gcm -O keyformat=passphrase automatic /dev/vdb1", + "zpool create -O mountpoint=legacy manual /dev/vdc1", + "echo otherpass | zfs create " + + "-o encryption=aes-256-gcm -o keyformat=passphrase manual/encrypted", + "zfs create -o encryption=aes-256-gcm -o keyformat=passphrase " + + "-o keylocation=http://localhost/zfskey manual/httpkey", + "${encryption}/bin/switch-to-configuration boot", + "sync", + "zpool export automatic", + "zpool export manual", + ) + machine.crash() + machine.start() + machine.wait_for_console_text("Starting password query on") + machine.send_console("password\n") + machine.wait_for_unit("multi-user.target") + machine.succeed( + "zfs get -Ho value keystatus manual/encrypted | grep -Fx unavailable", + "echo otherpass | zfs load-key manual/encrypted", + "systemctl start manual-encrypted.mount", + "zfs load-key manual/httpkey", + "systemctl start manual-httpkey.mount", + "umount /automatic /manual/encrypted /manual/httpkey /manual", + "zpool destroy automatic", + "zpool destroy manual", + ) - with subtest("boot.zfs.forceImportAll works"): - machine.succeed( - "rm /etc/hostid", - "zgenhostid deadcafe", - "zpool create forcepool /dev/vdb1 -O mountpoint=legacy", - "bootctl set-default nixos-generation-1-specialisation-forcepool.conf", - "rm /etc/hostid", - "sync", - ) - machine.crash() - machine.wait_for_unit("multi-user.target") - machine.fail("zpool import forcepool") - machine.succeed( - "systemctl start forcepool.mount", - "mount | grep forcepool", - ) - '' - + extraTest; + with subtest("boot.zfs.forceImportAll works"): + machine.succeed( + "rm /etc/hostid", + "zgenhostid deadcafe", + "zpool create forcepool /dev/vdb1 -O mountpoint=legacy", + "${forcepool}/bin/switch-to-configuration boot", + "rm /etc/hostid", + "sync", + ) + machine.crash() + machine.wait_for_unit("multi-user.target") + machine.fail("zpool import forcepool") + machine.succeed( + "systemctl start forcepool.mount", + "mount | grep forcepool", + ) + '' + + extraTest; }; @@ -250,7 +255,7 @@ in systemdStage1 = true; }).zfsroot; - expand-partitions = makeTest { + expand-partitions = runTest { name = "multi-disk-zfs"; nodes = { machine =