1{ system ? builtins.currentSystem }:
2
3with import ../lib/testing.nix { inherit system; };
4with pkgs.lib;
5
6let
7
8 # The configuration to install.
9 makeConfig = { bootLoader, grubVersion, grubDevice, grubIdentifier, grubUseEfi
10 , extraConfig, forceGrubReinstallCount ? 0
11 }:
12 pkgs.writeText "configuration.nix" ''
13 { config, lib, pkgs, modulesPath, ... }:
14
15 { imports =
16 [ ./hardware-configuration.nix
17 <nixpkgs/nixos/modules/testing/test-instrumentation.nix>
18 ];
19
20 # To ensure that we can rebuild the grub configuration on the nixos-rebuild
21 system.extraDependencies = with pkgs; [ stdenvNoCC ];
22
23 ${optionalString (bootLoader == "grub") ''
24 boot.loader.grub.version = ${toString grubVersion};
25 ${optionalString (grubVersion == 1) ''
26 boot.loader.grub.splashImage = null;
27 ''}
28
29 boot.loader.grub.extraConfig = "serial; terminal_output.serial";
30 ${if grubUseEfi then ''
31 boot.loader.grub.device = "nodev";
32 boot.loader.grub.efiSupport = true;
33 boot.loader.grub.efiInstallAsRemovable = true; # XXX: needed for OVMF?
34 '' else ''
35 boot.loader.grub.device = "${grubDevice}";
36 boot.loader.grub.fsIdentifier = "${grubIdentifier}";
37 ''}
38
39 boot.loader.grub.configurationLimit = 100 + ${toString forceGrubReinstallCount};
40 ''}
41
42 ${optionalString (bootLoader == "systemd-boot") ''
43 boot.loader.systemd-boot.enable = true;
44 ''}
45
46 users.users.alice = {
47 isNormalUser = true;
48 home = "/home/alice";
49 description = "Alice Foobar";
50 };
51
52 hardware.enableAllFirmware = lib.mkForce false;
53
54 services.udisks2.enable = lib.mkDefault false;
55
56 ${replaceChars ["\n"] ["\n "] extraConfig}
57 }
58 '';
59
60
61 # The test script boots a NixOS VM, installs NixOS on an empty hard
62 # disk, and then reboot from the hard disk. It's parameterized with
63 # a test script fragment `createPartitions', which must create
64 # partitions and filesystems.
65 testScriptFun = { bootLoader, createPartitions, grubVersion, grubDevice, grubUseEfi
66 , grubIdentifier, preBootCommands, extraConfig
67 }:
68 let
69 iface = if grubVersion == 1 then "ide" else "virtio";
70 isEfi = bootLoader == "systemd-boot" || (bootLoader == "grub" && grubUseEfi);
71
72 # FIXME don't duplicate the -enable-kvm etc. flags here yet again!
73 qemuFlags =
74 (if system == "x86_64-linux" then "-m 768 " else "-m 512 ") +
75 (optionalString (system == "x86_64-linux") "-cpu kvm64 ") +
76 (optionalString (system == "aarch64-linux") "-enable-kvm -machine virt,gic-version=host -cpu host ");
77
78 hdFlags = ''hda => "vm-state-machine/machine.qcow2", hdaInterface => "${iface}", ''
79 + optionalString isEfi (if pkgs.stdenv.isAarch64
80 then ''bios => "${pkgs.OVMF.fd}/FV/QEMU_EFI.fd", ''
81 else ''bios => "${pkgs.OVMF.fd}/FV/OVMF.fd", '');
82 in if !isEfi && !(pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) then
83 throw "Non-EFI boot methods are only supported on i686 / x86_64"
84 else ''
85 $machine->start;
86
87 # Make sure that we get a login prompt etc.
88 $machine->succeed("echo hello");
89 #$machine->waitForUnit('getty@tty2');
90 #$machine->waitForUnit("rogue");
91 $machine->waitForUnit("nixos-manual");
92
93 # Wait for hard disks to appear in /dev
94 $machine->succeed("udevadm settle");
95
96 # Partition the disk.
97 ${createPartitions}
98
99 # Create the NixOS configuration.
100 $machine->succeed("nixos-generate-config --root /mnt");
101
102 $machine->succeed("cat /mnt/etc/nixos/hardware-configuration.nix >&2");
103
104 $machine->copyFileFromHost(
105 "${ makeConfig { inherit bootLoader grubVersion grubDevice grubIdentifier grubUseEfi extraConfig; } }",
106 "/mnt/etc/nixos/configuration.nix");
107
108 # Perform the installation.
109 $machine->succeed("nixos-install < /dev/null >&2");
110
111 # Do it again to make sure it's idempotent.
112 $machine->succeed("nixos-install < /dev/null >&2");
113
114 $machine->succeed("umount /mnt/boot || true");
115 $machine->succeed("umount /mnt");
116 $machine->succeed("sync");
117
118 $machine->shutdown;
119
120 # Now see if we can boot the installation.
121 $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}", name => "boot-after-install" });
122
123 # For example to enter LUKS passphrase.
124 ${preBootCommands}
125
126 # Did /boot get mounted?
127 $machine->waitForUnit("local-fs.target");
128
129 ${if bootLoader == "grub" then
130 ''$machine->succeed("test -e /boot/grub");''
131 else
132 ''$machine->succeed("test -e /boot/loader/loader.conf");''
133 }
134
135 # Check whether /root has correct permissions.
136 $machine->succeed("stat -c '%a' /root") =~ /700/ or die;
137
138 # Did the swap device get activated?
139 # uncomment once https://bugs.freedesktop.org/show_bug.cgi?id=86930 is resolved
140 $machine->waitForUnit("swap.target");
141 $machine->succeed("cat /proc/swaps | grep -q /dev");
142
143 # Check that the store is in good shape
144 $machine->succeed("nix-store --verify --check-contents >&2");
145
146 # Check whether the channel works.
147 $machine->succeed("nix-env -iA nixos.procps >&2");
148 $machine->succeed("type -tP ps | tee /dev/stderr") =~ /.nix-profile/
149 or die "nix-env failed";
150
151 # Check that the daemon works, and that non-root users can run builds (this will build a new profile generation through the daemon)
152 $machine->succeed("su alice -l -c 'nix-env -iA nixos.procps' >&2");
153
154 # We need a writable Nix store on next boot.
155 $machine->copyFileFromHost(
156 "${ makeConfig { inherit bootLoader grubVersion grubDevice grubIdentifier grubUseEfi extraConfig; forceGrubReinstallCount = 1; } }",
157 "/etc/nixos/configuration.nix");
158
159 # Check whether nixos-rebuild works.
160 $machine->succeed("nixos-rebuild switch >&2");
161
162 # Test nixos-option.
163 $machine->succeed("nixos-option boot.initrd.kernelModules | grep virtio_console");
164 $machine->succeed("nixos-option boot.initrd.kernelModules | grep 'List of modules'");
165 $machine->succeed("nixos-option boot.initrd.kernelModules | grep qemu-guest.nix");
166
167 $machine->shutdown;
168
169 # Check whether a writable store build works
170 $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}", name => "rebuild-switch" });
171 ${preBootCommands}
172 $machine->waitForUnit("multi-user.target");
173 $machine->copyFileFromHost(
174 "${ makeConfig { inherit bootLoader grubVersion grubDevice grubIdentifier grubUseEfi extraConfig; forceGrubReinstallCount = 2; } }",
175 "/etc/nixos/configuration.nix");
176 $machine->succeed("nixos-rebuild boot >&2");
177 $machine->shutdown;
178
179 # And just to be sure, check that the machine still boots after
180 # "nixos-rebuild switch".
181 $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}", "boot-after-rebuild-switch" });
182 ${preBootCommands}
183 $machine->waitForUnit("network.target");
184 $machine->shutdown;
185 '';
186
187
188 makeInstallerTest = name:
189 { createPartitions, preBootCommands ? "", extraConfig ? ""
190 , extraInstallerConfig ? {}
191 , bootLoader ? "grub" # either "grub" or "systemd-boot"
192 , grubVersion ? 2, grubDevice ? "/dev/vda", grubIdentifier ? "uuid", grubUseEfi ? false
193 , enableOCR ? false, meta ? {}
194 }:
195 makeTest {
196 inherit enableOCR;
197 name = "installer-" + name;
198 meta = with pkgs.stdenv.lib.maintainers; {
199 # put global maintainers here, individuals go into makeInstallerTest fkt call
200 maintainers = [ wkennington ] ++ (meta.maintainers or []);
201 };
202 nodes = {
203
204 # The configuration of the machine used to run "nixos-install".
205 machine =
206 { pkgs, ... }:
207
208 { imports =
209 [ ../modules/profiles/installation-device.nix
210 ../modules/profiles/base.nix
211 extraInstallerConfig
212 ];
213
214 virtualisation.diskSize = 8 * 1024;
215 virtualisation.memorySize = 1024;
216
217 # Use a small /dev/vdb as the root disk for the
218 # installer. This ensures the target disk (/dev/vda) is
219 # the same during and after installation.
220 virtualisation.emptyDiskImages = [ 512 ];
221 virtualisation.bootDevice =
222 if grubVersion == 1 then "/dev/sdb" else "/dev/vdb";
223 virtualisation.qemu.diskInterface =
224 if grubVersion == 1 then "scsi" else "virtio";
225
226 boot.loader.systemd-boot.enable = mkIf (bootLoader == "systemd-boot") true;
227
228 hardware.enableAllFirmware = mkForce false;
229
230 # The test cannot access the network, so any packages we
231 # need must be included in the VM.
232 system.extraDependencies = with pkgs;
233 [ sudo
234 libxml2.bin
235 libxslt.bin
236 desktop-file-utils
237 docbook5
238 docbook_xsl_ns
239 unionfs-fuse
240 ntp
241 nixos-artwork.wallpapers.simple-dark-gray-bottom
242 perlPackages.XMLLibXML
243 perlPackages.ListCompare
244 shared-mime-info
245 texinfo
246 xorg.lndir
247
248 # add curl so that rather than seeing the test attempt to download
249 # curl's tarball, we see what it's trying to download
250 curl
251 ]
252 ++ optional (bootLoader == "grub" && grubVersion == 1) pkgs.grub
253 ++ optionals (bootLoader == "grub" && grubVersion == 2) [ pkgs.grub2 pkgs.grub2_efi ];
254
255 services.udisks2.enable = mkDefault false;
256
257 nix.binaryCaches = mkForce [ ];
258 nix.extraOptions =
259 ''
260 hashed-mirrors =
261 connect-timeout = 1
262 '';
263 };
264
265 };
266
267 testScript = testScriptFun {
268 inherit bootLoader createPartitions preBootCommands
269 grubVersion grubDevice grubIdentifier grubUseEfi extraConfig;
270 };
271 };
272
273
274in {
275
276 # !!! `parted mkpart' seems to silently create overlapping partitions.
277
278
279 # The (almost) simplest partitioning scheme: a swap partition and
280 # one big filesystem partition.
281 simple = makeInstallerTest "simple"
282 { createPartitions =
283 ''
284 $machine->succeed(
285 "parted --script /dev/vda mklabel msdos",
286 "parted --script /dev/vda -- mkpart primary linux-swap 1M 1024M",
287 "parted --script /dev/vda -- mkpart primary ext2 1024M -1s",
288 "udevadm settle",
289 "mkswap /dev/vda1 -L swap",
290 "swapon -L swap",
291 "mkfs.ext3 -L nixos /dev/vda2",
292 "mount LABEL=nixos /mnt",
293 );
294 '';
295 };
296
297 # Simple GPT/UEFI configuration using systemd-boot with 3 partitions: ESP, swap & root filesystem
298 simpleUefiSystemdBoot = makeInstallerTest "simpleUefiSystemdBoot"
299 { createPartitions =
300 ''
301 $machine->succeed(
302 "parted --script /dev/vda mklabel gpt",
303 "parted --script /dev/vda -- mkpart ESP fat32 1M 50MiB", # /boot
304 "parted --script /dev/vda -- set 1 boot on",
305 "parted --script /dev/vda -- mkpart primary linux-swap 50MiB 1024MiB",
306 "parted --script /dev/vda -- mkpart primary ext2 1024MiB -1MiB", # /
307 "udevadm settle",
308 "mkswap /dev/vda2 -L swap",
309 "swapon -L swap",
310 "mkfs.ext3 -L nixos /dev/vda3",
311 "mount LABEL=nixos /mnt",
312 "mkfs.vfat -n BOOT /dev/vda1",
313 "mkdir -p /mnt/boot",
314 "mount LABEL=BOOT /mnt/boot",
315 );
316 '';
317 bootLoader = "systemd-boot";
318 };
319
320 simpleUefiGrub = makeInstallerTest "simpleUefiGrub"
321 { createPartitions =
322 ''
323 $machine->succeed(
324 "parted --script /dev/vda mklabel gpt",
325 "parted --script /dev/vda -- mkpart ESP fat32 1M 50MiB", # /boot
326 "parted --script /dev/vda -- set 1 boot on",
327 "parted --script /dev/vda -- mkpart primary linux-swap 50MiB 1024MiB",
328 "parted --script /dev/vda -- mkpart primary ext2 1024MiB -1MiB", # /
329 "udevadm settle",
330 "mkswap /dev/vda2 -L swap",
331 "swapon -L swap",
332 "mkfs.ext3 -L nixos /dev/vda3",
333 "mount LABEL=nixos /mnt",
334 "mkfs.vfat -n BOOT /dev/vda1",
335 "mkdir -p /mnt/boot",
336 "mount LABEL=BOOT /mnt/boot",
337 );
338 '';
339 bootLoader = "grub";
340 grubUseEfi = true;
341 };
342
343 # Same as the previous, but now with a separate /boot partition.
344 separateBoot = makeInstallerTest "separateBoot"
345 { createPartitions =
346 ''
347 $machine->succeed(
348 "parted --script /dev/vda mklabel msdos",
349 "parted --script /dev/vda -- mkpart primary ext2 1M 50MB", # /boot
350 "parted --script /dev/vda -- mkpart primary linux-swap 50MB 1024M",
351 "parted --script /dev/vda -- mkpart primary ext2 1024M -1s", # /
352 "udevadm settle",
353 "mkswap /dev/vda2 -L swap",
354 "swapon -L swap",
355 "mkfs.ext3 -L nixos /dev/vda3",
356 "mount LABEL=nixos /mnt",
357 "mkfs.ext3 -L boot /dev/vda1",
358 "mkdir -p /mnt/boot",
359 "mount LABEL=boot /mnt/boot",
360 );
361 '';
362 };
363
364 # Same as the previous, but with fat32 /boot.
365 separateBootFat = makeInstallerTest "separateBootFat"
366 { createPartitions =
367 ''
368 $machine->succeed(
369 "parted --script /dev/vda mklabel msdos",
370 "parted --script /dev/vda -- mkpart primary ext2 1M 50MB", # /boot
371 "parted --script /dev/vda -- mkpart primary linux-swap 50MB 1024M",
372 "parted --script /dev/vda -- mkpart primary ext2 1024M -1s", # /
373 "udevadm settle",
374 "mkswap /dev/vda2 -L swap",
375 "swapon -L swap",
376 "mkfs.ext3 -L nixos /dev/vda3",
377 "mount LABEL=nixos /mnt",
378 "mkfs.vfat -n BOOT /dev/vda1",
379 "mkdir -p /mnt/boot",
380 "mount LABEL=BOOT /mnt/boot",
381 );
382 '';
383 };
384
385 # zfs on / with swap
386 zfsroot = makeInstallerTest "zfs-root"
387 {
388 extraInstallerConfig = {
389 boot.supportedFilesystems = [ "zfs" ];
390 };
391
392 extraConfig = ''
393 boot.supportedFilesystems = [ "zfs" ];
394
395 # Using by-uuid overrides the default of by-id, and is unique
396 # to the qemu disks, as they don't produce by-id paths for
397 # some reason.
398 boot.zfs.devNodes = "/dev/disk/by-uuid/";
399 networking.hostId = "00000000";
400 '';
401
402 createPartitions =
403 ''
404 $machine->succeed(
405 "parted --script /dev/vda mklabel msdos",
406 "parted --script /dev/vda -- mkpart primary linux-swap 1M 1024M",
407 "parted --script /dev/vda -- mkpart primary 1024M -1s",
408 "udevadm settle",
409
410 "mkswap /dev/vda1 -L swap",
411 "swapon -L swap",
412
413 "zpool create rpool /dev/vda2",
414 "zfs create -o mountpoint=legacy rpool/root",
415 "mount -t zfs rpool/root /mnt",
416
417 "udevadm settle"
418 );
419 '';
420 };
421
422 # Create two physical LVM partitions combined into one volume group
423 # that contains the logical swap and root partitions.
424 lvm = makeInstallerTest "lvm"
425 { createPartitions =
426 ''
427 $machine->succeed(
428 "parted --script /dev/vda mklabel msdos",
429 "parted --script /dev/vda -- mkpart primary 1M 2048M", # PV1
430 "parted --script /dev/vda -- set 1 lvm on",
431 "parted --script /dev/vda -- mkpart primary 2048M -1s", # PV2
432 "parted --script /dev/vda -- set 2 lvm on",
433 "udevadm settle",
434 "pvcreate /dev/vda1 /dev/vda2",
435 "vgcreate MyVolGroup /dev/vda1 /dev/vda2",
436 "lvcreate --size 1G --name swap MyVolGroup",
437 "lvcreate --size 2G --name nixos MyVolGroup",
438 "mkswap -f /dev/MyVolGroup/swap -L swap",
439 "swapon -L swap",
440 "mkfs.xfs -L nixos /dev/MyVolGroup/nixos",
441 "mount LABEL=nixos /mnt",
442 );
443 '';
444 };
445
446 # Boot off an encrypted root partition
447 luksroot = makeInstallerTest "luksroot"
448 { createPartitions = ''
449 $machine->succeed(
450 "parted --script /dev/vda mklabel msdos",
451 "parted --script /dev/vda -- mkpart primary ext2 1M 50MB", # /boot
452 "parted --script /dev/vda -- mkpart primary linux-swap 50M 1024M",
453 "parted --script /dev/vda -- mkpart primary 1024M -1s", # LUKS
454 "udevadm settle",
455 "mkswap /dev/vda2 -L swap",
456 "swapon -L swap",
457 "modprobe dm_mod dm_crypt",
458 "echo -n supersecret | cryptsetup luksFormat -q /dev/vda3 -",
459 "echo -n supersecret | cryptsetup luksOpen --key-file - /dev/vda3 cryptroot",
460 "mkfs.ext3 -L nixos /dev/mapper/cryptroot",
461 "mount LABEL=nixos /mnt",
462 "mkfs.ext3 -L boot /dev/vda1",
463 "mkdir -p /mnt/boot",
464 "mount LABEL=boot /mnt/boot",
465 );
466 '';
467 extraConfig = ''
468 boot.kernelParams = lib.mkAfter [ "console=tty0" ];
469 '';
470 enableOCR = true;
471 preBootCommands = ''
472 $machine->start;
473 $machine->waitForText(qr/Passphrase for/);
474 $machine->sendChars("supersecret\n");
475 '';
476 };
477
478 # Test whether opening encrypted filesystem with keyfile
479 # Checks for regression of missing cryptsetup, when no luks device without
480 # keyfile is configured
481 filesystemEncryptedWithKeyfile = makeInstallerTest "filesystemEncryptedWithKeyfile"
482 { createPartitions = ''
483 $machine->succeed(
484 "parted --script /dev/vda mklabel msdos",
485 "parted --script /dev/vda -- mkpart primary ext2 1M 50MB", # /boot
486 "parted --script /dev/vda -- mkpart primary linux-swap 50M 1024M",
487 "parted --script /dev/vda -- mkpart primary 1024M 1280M", # LUKS with keyfile
488 "parted --script /dev/vda -- mkpart primary 1280M -1s",
489 "udevadm settle",
490 "mkswap /dev/vda2 -L swap",
491 "swapon -L swap",
492 "mkfs.ext3 -L nixos /dev/vda4",
493 "mount LABEL=nixos /mnt",
494 "mkfs.ext3 -L boot /dev/vda1",
495 "mkdir -p /mnt/boot",
496 "mount LABEL=boot /mnt/boot",
497 "modprobe dm_mod dm_crypt",
498 "echo -n supersecret > /mnt/keyfile",
499 "cryptsetup luksFormat -q /dev/vda3 --key-file /mnt/keyfile",
500 "cryptsetup luksOpen --key-file /mnt/keyfile /dev/vda3 crypt",
501 "mkfs.ext3 -L test /dev/mapper/crypt",
502 "cryptsetup luksClose crypt",
503 "mkdir -p /mnt/test"
504 );
505 '';
506 extraConfig = ''
507 fileSystems."/test" =
508 { device = "/dev/disk/by-label/test";
509 fsType = "ext3";
510 encrypted.enable = true;
511 encrypted.blkDev = "/dev/vda3";
512 encrypted.label = "crypt";
513 encrypted.keyFile = "/mnt-root/keyfile";
514 };
515 '';
516 };
517
518
519 swraid = makeInstallerTest "swraid"
520 { createPartitions =
521 ''
522 $machine->succeed(
523 "parted --script /dev/vda --"
524 . " mklabel msdos"
525 . " mkpart primary ext2 1M 100MB" # /boot
526 . " mkpart extended 100M -1s"
527 . " mkpart logical 102M 2102M" # md0 (root), first device
528 . " mkpart logical 2103M 4103M" # md0 (root), second device
529 . " mkpart logical 4104M 4360M" # md1 (swap), first device
530 . " mkpart logical 4361M 4617M", # md1 (swap), second device
531 "udevadm settle",
532 "ls -l /dev/vda* >&2",
533 "cat /proc/partitions >&2",
534 "mdadm --create --force /dev/md0 --metadata 1.2 --level=raid1 --raid-devices=2 /dev/vda5 /dev/vda6",
535 "mdadm --create --force /dev/md1 --metadata 1.2 --level=raid1 --raid-devices=2 /dev/vda7 /dev/vda8",
536 "udevadm settle",
537 "mkswap -f /dev/md1 -L swap",
538 "swapon -L swap",
539 "mkfs.ext3 -L nixos /dev/md0",
540 "mount LABEL=nixos /mnt",
541 "mkfs.ext3 -L boot /dev/vda1",
542 "mkdir /mnt/boot",
543 "mount LABEL=boot /mnt/boot",
544 "udevadm settle",
545 );
546 '';
547 preBootCommands = ''
548 $machine->start;
549 $machine->fail("dmesg | grep 'immediate safe mode'");
550 '';
551 };
552
553 # Test a basic install using GRUB 1.
554 grub1 = makeInstallerTest "grub1"
555 { createPartitions =
556 ''
557 $machine->succeed(
558 "parted --script /dev/sda mklabel msdos",
559 "parted --script /dev/sda -- mkpart primary linux-swap 1M 1024M",
560 "parted --script /dev/sda -- mkpart primary ext2 1024M -1s",
561 "udevadm settle",
562 "mkswap /dev/sda1 -L swap",
563 "swapon -L swap",
564 "mkfs.ext3 -L nixos /dev/sda2",
565 "mount LABEL=nixos /mnt",
566 );
567 '';
568 grubVersion = 1;
569 grubDevice = "/dev/sda";
570 };
571
572 # Test using labels to identify volumes in grub
573 simpleLabels = makeInstallerTest "simpleLabels" {
574 createPartitions = ''
575 $machine->succeed(
576 "sgdisk -Z /dev/vda",
577 "sgdisk -n 1:0:+1M -n 2:0:+1G -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda",
578 "mkswap /dev/vda2 -L swap",
579 "swapon -L swap",
580 "mkfs.ext4 -L root /dev/vda3",
581 "mount LABEL=root /mnt",
582 );
583 '';
584 grubIdentifier = "label";
585 };
586
587 # Test using the provided disk name within grub
588 # TODO: Fix udev so the symlinks are unneeded in /dev/disks
589 simpleProvided = makeInstallerTest "simpleProvided" {
590 createPartitions = ''
591 my $UUID = "\$(blkid -s UUID -o value /dev/vda2)";
592 $machine->succeed(
593 "sgdisk -Z /dev/vda",
594 "sgdisk -n 1:0:+1M -n 2:0:+100M -n 3:0:+1G -N 4 -t 1:ef02 -t 2:8300 -t 3:8200 -t 4:8300 -c 2:boot -c 4:root /dev/vda",
595 "mkswap /dev/vda3 -L swap",
596 "swapon -L swap",
597 "mkfs.ext4 -L boot /dev/vda2",
598 "mkfs.ext4 -L root /dev/vda4",
599 );
600 $machine->execute("ln -s ../../vda2 /dev/disk/by-uuid/$UUID");
601 $machine->execute("ln -s ../../vda4 /dev/disk/by-label/root");
602 $machine->succeed(
603 "mount /dev/disk/by-label/root /mnt",
604 "mkdir /mnt/boot",
605 "mount /dev/disk/by-uuid/$UUID /mnt/boot"
606 );
607 '';
608 grubIdentifier = "provided";
609 };
610
611 # Simple btrfs grub testing
612 btrfsSimple = makeInstallerTest "btrfsSimple" {
613 createPartitions = ''
614 $machine->succeed(
615 "sgdisk -Z /dev/vda",
616 "sgdisk -n 1:0:+1M -n 2:0:+1G -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda",
617 "mkswap /dev/vda2 -L swap",
618 "swapon -L swap",
619 "mkfs.btrfs -L root /dev/vda3",
620 "mount LABEL=root /mnt",
621 );
622 '';
623 };
624
625 # Test to see if we can detect /boot and /nix on subvolumes
626 btrfsSubvols = makeInstallerTest "btrfsSubvols" {
627 createPartitions = ''
628 $machine->succeed(
629 "sgdisk -Z /dev/vda",
630 "sgdisk -n 1:0:+1M -n 2:0:+1G -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda",
631 "mkswap /dev/vda2 -L swap",
632 "swapon -L swap",
633 "mkfs.btrfs -L root /dev/vda3",
634 "btrfs device scan",
635 "mount LABEL=root /mnt",
636 "btrfs subvol create /mnt/boot",
637 "btrfs subvol create /mnt/nixos",
638 "btrfs subvol create /mnt/nixos/default",
639 "umount /mnt",
640 "mount -o defaults,subvol=nixos/default LABEL=root /mnt",
641 "mkdir /mnt/boot",
642 "mount -o defaults,subvol=boot LABEL=root /mnt/boot",
643 );
644 '';
645 };
646
647 # Test to see if we can detect default and aux subvolumes correctly
648 btrfsSubvolDefault = makeInstallerTest "btrfsSubvolDefault" {
649 createPartitions = ''
650 $machine->succeed(
651 "sgdisk -Z /dev/vda",
652 "sgdisk -n 1:0:+1M -n 2:0:+1G -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda",
653 "mkswap /dev/vda2 -L swap",
654 "swapon -L swap",
655 "mkfs.btrfs -L root /dev/vda3",
656 "btrfs device scan",
657 "mount LABEL=root /mnt",
658 "btrfs subvol create /mnt/badpath",
659 "btrfs subvol create /mnt/badpath/boot",
660 "btrfs subvol create /mnt/nixos",
661 "btrfs subvol set-default \$(btrfs subvol list /mnt | grep 'nixos' | awk '{print \$2}') /mnt",
662 "umount /mnt",
663 "mount -o defaults LABEL=root /mnt",
664 "mkdir -p /mnt/badpath/boot", # Help ensure the detection mechanism is actually looking up subvolumes
665 "mkdir /mnt/boot",
666 "mount -o defaults,subvol=badpath/boot LABEL=root /mnt/boot",
667 );
668 '';
669 };
670
671}