1{ lib, pkgs, ... }:
2
3let
4 initrdLowerdir = pkgs.runCommand "initrd-lowerdir" { } ''
5 mkdir -p $out
6 echo "initrd" > $out/initrd.txt
7 '';
8 initrdLowerdir2 = pkgs.runCommand "initrd-lowerdir-2" { } ''
9 mkdir -p $out
10 echo "initrd2" > $out/initrd2.txt
11 '';
12 userspaceLowerdir = pkgs.runCommand "userspace-lowerdir" { } ''
13 mkdir -p $out
14 echo "userspace" > $out/userspace.txt
15 '';
16 userspaceLowerdir2 = pkgs.runCommand "userspace-lowerdir-2" { } ''
17 mkdir -p $out
18 echo "userspace2" > $out/userspace2.txt
19 '';
20in
21{
22
23 name = "writable-overlays";
24
25 meta.maintainers = with lib.maintainers; [ nikstur ];
26
27 nodes.machine =
28 { config, pkgs, ... }:
29 {
30 boot.initrd.systemd.enable = true;
31
32 virtualisation.fileSystems = {
33 "/initrd-overlay" = {
34 overlay = {
35 lowerdir = [ initrdLowerdir ];
36 upperdir = "/.rw-initrd-overlay/upper";
37 workdir = "/.rw-initrd-overlay/work";
38 };
39 neededForBoot = true;
40 };
41 "/initrd-real-root-overlay" = {
42 overlay = {
43 lowerdir = [ userspaceLowerdir ];
44 upperdir = "/run/upper"; # from initrd
45 workdir = "/run/work"; # from initrd
46 useStage1BaseDirectories = false;
47 };
48 };
49 "/userspace-overlay" = {
50 overlay = {
51 lowerdir = [ userspaceLowerdir ];
52 upperdir = "/.rw-userspace-overlay/upper";
53 workdir = "/.rw-userspace-overlay/work";
54 };
55 };
56 "/ro-initrd-overlay" = {
57 overlay.lowerdir = [
58 initrdLowerdir
59 initrdLowerdir2
60 ];
61 neededForBoot = true;
62 };
63 "/ro-userspace-overlay" = {
64 overlay.lowerdir = [
65 userspaceLowerdir
66 userspaceLowerdir2
67 ];
68 };
69 };
70 };
71
72 testScript = ''
73 machine.wait_for_unit("default.target")
74
75 with subtest("Initrd overlay"):
76 machine.wait_for_file("/initrd-overlay/initrd.txt", 5)
77 machine.succeed("touch /initrd-overlay/writable.txt")
78 machine.succeed("findmnt --kernel --types overlay /initrd-overlay")
79
80 with subtest("Userspace overlay with upper/workdir in initrd"):
81 machine.wait_for_file("/initrd-real-root-overlay/userspace.txt", 5)
82 machine.succeed("touch /initrd-real-root-overlay/writable.txt")
83 machine.succeed("findmnt --kernel --types overlay /initrd-real-root-overlay")
84
85 with subtest("Userspace overlay"):
86 machine.wait_for_file("/userspace-overlay/userspace.txt", 5)
87 machine.succeed("touch /userspace-overlay/writable.txt")
88 machine.succeed("findmnt --kernel --types overlay /userspace-overlay")
89
90 with subtest("Read only initrd overlay"):
91 machine.wait_for_file("/ro-initrd-overlay/initrd.txt", 5)
92 machine.wait_for_file("/ro-initrd-overlay/initrd2.txt", 5)
93 machine.fail("touch /ro-initrd-overlay/not-writable.txt")
94 machine.succeed("findmnt --kernel --types overlay /ro-initrd-overlay")
95
96 with subtest("Read only userspace overlay"):
97 machine.wait_for_file("/ro-userspace-overlay/userspace.txt", 5)
98 machine.wait_for_file("/ro-userspace-overlay/userspace2.txt", 5)
99 machine.fail("touch /ro-userspace-overlay/not-writable.txt")
100 machine.succeed("findmnt --kernel --types overlay /ro-userspace-overlay")
101 '';
102
103}