at 22.05-pre 30 kB view raw
1{ system ? builtins.currentSystem, 2 config ? {}, 3 pkgs ? import ../.. { inherit system config; } 4}: 5 6with import ../lib/testing-python.nix { inherit system pkgs; }; 7with pkgs.lib; 8 9let 10 11 # The configuration to install. 12 makeConfig = { bootLoader, grubVersion, grubDevice, grubIdentifier, grubUseEfi 13 , extraConfig, forceGrubReinstallCount ? 0 14 }: 15 pkgs.writeText "configuration.nix" '' 16 { config, lib, pkgs, modulesPath, ... }: 17 18 { imports = 19 [ ./hardware-configuration.nix 20 <nixpkgs/nixos/modules/testing/test-instrumentation.nix> 21 ]; 22 23 # To ensure that we can rebuild the grub configuration on the nixos-rebuild 24 system.extraDependencies = with pkgs; [ stdenvNoCC ]; 25 26 ${optionalString (bootLoader == "grub") '' 27 boot.loader.grub.version = ${toString grubVersion}; 28 ${optionalString (grubVersion == 1) '' 29 boot.loader.grub.splashImage = null; 30 ''} 31 32 boot.loader.grub.extraConfig = "serial; terminal_output serial"; 33 ${if grubUseEfi then '' 34 boot.loader.grub.device = "nodev"; 35 boot.loader.grub.efiSupport = true; 36 boot.loader.grub.efiInstallAsRemovable = true; # XXX: needed for OVMF? 37 '' else '' 38 boot.loader.grub.device = "${grubDevice}"; 39 boot.loader.grub.fsIdentifier = "${grubIdentifier}"; 40 ''} 41 42 boot.loader.grub.configurationLimit = 100 + ${toString forceGrubReinstallCount}; 43 ''} 44 45 ${optionalString (bootLoader == "systemd-boot") '' 46 boot.loader.systemd-boot.enable = true; 47 ''} 48 49 users.users.alice = { 50 isNormalUser = true; 51 home = "/home/alice"; 52 description = "Alice Foobar"; 53 }; 54 55 hardware.enableAllFirmware = lib.mkForce false; 56 57 ${replaceChars ["\n"] ["\n "] extraConfig} 58 } 59 ''; 60 61 62 # The test script boots a NixOS VM, installs NixOS on an empty hard 63 # disk, and then reboot from the hard disk. It's parameterized with 64 # a test script fragment `createPartitions', which must create 65 # partitions and filesystems. 66 testScriptFun = { bootLoader, createPartitions, grubVersion, grubDevice, grubUseEfi 67 , grubIdentifier, preBootCommands, postBootCommands, extraConfig 68 , testSpecialisationConfig 69 }: 70 let iface = if grubVersion == 1 then "ide" else "virtio"; 71 isEfi = bootLoader == "systemd-boot" || (bootLoader == "grub" && grubUseEfi); 72 bios = if pkgs.stdenv.isAarch64 then "QEMU_EFI.fd" else "OVMF.fd"; 73 in if !isEfi && !pkgs.stdenv.hostPlatform.isx86 then 74 throw "Non-EFI boot methods are only supported on i686 / x86_64" 75 else '' 76 def assemble_qemu_flags(): 77 flags = "-cpu max" 78 ${if (system == "x86_64-linux" || system == "i686-linux") 79 then ''flags += " -m 1500"'' 80 else ''flags += " -m 1000 -enable-kvm -machine virt,gic-version=host"'' 81 } 82 return flags 83 84 85 qemu_flags = {"qemuFlags": assemble_qemu_flags()} 86 87 hd_flags = { 88 "hdaInterface": "${iface}", 89 "hda": "vm-state-machine/machine.qcow2", 90 } 91 ${optionalString isEfi '' 92 hd_flags.update( 93 bios="${pkgs.OVMF.fd}/FV/${bios}" 94 )'' 95 } 96 default_flags = {**hd_flags, **qemu_flags} 97 98 99 def create_machine_named(name): 100 return create_machine({**default_flags, "name": name}) 101 102 103 machine.start() 104 105 with subtest("Assert readiness of login prompt"): 106 machine.succeed("echo hello") 107 108 with subtest("Wait for hard disks to appear in /dev"): 109 machine.succeed("udevadm settle") 110 111 ${createPartitions} 112 113 with subtest("Create the NixOS configuration"): 114 machine.succeed("nixos-generate-config --root /mnt") 115 machine.succeed("cat /mnt/etc/nixos/hardware-configuration.nix >&2") 116 machine.copy_from_host( 117 "${ makeConfig { 118 inherit bootLoader grubVersion grubDevice grubIdentifier 119 grubUseEfi extraConfig; 120 } 121 }", 122 "/mnt/etc/nixos/configuration.nix", 123 ) 124 125 with subtest("Perform the installation"): 126 machine.succeed("nixos-install < /dev/null >&2") 127 128 with subtest("Do it again to make sure it's idempotent"): 129 machine.succeed("nixos-install < /dev/null >&2") 130 131 with subtest("Shutdown system after installation"): 132 machine.succeed("umount /mnt/boot || true") 133 machine.succeed("umount /mnt") 134 machine.succeed("sync") 135 machine.shutdown() 136 137 # Now see if we can boot the installation. 138 machine = create_machine_named("boot-after-install") 139 140 # For example to enter LUKS passphrase. 141 ${preBootCommands} 142 143 with subtest("Assert that /boot get mounted"): 144 machine.wait_for_unit("local-fs.target") 145 ${if bootLoader == "grub" 146 then ''machine.succeed("test -e /boot/grub")'' 147 else ''machine.succeed("test -e /boot/loader/loader.conf")'' 148 } 149 150 with subtest("Check whether /root has correct permissions"): 151 assert "700" in machine.succeed("stat -c '%a' /root") 152 153 with subtest("Assert swap device got activated"): 154 # uncomment once https://bugs.freedesktop.org/show_bug.cgi?id=86930 is resolved 155 machine.wait_for_unit("swap.target") 156 machine.succeed("cat /proc/swaps | grep -q /dev") 157 158 with subtest("Check that the store is in good shape"): 159 machine.succeed("nix-store --verify --check-contents >&2") 160 161 with subtest("Check whether the channel works"): 162 machine.succeed("nix-env -iA nixos.procps >&2") 163 assert ".nix-profile" in machine.succeed("type -tP ps | tee /dev/stderr") 164 165 with subtest( 166 "Check that the daemon works, and that non-root users can run builds " 167 "(this will build a new profile generation through the daemon)" 168 ): 169 machine.succeed("su alice -l -c 'nix-env -iA nixos.procps' >&2") 170 171 with subtest("Configure system with writable Nix store on next boot"): 172 # we're not using copy_from_host here because the installer image 173 # doesn't know about the host-guest sharing mechanism. 174 machine.copy_from_host_via_shell( 175 "${ makeConfig { 176 inherit bootLoader grubVersion grubDevice grubIdentifier 177 grubUseEfi extraConfig; 178 forceGrubReinstallCount = 1; 179 } 180 }", 181 "/etc/nixos/configuration.nix", 182 ) 183 184 with subtest("Check whether nixos-rebuild works"): 185 machine.succeed("nixos-rebuild switch >&2") 186 187 # FIXME: Nix 2.4 broke nixos-option, someone has to fix it. 188 # with subtest("Test nixos-option"): 189 # kernel_modules = machine.succeed("nixos-option boot.initrd.kernelModules") 190 # assert "virtio_console" in kernel_modules 191 # assert "List of modules" in kernel_modules 192 # assert "qemu-guest.nix" in kernel_modules 193 194 machine.shutdown() 195 196 # Check whether a writable store build works 197 machine = create_machine_named("rebuild-switch") 198 ${preBootCommands} 199 machine.wait_for_unit("multi-user.target") 200 201 # we're not using copy_from_host here because the installer image 202 # doesn't know about the host-guest sharing mechanism. 203 machine.copy_from_host_via_shell( 204 "${ makeConfig { 205 inherit bootLoader grubVersion grubDevice grubIdentifier 206 grubUseEfi extraConfig; 207 forceGrubReinstallCount = 2; 208 } 209 }", 210 "/etc/nixos/configuration.nix", 211 ) 212 machine.succeed("nixos-rebuild boot >&2") 213 machine.shutdown() 214 215 # And just to be sure, check that the machine still boots after 216 # "nixos-rebuild switch". 217 machine = create_machine_named("boot-after-rebuild-switch") 218 ${preBootCommands} 219 machine.wait_for_unit("network.target") 220 ${postBootCommands} 221 machine.shutdown() 222 223 # Tests for validating clone configuration entries in grub menu 224 '' 225 + optionalString testSpecialisationConfig '' 226 # Reboot Machine 227 machine = create_machine_named("clone-default-config") 228 ${preBootCommands} 229 machine.wait_for_unit("multi-user.target") 230 231 with subtest("Booted configuration name should be 'Home'"): 232 # This is not the name that shows in the grub menu. 233 # The default configuration is always shown as "Default" 234 machine.succeed("cat /run/booted-system/configuration-name >&2") 235 assert "Home" in machine.succeed("cat /run/booted-system/configuration-name") 236 237 with subtest("We should **not** find a file named /etc/gitconfig"): 238 machine.fail("test -e /etc/gitconfig") 239 240 with subtest("Set grub to boot the second configuration"): 241 machine.succeed("grub-reboot 1") 242 243 ${postBootCommands} 244 machine.shutdown() 245 246 # Reboot Machine 247 machine = create_machine_named("clone-alternate-config") 248 ${preBootCommands} 249 250 machine.wait_for_unit("multi-user.target") 251 with subtest("Booted configuration name should be Work"): 252 machine.succeed("cat /run/booted-system/configuration-name >&2") 253 assert "Work" in machine.succeed("cat /run/booted-system/configuration-name") 254 255 with subtest("We should find a file named /etc/gitconfig"): 256 machine.succeed("test -e /etc/gitconfig") 257 258 ${postBootCommands} 259 machine.shutdown() 260 ''; 261 262 263 makeInstallerTest = name: 264 { createPartitions, preBootCommands ? "", postBootCommands ? "", extraConfig ? "" 265 , extraInstallerConfig ? {} 266 , bootLoader ? "grub" # either "grub" or "systemd-boot" 267 , grubVersion ? 2, grubDevice ? "/dev/vda", grubIdentifier ? "uuid", grubUseEfi ? false 268 , enableOCR ? false, meta ? {} 269 , testSpecialisationConfig ? false 270 }: 271 makeTest { 272 inherit enableOCR; 273 name = "installer-" + name; 274 meta = with pkgs.lib.maintainers; { 275 # put global maintainers here, individuals go into makeInstallerTest fkt call 276 maintainers = (meta.maintainers or []); 277 }; 278 nodes = { 279 280 # The configuration of the machine used to run "nixos-install". 281 machine = { pkgs, ... }: { 282 imports = [ 283 ../modules/profiles/installation-device.nix 284 ../modules/profiles/base.nix 285 extraInstallerConfig 286 ]; 287 288 # builds stuff in the VM, needs more juice 289 virtualisation.diskSize = 8 * 1024; 290 virtualisation.cores = 8; 291 virtualisation.memorySize = 3096; 292 293 # Use a small /dev/vdb as the root disk for the 294 # installer. This ensures the target disk (/dev/vda) is 295 # the same during and after installation. 296 virtualisation.emptyDiskImages = [ 512 ]; 297 virtualisation.bootDevice = 298 if grubVersion == 1 then "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive2" else "/dev/vdb"; 299 virtualisation.qemu.diskInterface = 300 if grubVersion == 1 then "scsi" else "virtio"; 301 302 boot.loader.systemd-boot.enable = mkIf (bootLoader == "systemd-boot") true; 303 304 hardware.enableAllFirmware = mkForce false; 305 306 # The test cannot access the network, so any packages we 307 # need must be included in the VM. 308 system.extraDependencies = with pkgs; [ 309 desktop-file-utils 310 docbook5 311 docbook_xsl_ns 312 libxml2.bin 313 libxslt.bin 314 nixos-artwork.wallpapers.simple-dark-gray-bottom 315 ntp 316 perlPackages.ListCompare 317 perlPackages.XMLLibXML 318 shared-mime-info 319 sudo 320 texinfo 321 unionfs-fuse 322 xorg.lndir 323 324 # add curl so that rather than seeing the test attempt to download 325 # curl's tarball, we see what it's trying to download 326 curl 327 ] 328 ++ optional (bootLoader == "grub" && grubVersion == 1) pkgs.grub 329 ++ optionals (bootLoader == "grub" && grubVersion == 2) (let 330 zfsSupport = lib.any (x: x == "zfs") 331 (extraInstallerConfig.boot.supportedFilesystems or []); 332 in [ 333 (pkgs.grub2.override { inherit zfsSupport; }) 334 (pkgs.grub2_efi.override { inherit zfsSupport; }) 335 ]); 336 337 nix.binaryCaches = mkForce [ ]; 338 nix.extraOptions = '' 339 hashed-mirrors = 340 connect-timeout = 1 341 ''; 342 }; 343 344 }; 345 346 testScript = testScriptFun { 347 inherit bootLoader createPartitions preBootCommands postBootCommands 348 grubVersion grubDevice grubIdentifier grubUseEfi extraConfig 349 testSpecialisationConfig; 350 }; 351 }; 352 353 makeLuksRootTest = name: luksFormatOpts: makeInstallerTest name { 354 createPartitions = '' 355 machine.succeed( 356 "flock /dev/vda parted --script /dev/vda -- mklabel msdos" 357 + " mkpart primary ext2 1M 50MB" # /boot 358 + " mkpart primary linux-swap 50M 1024M" 359 + " mkpart primary 1024M -1s", # LUKS 360 "udevadm settle", 361 "mkswap /dev/vda2 -L swap", 362 "swapon -L swap", 363 "modprobe dm_mod dm_crypt", 364 "echo -n supersecret | cryptsetup luksFormat ${luksFormatOpts} -q /dev/vda3 -", 365 "echo -n supersecret | cryptsetup luksOpen --key-file - /dev/vda3 cryptroot", 366 "mkfs.ext3 -L nixos /dev/mapper/cryptroot", 367 "mount LABEL=nixos /mnt", 368 "mkfs.ext3 -L boot /dev/vda1", 369 "mkdir -p /mnt/boot", 370 "mount LABEL=boot /mnt/boot", 371 ) 372 ''; 373 extraConfig = '' 374 boot.kernelParams = lib.mkAfter [ "console=tty0" ]; 375 ''; 376 enableOCR = true; 377 preBootCommands = '' 378 machine.start() 379 machine.wait_for_text("Passphrase for") 380 machine.send_chars("supersecret\n") 381 ''; 382 }; 383 384 # The (almost) simplest partitioning scheme: a swap partition and 385 # one big filesystem partition. 386 simple-test-config = { 387 createPartitions = '' 388 machine.succeed( 389 "flock /dev/vda parted --script /dev/vda -- mklabel msdos" 390 + " mkpart primary linux-swap 1M 1024M" 391 + " mkpart primary ext2 1024M -1s", 392 "udevadm settle", 393 "mkswap /dev/vda1 -L swap", 394 "swapon -L swap", 395 "mkfs.ext3 -L nixos /dev/vda2", 396 "mount LABEL=nixos /mnt", 397 ) 398 ''; 399 }; 400 401 simple-uefi-grub-config = { 402 createPartitions = '' 403 machine.succeed( 404 "flock /dev/vda parted --script /dev/vda -- mklabel gpt" 405 + " mkpart ESP fat32 1M 100MiB" # /boot 406 + " set 1 boot on" 407 + " mkpart primary linux-swap 100MiB 1024MiB" 408 + " mkpart primary ext2 1024MiB -1MiB", # / 409 "udevadm settle", 410 "mkswap /dev/vda2 -L swap", 411 "swapon -L swap", 412 "mkfs.ext3 -L nixos /dev/vda3", 413 "mount LABEL=nixos /mnt", 414 "mkfs.vfat -n BOOT /dev/vda1", 415 "mkdir -p /mnt/boot", 416 "mount LABEL=BOOT /mnt/boot", 417 ) 418 ''; 419 bootLoader = "grub"; 420 grubUseEfi = true; 421 }; 422 423 specialisation-test-extraconfig = { 424 extraConfig = '' 425 environment.systemPackages = [ pkgs.grub2 ]; 426 boot.loader.grub.configurationName = "Home"; 427 specialisation.work.configuration = { 428 boot.loader.grub.configurationName = lib.mkForce "Work"; 429 430 environment.etc = { 431 "gitconfig".text = " 432 [core] 433 gitproxy = none for work.com 434 "; 435 }; 436 }; 437 ''; 438 testSpecialisationConfig = true; 439 }; 440 441 442in { 443 444 # !!! `parted mkpart' seems to silently create overlapping partitions. 445 446 447 # The (almost) simplest partitioning scheme: a swap partition and 448 # one big filesystem partition. 449 simple = makeInstallerTest "simple" simple-test-config; 450 451 # Test cloned configurations with the simple grub configuration 452 simpleSpecialised = makeInstallerTest "simpleSpecialised" (simple-test-config // specialisation-test-extraconfig); 453 454 # Simple GPT/UEFI configuration using systemd-boot with 3 partitions: ESP, swap & root filesystem 455 simpleUefiSystemdBoot = makeInstallerTest "simpleUefiSystemdBoot" { 456 createPartitions = '' 457 machine.succeed( 458 "flock /dev/vda parted --script /dev/vda -- mklabel gpt" 459 + " mkpart ESP fat32 1M 50MiB" # /boot 460 + " set 1 boot on" 461 + " mkpart primary linux-swap 50MiB 1024MiB" 462 + " mkpart primary ext2 1024MiB -1MiB", # / 463 "udevadm settle", 464 "mkswap /dev/vda2 -L swap", 465 "swapon -L swap", 466 "mkfs.ext3 -L nixos /dev/vda3", 467 "mount LABEL=nixos /mnt", 468 "mkfs.vfat -n BOOT /dev/vda1", 469 "mkdir -p /mnt/boot", 470 "mount LABEL=BOOT /mnt/boot", 471 ) 472 ''; 473 bootLoader = "systemd-boot"; 474 }; 475 476 simpleUefiGrub = makeInstallerTest "simpleUefiGrub" simple-uefi-grub-config; 477 478 # Test cloned configurations with the uefi grub configuration 479 simpleUefiGrubSpecialisation = makeInstallerTest "simpleUefiGrubSpecialisation" (simple-uefi-grub-config // specialisation-test-extraconfig); 480 481 # Same as the previous, but now with a separate /boot partition. 482 separateBoot = makeInstallerTest "separateBoot" { 483 createPartitions = '' 484 machine.succeed( 485 "flock /dev/vda parted --script /dev/vda -- mklabel msdos" 486 + " mkpart primary ext2 1M 50MB" # /boot 487 + " mkpart primary linux-swap 50MB 1024M" 488 + " mkpart primary ext2 1024M -1s", # / 489 "udevadm settle", 490 "mkswap /dev/vda2 -L swap", 491 "swapon -L swap", 492 "mkfs.ext3 -L nixos /dev/vda3", 493 "mount LABEL=nixos /mnt", 494 "mkfs.ext3 -L boot /dev/vda1", 495 "mkdir -p /mnt/boot", 496 "mount LABEL=boot /mnt/boot", 497 ) 498 ''; 499 }; 500 501 # Same as the previous, but with fat32 /boot. 502 separateBootFat = makeInstallerTest "separateBootFat" { 503 createPartitions = '' 504 machine.succeed( 505 "flock /dev/vda parted --script /dev/vda -- mklabel msdos" 506 + " mkpart primary ext2 1M 50MB" # /boot 507 + " mkpart primary linux-swap 50MB 1024M" 508 + " mkpart primary ext2 1024M -1s", # / 509 "udevadm settle", 510 "mkswap /dev/vda2 -L swap", 511 "swapon -L swap", 512 "mkfs.ext3 -L nixos /dev/vda3", 513 "mount LABEL=nixos /mnt", 514 "mkfs.vfat -n BOOT /dev/vda1", 515 "mkdir -p /mnt/boot", 516 "mount LABEL=BOOT /mnt/boot", 517 ) 518 ''; 519 }; 520 521 # zfs on / with swap 522 zfsroot = makeInstallerTest "zfs-root" { 523 extraInstallerConfig = { 524 boot.supportedFilesystems = [ "zfs" ]; 525 }; 526 527 extraConfig = '' 528 boot.supportedFilesystems = [ "zfs" ]; 529 530 # Using by-uuid overrides the default of by-id, and is unique 531 # to the qemu disks, as they don't produce by-id paths for 532 # some reason. 533 boot.zfs.devNodes = "/dev/disk/by-uuid/"; 534 networking.hostId = "00000000"; 535 ''; 536 537 createPartitions = '' 538 machine.succeed( 539 "flock /dev/vda parted --script /dev/vda -- mklabel msdos" 540 + " mkpart primary linux-swap 1M 1024M" 541 + " mkpart primary 1024M -1s", 542 "udevadm settle", 543 "mkswap /dev/vda1 -L swap", 544 "swapon -L swap", 545 "zpool create rpool /dev/vda2", 546 "zfs create -o mountpoint=legacy rpool/root", 547 "mount -t zfs rpool/root /mnt", 548 "udevadm settle", 549 ) 550 ''; 551 }; 552 553 # Create two physical LVM partitions combined into one volume group 554 # that contains the logical swap and root partitions. 555 lvm = makeInstallerTest "lvm" { 556 createPartitions = '' 557 machine.succeed( 558 "flock /dev/vda parted --script /dev/vda -- mklabel msdos" 559 + " mkpart primary 1M 2048M" # PV1 560 + " set 1 lvm on" 561 + " mkpart primary 2048M -1s" # PV2 562 + " set 2 lvm on", 563 "udevadm settle", 564 "sleep 1", 565 "pvcreate /dev/vda1 /dev/vda2", 566 "sleep 1", 567 "vgcreate MyVolGroup /dev/vda1 /dev/vda2", 568 "sleep 1", 569 "lvcreate --size 1G --name swap MyVolGroup", 570 "sleep 1", 571 "lvcreate --size 3G --name nixos MyVolGroup", 572 "sleep 1", 573 "mkswap -f /dev/MyVolGroup/swap -L swap", 574 "swapon -L swap", 575 "mkfs.xfs -L nixos /dev/MyVolGroup/nixos", 576 "mount LABEL=nixos /mnt", 577 ) 578 ''; 579 postBootCommands = '' 580 assert "loaded active" in machine.succeed( 581 "systemctl list-units 'lvm2-pvscan@*' -ql --no-legend | tee /dev/stderr" 582 ) 583 ''; 584 }; 585 586 # Boot off an encrypted root partition with the default LUKS header format 587 luksroot = makeLuksRootTest "luksroot-format1" ""; 588 589 # Boot off an encrypted root partition with LUKS1 format 590 luksroot-format1 = makeLuksRootTest "luksroot-format1" "--type=LUKS1"; 591 592 # Boot off an encrypted root partition with LUKS2 format 593 luksroot-format2 = makeLuksRootTest "luksroot-format2" "--type=LUKS2"; 594 595 # Test whether opening encrypted filesystem with keyfile 596 # Checks for regression of missing cryptsetup, when no luks device without 597 # keyfile is configured 598 encryptedFSWithKeyfile = makeInstallerTest "encryptedFSWithKeyfile" { 599 createPartitions = '' 600 machine.succeed( 601 "flock /dev/vda parted --script /dev/vda -- mklabel msdos" 602 + " mkpart primary ext2 1M 50MB" # /boot 603 + " mkpart primary linux-swap 50M 1024M" 604 + " mkpart primary 1024M 1280M" # LUKS with keyfile 605 + " mkpart primary 1280M -1s", 606 "udevadm settle", 607 "mkswap /dev/vda2 -L swap", 608 "swapon -L swap", 609 "mkfs.ext3 -L nixos /dev/vda4", 610 "mount LABEL=nixos /mnt", 611 "mkfs.ext3 -L boot /dev/vda1", 612 "mkdir -p /mnt/boot", 613 "mount LABEL=boot /mnt/boot", 614 "modprobe dm_mod dm_crypt", 615 "echo -n supersecret > /mnt/keyfile", 616 "cryptsetup luksFormat -q /dev/vda3 --key-file /mnt/keyfile", 617 "cryptsetup luksOpen --key-file /mnt/keyfile /dev/vda3 crypt", 618 "mkfs.ext3 -L test /dev/mapper/crypt", 619 "cryptsetup luksClose crypt", 620 "mkdir -p /mnt/test", 621 ) 622 ''; 623 extraConfig = '' 624 fileSystems."/test" = { 625 device = "/dev/disk/by-label/test"; 626 fsType = "ext3"; 627 encrypted.enable = true; 628 encrypted.blkDev = "/dev/vda3"; 629 encrypted.label = "crypt"; 630 encrypted.keyFile = "/mnt-root/keyfile"; 631 }; 632 ''; 633 }; 634 635 swraid = makeInstallerTest "swraid" { 636 createPartitions = '' 637 machine.succeed( 638 "flock /dev/vda parted --script /dev/vda --" 639 + " mklabel msdos" 640 + " mkpart primary ext2 1M 100MB" # /boot 641 + " mkpart extended 100M -1s" 642 + " mkpart logical 102M 3102M" # md0 (root), first device 643 + " mkpart logical 3103M 6103M" # md0 (root), second device 644 + " mkpart logical 6104M 6360M" # md1 (swap), first device 645 + " mkpart logical 6361M 6617M", # md1 (swap), second device 646 "udevadm settle", 647 "ls -l /dev/vda* >&2", 648 "cat /proc/partitions >&2", 649 "udevadm control --stop-exec-queue", 650 "mdadm --create --force /dev/md0 --metadata 1.2 --level=raid1 " 651 + "--raid-devices=2 /dev/vda5 /dev/vda6", 652 "mdadm --create --force /dev/md1 --metadata 1.2 --level=raid1 " 653 + "--raid-devices=2 /dev/vda7 /dev/vda8", 654 "udevadm control --start-exec-queue", 655 "udevadm settle", 656 "mkswap -f /dev/md1 -L swap", 657 "swapon -L swap", 658 "mkfs.ext3 -L nixos /dev/md0", 659 "mount LABEL=nixos /mnt", 660 "mkfs.ext3 -L boot /dev/vda1", 661 "mkdir /mnt/boot", 662 "mount LABEL=boot /mnt/boot", 663 "udevadm settle", 664 ) 665 ''; 666 preBootCommands = '' 667 machine.start() 668 machine.fail("dmesg | grep 'immediate safe mode'") 669 ''; 670 }; 671 672 bcache = makeInstallerTest "bcache" { 673 createPartitions = '' 674 machine.succeed( 675 "flock /dev/vda parted --script /dev/vda --" 676 + " mklabel msdos" 677 + " mkpart primary ext2 1M 50MB" # /boot 678 + " mkpart primary 50MB 512MB " # swap 679 + " mkpart primary 512MB 1024MB" # Cache (typically SSD) 680 + " mkpart primary 1024MB -1s ", # Backing device (typically HDD) 681 "modprobe bcache", 682 "udevadm settle", 683 "make-bcache -B /dev/vda4 -C /dev/vda3", 684 "echo /dev/vda3 > /sys/fs/bcache/register", 685 "echo /dev/vda4 > /sys/fs/bcache/register", 686 "udevadm settle", 687 "mkfs.ext3 -L nixos /dev/bcache0", 688 "mount LABEL=nixos /mnt", 689 "mkfs.ext3 -L boot /dev/vda1", 690 "mkdir /mnt/boot", 691 "mount LABEL=boot /mnt/boot", 692 "mkswap -f /dev/vda2 -L swap", 693 "swapon -L swap", 694 ) 695 ''; 696 }; 697 698 # Test a basic install using GRUB 1. 699 grub1 = makeInstallerTest "grub1" rec { 700 createPartitions = '' 701 machine.succeed( 702 "flock ${grubDevice} parted --script ${grubDevice} -- mklabel msdos" 703 + " mkpart primary linux-swap 1M 1024M" 704 + " mkpart primary ext2 1024M -1s", 705 "udevadm settle", 706 "mkswap ${grubDevice}-part1 -L swap", 707 "swapon -L swap", 708 "mkfs.ext3 -L nixos ${grubDevice}-part2", 709 "mount LABEL=nixos /mnt", 710 "mkdir -p /mnt/tmp", 711 ) 712 ''; 713 grubVersion = 1; 714 # /dev/sda is not stable, even when the SCSI disk number is. 715 grubDevice = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive1"; 716 }; 717 718 # Test using labels to identify volumes in grub 719 simpleLabels = makeInstallerTest "simpleLabels" { 720 createPartitions = '' 721 machine.succeed( 722 "sgdisk -Z /dev/vda", 723 "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", 724 "mkswap /dev/vda2 -L swap", 725 "swapon -L swap", 726 "mkfs.ext4 -L root /dev/vda3", 727 "mount LABEL=root /mnt", 728 ) 729 ''; 730 grubIdentifier = "label"; 731 }; 732 733 # Test using the provided disk name within grub 734 # TODO: Fix udev so the symlinks are unneeded in /dev/disks 735 simpleProvided = makeInstallerTest "simpleProvided" { 736 createPartitions = '' 737 uuid = "$(blkid -s UUID -o value /dev/vda2)" 738 machine.succeed( 739 "sgdisk -Z /dev/vda", 740 "sgdisk -n 1:0:+1M -n 2:0:+100M -n 3:0:+1G -N 4 -t 1:ef02 -t 2:8300 " 741 + "-t 3:8200 -t 4:8300 -c 2:boot -c 4:root /dev/vda", 742 "mkswap /dev/vda3 -L swap", 743 "swapon -L swap", 744 "mkfs.ext4 -L boot /dev/vda2", 745 "mkfs.ext4 -L root /dev/vda4", 746 ) 747 machine.execute(f"ln -s ../../vda2 /dev/disk/by-uuid/{uuid}") 748 machine.execute("ln -s ../../vda4 /dev/disk/by-label/root") 749 machine.succeed( 750 "mount /dev/disk/by-label/root /mnt", 751 "mkdir /mnt/boot", 752 f"mount /dev/disk/by-uuid/{uuid} /mnt/boot", 753 ) 754 ''; 755 grubIdentifier = "provided"; 756 }; 757 758 # Simple btrfs grub testing 759 btrfsSimple = makeInstallerTest "btrfsSimple" { 760 createPartitions = '' 761 machine.succeed( 762 "sgdisk -Z /dev/vda", 763 "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", 764 "mkswap /dev/vda2 -L swap", 765 "swapon -L swap", 766 "mkfs.btrfs -L root /dev/vda3", 767 "mount LABEL=root /mnt", 768 ) 769 ''; 770 }; 771 772 # Test to see if we can detect /boot and /nix on subvolumes 773 btrfsSubvols = makeInstallerTest "btrfsSubvols" { 774 createPartitions = '' 775 machine.succeed( 776 "sgdisk -Z /dev/vda", 777 "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", 778 "mkswap /dev/vda2 -L swap", 779 "swapon -L swap", 780 "mkfs.btrfs -L root /dev/vda3", 781 "btrfs device scan", 782 "mount LABEL=root /mnt", 783 "btrfs subvol create /mnt/boot", 784 "btrfs subvol create /mnt/nixos", 785 "btrfs subvol create /mnt/nixos/default", 786 "umount /mnt", 787 "mount -o defaults,subvol=nixos/default LABEL=root /mnt", 788 "mkdir /mnt/boot", 789 "mount -o defaults,subvol=boot LABEL=root /mnt/boot", 790 ) 791 ''; 792 }; 793 794 # Test to see if we can detect default and aux subvolumes correctly 795 btrfsSubvolDefault = makeInstallerTest "btrfsSubvolDefault" { 796 createPartitions = '' 797 machine.succeed( 798 "sgdisk -Z /dev/vda", 799 "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", 800 "mkswap /dev/vda2 -L swap", 801 "swapon -L swap", 802 "mkfs.btrfs -L root /dev/vda3", 803 "btrfs device scan", 804 "mount LABEL=root /mnt", 805 "btrfs subvol create /mnt/badpath", 806 "btrfs subvol create /mnt/badpath/boot", 807 "btrfs subvol create /mnt/nixos", 808 "btrfs subvol set-default " 809 + "$(btrfs subvol list /mnt | grep 'nixos' | awk '{print $2}') /mnt", 810 "umount /mnt", 811 "mount -o defaults LABEL=root /mnt", 812 "mkdir -p /mnt/badpath/boot", # Help ensure the detection mechanism 813 # is actually looking up subvolumes 814 "mkdir /mnt/boot", 815 "mount -o defaults,subvol=badpath/boot LABEL=root /mnt/boot", 816 ) 817 ''; 818 }; 819}