nixpkgs/nixos/tests/systemd-boot.nix
Bjørn Forsman 39fad297fd nixos: fix "nixos-rebuild build-vm-with-bootloader" for EFI systems
`nixos-rebuild build-vm-with-bootloader` currently fails with the
default NixOS EFI configuration:

  $ cat >configuration.nix <<EOF
  {
    fileSystems."/".device = "/dev/sda1";
    boot.loader.systemd-boot.enable = true;
    boot.loader.efi.canTouchEfiVariables = true;
  }
  EOF

  $ nixos-rebuild build-vm-with-bootloader -I nixos-config=$PWD/configuration.nix -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixos-20.09.tar.gz
  [...]
  insmod: ERROR: could not insert module /nix/store/1ibmgfr13r8b6xyn4f0wj115819f359c-linux-5.4.83/lib/modules/5.4.83/kernel/fs/efivarfs/efivarfs.ko.xz: No such device
  mount: /sys/firmware/efi/efivars: mount point does not exist.
  [    1.908328] reboot: Power down
  builder for '/nix/store/dx2ycclyknvibrskwmii42sgyalagjxa-nixos-boot-disk.drv' failed with exit code 32
  [...]

Fix it by setting virtualisation.useEFIBoot = true in qemu-vm.nix, when
efi is needed.

And remove the now unneeded configuration in
./nixos/tests/systemd-boot.nix, since it's handled globally.

Before:
* release-20.03: successful build, unsuccessful run
* release-20.09 (and master): unsuccessful build

After:
* Successful build and run.

Fixes https://github.com/NixOS/nixpkgs/issues/107255
2020-12-21 08:55:13 +01:00

90 lines
2.7 KiB
Nix

{ system ? builtins.currentSystem,
config ? {},
pkgs ? import ../.. { inherit system config; }
}:
with import ../lib/testing-python.nix { inherit system pkgs; };
with pkgs.lib;
let
common = {
virtualisation.useBootLoader = true;
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
environment.systemPackages = [ pkgs.efibootmgr ];
};
in
{
basic = makeTest {
name = "systemd-boot";
meta.maintainers = with pkgs.stdenv.lib.maintainers; [ danielfullmer ];
machine = common;
testScript = ''
machine.start()
machine.wait_for_unit("multi-user.target")
machine.succeed("test -e /boot/loader/entries/nixos-generation-1.conf")
# Ensure we actually booted using systemd-boot
# Magic number is the vendor UUID used by systemd-boot.
machine.succeed(
"test -e /sys/firmware/efi/efivars/LoaderEntrySelected-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"
)
# "bootctl install" should have created an EFI entry
machine.succeed('efibootmgr | grep "Linux Boot Manager"')
'';
};
# Boot without having created an EFI entry--instead using default "/EFI/BOOT/BOOTX64.EFI"
fallback = makeTest {
name = "systemd-boot-fallback";
meta.maintainers = with pkgs.stdenv.lib.maintainers; [ danielfullmer ];
machine = { pkgs, lib, ... }: {
imports = [ common ];
boot.loader.efi.canTouchEfiVariables = mkForce false;
};
testScript = ''
machine.start()
machine.wait_for_unit("multi-user.target")
machine.succeed("test -e /boot/loader/entries/nixos-generation-1.conf")
# Ensure we actually booted using systemd-boot
# Magic number is the vendor UUID used by systemd-boot.
machine.succeed(
"test -e /sys/firmware/efi/efivars/LoaderEntrySelected-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"
)
# "bootctl install" should _not_ have created an EFI entry
machine.fail('efibootmgr | grep "Linux Boot Manager"')
'';
};
update = makeTest {
name = "systemd-boot-update";
meta.maintainers = with pkgs.stdenv.lib.maintainers; [ danielfullmer ];
machine = common;
testScript = ''
machine.succeed("mount -o remount,rw /boot")
# Replace version inside sd-boot with something older. See magic[] string in systemd src/boot/efi/boot.c
machine.succeed(
"""
find /boot -iname '*.efi' -print0 | \
xargs -0 -I '{}' sed -i 's/#### LoaderInfo: systemd-boot .* ####/#### LoaderInfo: systemd-boot 001 ####/' '{}'
"""
)
output = machine.succeed("/run/current-system/bin/switch-to-configuration boot")
assert "updating systemd-boot from 001 to " in output
'';
};
}