diff options
Diffstat (limited to 'nixos/tests/installer.nix')
-rw-r--r-- | nixos/tests/installer.nix | 342 |
1 files changed, 258 insertions, 84 deletions
diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index b2e1abc26eec..7da02d9c204a 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -1,13 +1,12 @@ { system ? builtins.currentSystem }: with import ../lib/testing.nix { inherit system; }; -with import ../lib/qemu-flags.nix; with pkgs.lib; let # The configuration to install. - makeConfig = { grubVersion, grubDevice, grubIdentifier + makeConfig = { bootLoader, grubVersion, grubDevice, grubIdentifier, grubUseEfi , extraConfig, forceGrubReinstallCount ? 0 }: pkgs.writeText "configuration.nix" '' @@ -18,15 +17,37 @@ let <nixpkgs/nixos/modules/testing/test-instrumentation.nix> ]; - boot.loader.grub.version = ${toString grubVersion}; - ${optionalString (grubVersion == 1) '' - boot.loader.grub.splashImage = null; + # To ensure that we can rebuild the grub configuration on the nixos-rebuild + system.extraDependencies = with pkgs; [ stdenvNoCC ]; + + ${optionalString (bootLoader == "grub") '' + boot.loader.grub.version = ${toString grubVersion}; + ${optionalString (grubVersion == 1) '' + boot.loader.grub.splashImage = null; + ''} + + boot.loader.grub.extraConfig = "serial; terminal_output.serial"; + ${if grubUseEfi then '' + boot.loader.grub.device = "nodev"; + boot.loader.grub.efiSupport = true; + boot.loader.grub.efiInstallAsRemovable = true; # XXX: needed for OVMF? + '' else '' + boot.loader.grub.device = "${grubDevice}"; + boot.loader.grub.fsIdentifier = "${grubIdentifier}"; + ''} + + boot.loader.grub.configurationLimit = 100 + ${toString forceGrubReinstallCount}; ''} - boot.loader.grub.device = "${grubDevice}"; - boot.loader.grub.extraConfig = "serial; terminal_output.serial"; - boot.loader.grub.fsIdentifier = "${grubIdentifier}"; - boot.loader.grub.configurationLimit = 100 + ${toString forceGrubReinstallCount}; + ${optionalString (bootLoader == "systemd-boot") '' + boot.loader.systemd-boot.enable = true; + ''} + + users.extraUsers.alice = { + isNormalUser = true; + home = "/home/alice"; + description = "Alice Foobar"; + }; hardware.enableAllFirmware = lib.mkForce false; @@ -42,23 +63,32 @@ let # disk, and then reboot from the hard disk. It's parameterized with # a test script fragment `createPartitions', which must create # partitions and filesystems. - testScriptFun = { createPartitions, grubVersion, grubDevice + testScriptFun = { bootLoader, createPartitions, grubVersion, grubDevice, grubUseEfi , grubIdentifier, preBootCommands, extraConfig }: let - iface = if grubVersion == 1 then "scsi" else "virtio"; + iface = if grubVersion == 1 then "ide" else "virtio"; + isEfi = bootLoader == "systemd-boot" || (bootLoader == "grub" && grubUseEfi); + + # FIXME don't duplicate the -enable-kvm etc. flags here yet again! qemuFlags = (if system == "x86_64-linux" then "-m 768 " else "-m 512 ") + - (optionalString (system == "x86_64-linux") "-cpu kvm64 "); - hdFlags = ''hda => "vm-state-machine/machine.qcow2", hdaInterface => "${iface}", ''; - in - '' + (optionalString (system == "x86_64-linux") "-cpu kvm64 ") + + (optionalString (system == "aarch64-linux") "-enable-kvm -machine virt,gic-version=host -cpu host "); + + hdFlags = ''hda => "vm-state-machine/machine.qcow2", hdaInterface => "${iface}", '' + + optionalString isEfi (if pkgs.stdenv.isAarch64 + then ''bios => "${pkgs.OVMF.fd}/FV/QEMU_EFI.fd", '' + else ''bios => "${pkgs.OVMF.fd}/FV/OVMF.fd", ''); + in if !isEfi && !(pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) then + throw "Non-EFI boot methods are only supported on i686 / x86_64" + else '' $machine->start; # Make sure that we get a login prompt etc. $machine->succeed("echo hello"); #$machine->waitForUnit('getty@tty2'); - $machine->waitForUnit("rogue"); + #$machine->waitForUnit("rogue"); $machine->waitForUnit("nixos-manual"); # Wait for hard disks to appear in /dev @@ -73,7 +103,7 @@ let $machine->succeed("cat /mnt/etc/nixos/hardware-configuration.nix >&2"); $machine->copyFileFromHost( - "${ makeConfig { inherit grubVersion grubDevice grubIdentifier extraConfig; } }", + "${ makeConfig { inherit bootLoader grubVersion grubDevice grubIdentifier grubUseEfi extraConfig; } }", "/mnt/etc/nixos/configuration.nix"); # Perform the installation. @@ -89,7 +119,7 @@ let $machine->shutdown; # Now see if we can boot the installation. - $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" }); + $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}", name => "boot-after-install" }); # For example to enter LUKS passphrase. ${preBootCommands} @@ -97,24 +127,34 @@ let # Did /boot get mounted? $machine->waitForUnit("local-fs.target"); - $machine->succeed("test -e /boot/grub"); + ${if bootLoader == "grub" then + ''$machine->succeed("test -e /boot/grub");'' + else + ''$machine->succeed("test -e /boot/loader/loader.conf");'' + } # Check whether /root has correct permissions. $machine->succeed("stat -c '%a' /root") =~ /700/ or die; # Did the swap device get activated? # uncomment once https://bugs.freedesktop.org/show_bug.cgi?id=86930 is resolved - #$machine->waitForUnit("swap.target"); - $machine->waitUntilSucceeds("cat /proc/swaps | grep -q /dev"); + $machine->waitForUnit("swap.target"); + $machine->succeed("cat /proc/swaps | grep -q /dev"); + + # Check that the store is in good shape + $machine->succeed("nix-store --verify --check-contents >&2"); # Check whether the channel works. - $machine->succeed("nix-env -i coreutils >&2"); - $machine->succeed("type -tP ls | tee /dev/stderr") =~ /.nix-profile/ + $machine->succeed("nix-env -iA nixos.procps >&2"); + $machine->succeed("type -tP ps | tee /dev/stderr") =~ /.nix-profile/ or die "nix-env failed"; - # We need to a writable nix-store on next boot. + # Check that the daemon works, and that non-root users can run builds (this will build a new profile generation through the daemon) + $machine->succeed("su alice -l -c 'nix-env -iA nixos.procps' >&2"); + + # We need a writable Nix store on next boot. $machine->copyFileFromHost( - "${ makeConfig { inherit grubVersion grubDevice grubIdentifier extraConfig; forceGrubReinstallCount = 1; } }", + "${ makeConfig { inherit bootLoader grubVersion grubDevice grubIdentifier grubUseEfi extraConfig; forceGrubReinstallCount = 1; } }", "/etc/nixos/configuration.nix"); # Check whether nixos-rebuild works. @@ -128,18 +168,18 @@ let $machine->shutdown; # Check whether a writable store build works - $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" }); + $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}", name => "rebuild-switch" }); ${preBootCommands} $machine->waitForUnit("multi-user.target"); $machine->copyFileFromHost( - "${ makeConfig { inherit grubVersion grubDevice grubIdentifier extraConfig; forceGrubReinstallCount = 2; } }", + "${ makeConfig { inherit bootLoader grubVersion grubDevice grubIdentifier grubUseEfi extraConfig; forceGrubReinstallCount = 2; } }", "/etc/nixos/configuration.nix"); $machine->succeed("nixos-rebuild boot >&2"); $machine->shutdown; # And just to be sure, check that the machine still boots after # "nixos-rebuild switch". - $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" }); + $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}", "boot-after-rebuild-switch" }); ${preBootCommands} $machine->waitForUnit("network.target"); $machine->shutdown; @@ -148,8 +188,10 @@ let makeInstallerTest = name: { createPartitions, preBootCommands ? "", extraConfig ? "" - , grubVersion ? 2, grubDevice ? "/dev/vda" - , grubIdentifier ? "uuid", enableOCR ? false, meta ? {} + , extraInstallerConfig ? {} + , bootLoader ? "grub" # either "grub" or "systemd-boot" + , grubVersion ? 2, grubDevice ? "/dev/vda", grubIdentifier ? "uuid", grubUseEfi ? false + , enableOCR ? false, meta ? {} }: makeTest { inherit enableOCR; @@ -160,19 +202,18 @@ let }; nodes = { - # The configuration of the machine used to run "nixos-install". It - # also has a web server that simulates cache.nixos.org. + # The configuration of the machine used to run "nixos-install". machine = { config, lib, pkgs, ... }: { imports = [ ../modules/profiles/installation-device.nix ../modules/profiles/base.nix + extraInstallerConfig ]; virtualisation.diskSize = 8 * 1024; - virtualisation.memorySize = 768; - virtualisation.writableStore = true; + virtualisation.memorySize = 1024; # Use a small /dev/vdb as the root disk for the # installer. This ensures the target disk (/dev/vda) is @@ -183,32 +224,45 @@ let virtualisation.qemu.diskInterface = if grubVersion == 1 then "scsi" else "virtio"; + boot.loader.systemd-boot.enable = mkIf (bootLoader == "systemd-boot") true; + hardware.enableAllFirmware = mkForce false; # The test cannot access the network, so any packages we # need must be included in the VM. - system.extraDependencies = - [ pkgs.sudo - pkgs.docbook5 - pkgs.docbook5_xsl - pkgs.unionfs-fuse - pkgs.ntp - pkgs.nixos-artwork - pkgs.gummiboot - pkgs.perlPackages.XMLLibXML - pkgs.perlPackages.ListCompare + system.extraDependencies = with pkgs; + [ sudo + libxml2.bin + libxslt.bin + docbook5 + docbook5_xsl + unionfs-fuse + ntp + nixos-artwork.wallpapers.gnome-dark + perlPackages.XMLLibXML + perlPackages.ListCompare + xorg.lndir + + # add curl so that rather than seeing the test attempt to download + # curl's tarball, we see what it's trying to download + curl ] - ++ optional (grubVersion == 1) pkgs.grub - ++ optionals (grubVersion == 2) [ pkgs.grub2 pkgs.grub2_efi ]; + ++ optional (bootLoader == "grub" && grubVersion == 1) pkgs.grub + ++ optionals (bootLoader == "grub" && grubVersion == 2) [ pkgs.grub2 pkgs.grub2_efi ]; nix.binaryCaches = mkForce [ ]; + nix.extraOptions = + '' + hashed-mirrors = + connect-timeout = 1 + ''; }; }; testScript = testScriptFun { - inherit createPartitions preBootCommands grubVersion - grubDevice grubIdentifier extraConfig; + inherit bootLoader createPartitions preBootCommands + grubVersion grubDevice grubIdentifier grubUseEfi extraConfig; }; }; @@ -224,9 +278,9 @@ in { { createPartitions = '' $machine->succeed( - "parted /dev/vda mklabel msdos", - "parted /dev/vda -- mkpart primary linux-swap 1M 1024M", - "parted /dev/vda -- mkpart primary ext2 1024M -1s", + "parted --script /dev/vda mklabel msdos", + "parted --script /dev/vda -- mkpart primary linux-swap 1M 1024M", + "parted --script /dev/vda -- mkpart primary ext2 1024M -1s", "udevadm settle", "mkswap /dev/vda1 -L swap", "swapon -L swap", @@ -236,15 +290,61 @@ in { ''; }; + # Simple GPT/UEFI configuration using systemd-boot with 3 partitions: ESP, swap & root filesystem + simpleUefiSystemdBoot = makeInstallerTest "simpleUefiSystemdBoot" + { createPartitions = + '' + $machine->succeed( + "parted --script /dev/vda mklabel gpt", + "parted --script /dev/vda -- mkpart ESP fat32 1M 50MiB", # /boot + "parted --script /dev/vda -- set 1 boot on", + "parted --script /dev/vda -- mkpart primary linux-swap 50MiB 1024MiB", + "parted --script /dev/vda -- mkpart primary ext2 1024MiB -1MiB", # / + "udevadm settle", + "mkswap /dev/vda2 -L swap", + "swapon -L swap", + "mkfs.ext3 -L nixos /dev/vda3", + "mount LABEL=nixos /mnt", + "mkfs.vfat -n BOOT /dev/vda1", + "mkdir -p /mnt/boot", + "mount LABEL=BOOT /mnt/boot", + ); + ''; + bootLoader = "systemd-boot"; + }; + + simpleUefiGrub = makeInstallerTest "simpleUefiGrub" + { createPartitions = + '' + $machine->succeed( + "parted --script /dev/vda mklabel gpt", + "parted --script /dev/vda -- mkpart ESP fat32 1M 50MiB", # /boot + "parted --script /dev/vda -- set 1 boot on", + "parted --script /dev/vda -- mkpart primary linux-swap 50MiB 1024MiB", + "parted --script /dev/vda -- mkpart primary ext2 1024MiB -1MiB", # / + "udevadm settle", + "mkswap /dev/vda2 -L swap", + "swapon -L swap", + "mkfs.ext3 -L nixos /dev/vda3", + "mount LABEL=nixos /mnt", + "mkfs.vfat -n BOOT /dev/vda1", + "mkdir -p /mnt/boot", + "mount LABEL=BOOT /mnt/boot", + ); + ''; + bootLoader = "grub"; + grubUseEfi = true; + }; + # Same as the previous, but now with a separate /boot partition. separateBoot = makeInstallerTest "separateBoot" { createPartitions = '' $machine->succeed( - "parted /dev/vda mklabel msdos", - "parted /dev/vda -- mkpart primary ext2 1M 50MB", # /boot - "parted /dev/vda -- mkpart primary linux-swap 50MB 1024M", - "parted /dev/vda -- mkpart primary ext2 1024M -1s", # / + "parted --script /dev/vda mklabel msdos", + "parted --script /dev/vda -- mkpart primary ext2 1M 50MB", # /boot + "parted --script /dev/vda -- mkpart primary linux-swap 50MB 1024M", + "parted --script /dev/vda -- mkpart primary ext2 1024M -1s", # / "udevadm settle", "mkswap /dev/vda2 -L swap", "swapon -L swap", @@ -262,10 +362,10 @@ in { { createPartitions = '' $machine->succeed( - "parted /dev/vda mklabel msdos", - "parted /dev/vda -- mkpart primary ext2 1M 50MB", # /boot - "parted /dev/vda -- mkpart primary linux-swap 50MB 1024M", - "parted /dev/vda -- mkpart primary ext2 1024M -1s", # / + "parted --script /dev/vda mklabel msdos", + "parted --script /dev/vda -- mkpart primary ext2 1M 50MB", # /boot + "parted --script /dev/vda -- mkpart primary linux-swap 50MB 1024M", + "parted --script /dev/vda -- mkpart primary ext2 1024M -1s", # / "udevadm settle", "mkswap /dev/vda2 -L swap", "swapon -L swap", @@ -278,17 +378,54 @@ in { ''; }; + # zfs on / with swap + zfsroot = makeInstallerTest "zfs-root" + { + extraInstallerConfig = { + boot.supportedFilesystems = [ "zfs" ]; + }; + + extraConfig = '' + boot.supportedFilesystems = [ "zfs" ]; + + # Using by-uuid overrides the default of by-id, and is unique + # to the qemu disks, as they don't produce by-id paths for + # some reason. + boot.zfs.devNodes = "/dev/disk/by-uuid/"; + networking.hostId = "00000000"; + ''; + + createPartitions = + '' + $machine->succeed( + "parted --script /dev/vda mklabel msdos", + "parted --script /dev/vda -- mkpart primary linux-swap 1M 1024M", + "parted --script /dev/vda -- mkpart primary 1024M -1s", + "udevadm settle", + + "mkswap /dev/vda1 -L swap", + "swapon -L swap", + + "zpool create rpool /dev/vda2", + "zfs create -o mountpoint=legacy rpool/root", + "mount -t zfs rpool/root /mnt", + + "udevadm settle" + ); + ''; + }; + # Create two physical LVM partitions combined into one volume group # that contains the logical swap and root partitions. lvm = makeInstallerTest "lvm" { createPartitions = '' $machine->succeed( - "parted /dev/vda mklabel msdos", - "parted /dev/vda -- mkpart primary 1M 2048M", # PV1 - "parted /dev/vda -- set 1 lvm on", - "parted /dev/vda -- mkpart primary 2048M -1s", # PV2 - "parted /dev/vda -- set 2 lvm on", + "parted --script /dev/vda mklabel msdos", + "parted --script /dev/vda -- mkpart primary 1M 2048M", # PV1 + "parted --script /dev/vda -- set 1 lvm on", + "parted --script /dev/vda -- mkpart primary 2048M -1s", # PV2 + "parted --script /dev/vda -- set 2 lvm on", "udevadm settle", "pvcreate /dev/vda1 /dev/vda2", "vgcreate MyVolGroup /dev/vda1 /dev/vda2", @@ -306,10 +443,10 @@ in { luksroot = makeInstallerTest "luksroot" { createPartitions = '' $machine->succeed( - "parted /dev/vda mklabel msdos", - "parted /dev/vda -- mkpart primary ext2 1M 50MB", # /boot - "parted /dev/vda -- mkpart primary linux-swap 50M 1024M", - "parted /dev/vda -- mkpart primary 1024M -1s", # LUKS + "parted --script /dev/vda mklabel msdos", + "parted --script /dev/vda -- mkpart primary ext2 1M 50MB", # /boot + "parted --script /dev/vda -- mkpart primary linux-swap 50M 1024M", + "parted --script /dev/vda -- mkpart primary 1024M -1s", # LUKS "udevadm settle", "mkswap /dev/vda2 -L swap", "swapon -L swap", @@ -323,14 +460,8 @@ in { "mount LABEL=boot /mnt/boot", ); ''; - # XXX: Currently, generate-config doesn't detect LUKS yet. extraConfig = '' boot.kernelParams = lib.mkAfter [ "console=tty0" ]; - boot.initrd.luks.devices = lib.singleton { - name = "cryptroot"; - device = "/dev/vda3"; - preLVM = true; - }; ''; enableOCR = true; preBootCommands = '' @@ -340,18 +471,59 @@ in { ''; }; + # Test whether opening encrypted filesystem with keyfile + # Checks for regression of missing cryptsetup, when no luks device without + # keyfile is configured + filesystemEncryptedWithKeyfile = makeInstallerTest "filesystemEncryptedWithKeyfile" + { createPartitions = '' + $machine->succeed( + "parted --script /dev/vda mklabel msdos", + "parted --script /dev/vda -- mkpart primary ext2 1M 50MB", # /boot + "parted --script /dev/vda -- mkpart primary linux-swap 50M 1024M", + "parted --script /dev/vda -- mkpart primary 1024M 1280M", # LUKS with keyfile + "parted --script /dev/vda -- mkpart primary 1280M -1s", + "udevadm settle", + "mkswap /dev/vda2 -L swap", + "swapon -L swap", + "mkfs.ext3 -L nixos /dev/vda4", + "mount LABEL=nixos /mnt", + "mkfs.ext3 -L boot /dev/vda1", + "mkdir -p /mnt/boot", + "mount LABEL=boot /mnt/boot", + "modprobe dm_mod dm_crypt", + "echo -n supersecret > /mnt/keyfile", + "cryptsetup luksFormat -q /dev/vda3 --key-file /mnt/keyfile", + "cryptsetup luksOpen --key-file /mnt/keyfile /dev/vda3 crypt", + "mkfs.ext3 -L test /dev/mapper/crypt", + "cryptsetup luksClose crypt", + "mkdir -p /mnt/test" + ); + ''; + extraConfig = '' + fileSystems."/test" = + { device = "/dev/disk/by-label/test"; + fsType = "ext3"; + encrypted.enable = true; + encrypted.blkDev = "/dev/vda3"; + encrypted.label = "crypt"; + encrypted.keyFile = "/mnt-root/keyfile"; + }; + ''; + }; + + swraid = makeInstallerTest "swraid" { createPartitions = '' $machine->succeed( - "parted /dev/vda --" + "parted --script /dev/vda --" . " mklabel msdos" . " mkpart primary ext2 1M 100MB" # /boot . " mkpart extended 100M -1s" - . " mkpart logical 102M 1602M" # md0 (root), first device - . " mkpart logical 1603M 3103M" # md0 (root), second device - . " mkpart logical 3104M 3360M" # md1 (swap), first device - . " mkpart logical 3361M 3617M", # md1 (swap), second device + . " mkpart logical 102M 2102M" # md0 (root), first device + . " mkpart logical 2103M 4103M" # md0 (root), second device + . " mkpart logical 4104M 4360M" # md1 (swap), first device + . " mkpart logical 4361M 4617M", # md1 (swap), second device "udevadm settle", "ls -l /dev/vda* >&2", "cat /proc/partitions >&2", @@ -366,10 +538,12 @@ in { "mkdir /mnt/boot", "mount LABEL=boot /mnt/boot", "udevadm settle", - "mdadm -W /dev/md0", # wait for sync to finish; booting off an unsynced device tends to fail - "mdadm -W /dev/md1", ); ''; + preBootCommands = '' + $machine->start; + $machine->fail("dmesg | grep 'immediate safe mode'"); + ''; }; # Test a basic install using GRUB 1. @@ -377,9 +551,9 @@ in { { createPartitions = '' $machine->succeed( - "parted /dev/sda mklabel msdos", - "parted /dev/sda -- mkpart primary linux-swap 1M 1024M", - "parted /dev/sda -- mkpart primary ext2 1024M -1s", + "parted --script /dev/sda mklabel msdos", + "parted --script /dev/sda -- mkpart primary linux-swap 1M 1024M", + "parted --script /dev/sda -- mkpart primary ext2 1024M -1s", "udevadm settle", "mkswap /dev/sda1 -L swap", "swapon -L swap", |