1{ lib, pkgs, ... }:
2{
3 name = "systemd-initrd-swraid";
4
5 nodes.machine =
6 { pkgs, ... }:
7 {
8 # Use systemd-boot
9 virtualisation = {
10 emptyDiskImages = [
11 512
12 512
13 ];
14 useBootLoader = true;
15 # Booting off the RAID requires an available init script
16 mountHostNixStore = true;
17 useEFIBoot = true;
18 };
19 boot.loader.systemd-boot.enable = true;
20 boot.loader.efi.canTouchEfiVariables = true;
21
22 environment.systemPackages = with pkgs; [
23 mdadm
24 e2fsprogs
25 ]; # for mdadm and mkfs.ext4
26 boot.swraid = {
27 enable = true;
28 mdadmConf = ''
29 ARRAY /dev/md0 devices=/dev/vdb,/dev/vdc
30 '';
31 };
32 environment.etc."mdadm.conf".text = ''
33 MAILADDR test@example.com
34 '';
35 boot.initrd = {
36 systemd = {
37 enable = true;
38 emergencyAccess = true;
39 };
40 kernelModules = [ "raid0" ];
41 };
42
43 specialisation.boot-swraid.configuration.virtualisation.rootDevice = "/dev/disk/by-label/testraid";
44 # This protects against a regression. We do not have to switch to it.
45 # It's sufficient to trigger its evaluation.
46 specialisation.build-old-initrd.configuration.boot.initrd.systemd.enable = lib.mkForce false;
47 };
48
49 testScript = ''
50 # Create RAID
51 machine.succeed("mdadm --create --force /dev/md0 -n 2 --level=raid1 /dev/vdb /dev/vdc --metadata=0.90")
52 machine.succeed("mkfs.ext4 -L testraid /dev/md0")
53 machine.succeed("mkdir -p /mnt && mount /dev/md0 /mnt && echo hello > /mnt/test && umount /mnt")
54
55 # Boot from the RAID
56 machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-swraid.conf")
57 machine.succeed("sync")
58 machine.crash()
59 machine.wait_for_unit("multi-user.target")
60
61 # Ensure we have successfully booted from the RAID
62 assert "(initrd)" in machine.succeed("systemd-analyze") # booted with systemd in stage 1
63 assert "/dev/md0 on / type ext4" in machine.succeed("mount")
64 assert "hello" in machine.succeed("cat /test")
65 assert "md0" in machine.succeed("cat /proc/mdstat")
66
67 expected_config = """MAILADDR test@example.com
68
69 ARRAY /dev/md0 devices=/dev/vdb,/dev/vdc
70 """
71 got_config = machine.execute("cat /etc/mdadm.conf")[1]
72 assert expected_config == got_config, repr((expected_config, got_config))
73 machine.wait_for_unit("mdmonitor.service")
74 '';
75}