1{
2 system ? builtins.currentSystem,
3 config ? { },
4 pkgs ? import ../.. { inherit system config; },
5}:
6
7with import ../lib/testing-python.nix { inherit system pkgs; };
8with pkgs.lib;
9
10let
11 baseline = {
12 virtualisation.useBootLoader = true;
13 };
14 grub = {
15 boot.loader.grub.enable = true;
16 };
17 systemd-boot = {
18 boot.loader.systemd-boot.enable = true;
19 };
20 uefi = {
21 virtualisation.useEFIBoot = true;
22 boot.loader.efi.canTouchEfiVariables = true;
23 boot.loader.grub.efiSupport = true;
24 environment.systemPackages = [ pkgs.efibootmgr ];
25 };
26 standard = {
27 boot.bootspec.enable = true;
28
29 imports = [
30 baseline
31 systemd-boot
32 uefi
33 ];
34 };
35in
36{
37 basic = makeTest {
38 name = "systemd-boot-with-bootspec";
39 meta.maintainers = with pkgs.lib.maintainers; [ raitobezarius ];
40
41 nodes.machine = standard;
42
43 testScript = ''
44 machine.start()
45 machine.wait_for_unit("multi-user.target")
46
47 machine.succeed("test -e /run/current-system/boot.json")
48 '';
49 };
50
51 grub = makeTest {
52 name = "grub-with-bootspec";
53 meta.maintainers = with pkgs.lib.maintainers; [ raitobezarius ];
54
55 nodes.machine = {
56 boot.bootspec.enable = true;
57
58 imports = [
59 baseline
60 grub
61 uefi
62 ];
63 };
64
65 testScript = ''
66 machine.start()
67 machine.wait_for_unit("multi-user.target")
68
69 machine.succeed("test -e /run/current-system/boot.json")
70 '';
71 };
72
73 legacy-boot = makeTest {
74 name = "legacy-boot-with-bootspec";
75 meta.maintainers = with pkgs.lib.maintainers; [ raitobezarius ];
76
77 nodes.machine = {
78 boot.bootspec.enable = true;
79
80 imports = [
81 baseline
82 grub
83 ];
84 };
85
86 testScript = ''
87 machine.start()
88 machine.wait_for_unit("multi-user.target")
89
90 machine.succeed("test -e /run/current-system/boot.json")
91 '';
92 };
93
94 # Check that initrd create corresponding entries in bootspec.
95 initrd = makeTest {
96 name = "bootspec-with-initrd";
97 meta.maintainers = with pkgs.lib.maintainers; [ raitobezarius ];
98
99 nodes.machine = {
100 imports = [ standard ];
101 environment.systemPackages = [ pkgs.jq ];
102 # It's probably the case, but we want to make it explicit here.
103 boot.initrd.enable = true;
104 };
105
106 testScript = ''
107 import json
108
109 machine.start()
110 machine.wait_for_unit("multi-user.target")
111
112 machine.succeed("test -e /run/current-system/boot.json")
113
114 bootspec = json.loads(machine.succeed("jq -r '.\"org.nixos.bootspec.v1\"' /run/current-system/boot.json"))
115
116 assert 'initrd' in bootspec, "Bootspec should contain initrd field when initrd is enabled"
117 assert 'initrdSecrets' not in bootspec, "Bootspec should not contain initrdSecrets when there's no initrdSecrets"
118 '';
119 };
120
121 # Check that initrd secrets create corresponding entries in bootspec.
122 initrd-secrets = makeTest {
123 name = "bootspec-with-initrd-secrets";
124 meta.maintainers = with pkgs.lib.maintainers; [ raitobezarius ];
125
126 nodes.machine = {
127 imports = [ standard ];
128 environment.systemPackages = [ pkgs.jq ];
129 # It's probably the case, but we want to make it explicit here.
130 boot.initrd.enable = true;
131 boot.initrd.secrets."/some/example" = pkgs.writeText "example-secret" "test";
132 };
133
134 testScript = ''
135 import json
136
137 machine.start()
138 machine.wait_for_unit("multi-user.target")
139
140 machine.succeed("test -e /run/current-system/boot.json")
141
142 bootspec = json.loads(machine.succeed("jq -r '.\"org.nixos.bootspec.v1\"' /run/current-system/boot.json"))
143
144 assert 'initrdSecrets' in bootspec, "Bootspec should contain an 'initrdSecrets' field given there's an initrd secret"
145 '';
146 };
147
148 # Check that specialisations create corresponding entries in bootspec.
149 specialisation = makeTest {
150 name = "bootspec-with-specialisation";
151 meta.maintainers = with pkgs.lib.maintainers; [ raitobezarius ];
152
153 nodes.machine = {
154 imports = [ standard ];
155 environment.systemPackages = [ pkgs.jq ];
156 specialisation.something.configuration = { };
157 };
158
159 testScript = ''
160 import json
161
162 machine.start()
163 machine.wait_for_unit("multi-user.target")
164
165 machine.succeed("test -e /run/current-system/boot.json")
166 machine.succeed("test -e /run/current-system/specialisation/something/boot.json")
167
168 sp_in_parent = json.loads(machine.succeed("jq -r '.\"org.nixos.specialisation.v1\".something' /run/current-system/boot.json"))
169 sp_in_fs = json.loads(machine.succeed("cat /run/current-system/specialisation/something/boot.json"))
170
171 assert sp_in_parent['org.nixos.bootspec.v1'] == sp_in_fs['org.nixos.bootspec.v1'], "Bootspecs of the same specialisation are different!"
172 '';
173 };
174
175 # Check that extensions are propagated.
176 extensions = makeTest {
177 name = "bootspec-with-extensions";
178 meta.maintainers = with pkgs.lib.maintainers; [ raitobezarius ];
179
180 nodes.machine =
181 { config, ... }:
182 {
183 imports = [ standard ];
184 environment.systemPackages = [ pkgs.jq ];
185 boot.bootspec.extensions = {
186 "org.nix-tests.product" = {
187 osRelease = config.environment.etc."os-release".source;
188 };
189 };
190 };
191
192 testScript = ''
193 machine.start()
194 machine.wait_for_unit("multi-user.target")
195
196 current_os_release = machine.succeed("cat /etc/os-release")
197 bootspec_os_release = machine.succeed("cat $(jq -r '.\"org.nix-tests.product\".osRelease' /run/current-system/boot.json)")
198
199 assert current_os_release == bootspec_os_release, "Filename referenced by extension has unexpected contents"
200 '';
201 };
202
203}