Something went wrong. Try again.
What happens if I push all of nixpkgs
Something went wrong. Try again.
Nix
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602{ 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; virtualisation.useEFIBoot = true; boot.loader.systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true; environment.systemPackages = [ pkgs.efibootmgr ]; system.switch.enable = true; };
commonXbootldr = { config, lib, pkgs, ... }: let diskImage = import ../lib/make-disk-image.nix { inherit config lib pkgs; label = "nixos"; format = "qcow2"; partitionTableType = "efixbootldr"; touchEFIVars = true; installBootLoader = true; }; in { imports = [ common ]; virtualisation.useBootLoader = lib.mkForce false; # Only way to tell qemu-vm not to create the default system image virtualisation.directBoot.enable = false; # But don't direct boot either because we're testing systemd-boot
system.build.diskImage = diskImage; # Use custom disk image with an XBOOTLDR partition virtualisation.efi.variables = "${diskImage}/efi-vars.fd";
virtualisation.useDefaultFilesystems = false; # Needs custom setup for `diskImage` virtualisation.bootPartition = null; virtualisation.fileSystems = { "/" = { device = "/dev/vda3"; fsType = "ext4"; }; "/boot" = { device = "/dev/vda2"; fsType = "vfat"; noCheck = true; }; "/efi" = { device = "/dev/vda1"; fsType = "vfat"; noCheck = true; }; };
boot.loader.systemd-boot.enable = true; boot.loader.efi.efiSysMountPoint = "/efi"; boot.loader.systemd-boot.xbootldrMountPoint = "/boot"; };
customDiskImage = nodes: '' import os import subprocess import tempfile
tmp_disk_image = tempfile.NamedTemporaryFile()
subprocess.run([ "${nodes.machine.virtualisation.qemu.package}/bin/qemu-img", "create", "-f", "qcow2", "-b", "${nodes.machine.system.build.diskImage}/nixos.qcow2", "-F", "qcow2", tmp_disk_image.name, ])
# Set NIX_DISK_IMAGE so that the qemu script finds the right disk image. os.environ['NIX_DISK_IMAGE'] = tmp_disk_image.name '';in{ basic = makeTest { name = "systemd-boot"; meta.maintainers = with pkgs.lib.maintainers; [ danielfullmer julienmalka ];
nodes.machine = common;
testScript = '' machine.start() machine.wait_for_unit("multi-user.target")
machine.succeed("test -e /boot/loader/entries/nixos-generation-1.conf") machine.succeed("grep 'sort-key nixos' /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"') ''; };
# Test that systemd-boot works with secure boot secureBoot = makeTest { name = "systemd-boot-secure-boot";
nodes.machine = { imports = [ common ]; environment.systemPackages = [ pkgs.sbctl ]; virtualisation.useSecureBoot = true; };
testScript = let efiArch = pkgs.stdenv.hostPlatform.efiArch; in { nodes, ... }: '' machine.start(allow_reboot=True) machine.wait_for_unit("multi-user.target")
machine.succeed("sbctl create-keys") machine.succeed("sbctl enroll-keys --yes-this-might-brick-my-machine") machine.succeed('sbctl sign /boot/EFI/systemd/systemd-boot${efiArch}.efi') machine.succeed('sbctl sign /boot/EFI/BOOT/BOOT${toUpper efiArch}.EFI') machine.succeed('sbctl sign /boot/EFI/nixos/*${nodes.machine.system.boot.loader.kernelFile}.efi')
machine.reboot()
assert "Secure Boot: enabled (user)" in machine.succeed("bootctl status") ''; };
basicXbootldr = makeTest { name = "systemd-boot-xbootldr"; meta.maintainers = with pkgs.lib.maintainers; [ sdht0 ];
nodes.machine = commonXbootldr;
testScript = { nodes, ... }: '' ${customDiskImage nodes}
machine.start() machine.wait_for_unit("multi-user.target")
machine.succeed("test -e /efi/EFI/systemd/systemd-bootx64.efi") 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"') ''; };
# Check that specialisations create corresponding boot entries. specialisation = makeTest { name = "systemd-boot-specialisation"; meta.maintainers = with pkgs.lib.maintainers; [ lukegb julienmalka ];
nodes.machine = { pkgs, lib, ... }: { imports = [ common ]; specialisation.something.configuration = { boot.loader.systemd-boot.sortKey = "something";
# Since qemu will dynamically create a devicetree blob when starting # up, it is not straight forward to create an export of that devicetree # blob without knowing before-hand all the flags we would pass to qemu # (we would then be able to use `dumpdtb`). Thus, the following config # will not boot, but it does allow us to assert that the boot entry has # the correct contents. boot.loader.systemd-boot.installDeviceTree = pkgs.stdenv.hostPlatform.isAarch64; hardware.deviceTree.name = "dummy.dtb"; hardware.deviceTree.package = lib.mkForce ( pkgs.runCommand "dummy-devicetree-package" { } '' mkdir -p $out cp ${pkgs.emptyFile} $out/dummy.dtb '' ); }; };
testScript = { nodes, ... }: '' machine.start() machine.wait_for_unit("multi-user.target")
machine.succeed( "test -e /boot/loader/entries/nixos-generation-1-specialisation-something.conf" ) machine.succeed( "grep -q 'title NixOS (something)' /boot/loader/entries/nixos-generation-1-specialisation-something.conf" ) machine.succeed( "grep 'sort-key something' /boot/loader/entries/nixos-generation-1-specialisation-something.conf" ) '' + pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isAarch64 '' machine.succeed( r"grep 'devicetree /EFI/nixos/[a-z0-9]\{32\}.*dummy' /boot/loader/entries/nixos-generation-1-specialisation-something.conf" ) ''; };
# Boot without having created an EFI entry--instead using default "/EFI/BOOT/BOOTX64.EFI" fallback = makeTest { name = "systemd-boot-fallback"; meta.maintainers = with pkgs.lib.maintainers; [ danielfullmer julienmalka ];
nodes.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.lib.maintainers; [ danielfullmer julienmalka ];
nodes.machine = common;
testScript = '' machine.succeed("mount -o remount,rw /boot")
def switch(): # Replace version inside sd-boot with something older. See magic[] string in systemd src/boot/efi/boot.c machine.succeed( """ find /boot -iname '*boot*.efi' -print0 | \ xargs -0 -I '{}' sed -i 's/#### LoaderInfo: systemd-boot .* ####/#### LoaderInfo: systemd-boot 000.0-1-notnixos ####/' '{}' """ ) return machine.succeed("/run/current-system/bin/switch-to-configuration boot 2>&1")
output = switch() assert "updating systemd-boot from 000.0-1-notnixos to " in output, "Couldn't find systemd-boot update message" assert 'to "/boot/EFI/systemd/systemd-bootx64.efi"' in output, "systemd-boot not copied to to /boot/EFI/systemd/systemd-bootx64.efi" assert 'to "/boot/EFI/BOOT/BOOTX64.EFI"' in output, "systemd-boot not copied to to /boot/EFI/BOOT/BOOTX64.EFI"
with subtest("Test that updating works with lowercase bootx64.efi"): machine.succeed( # Move to tmp file name first, otherwise mv complains the new location is the same "mv /boot/EFI/BOOT/BOOTX64.EFI /boot/EFI/BOOT/bootx64.efi.new", "mv /boot/EFI/BOOT/bootx64.efi.new /boot/EFI/BOOT/bootx64.efi", ) output = switch() assert "updating systemd-boot from 000.0-1-notnixos to " in output, "Couldn't find systemd-boot update message" assert 'to "/boot/EFI/systemd/systemd-bootx64.efi"' in output, "systemd-boot not copied to to /boot/EFI/systemd/systemd-bootx64.efi" assert 'to "/boot/EFI/BOOT/BOOTX64.EFI"' in output, "systemd-boot not copied to to /boot/EFI/BOOT/BOOTX64.EFI" ''; };
memtest86 = with pkgs.lib; optionalAttrs (meta.availableOn { inherit system; } pkgs.memtest86plus) (makeTest { name = "systemd-boot-memtest86"; meta.maintainers = with maintainers; [ julienmalka ];
nodes.machine = { pkgs, lib, ... }: { imports = [ common ]; boot.loader.systemd-boot.memtest86.enable = true; };
testScript = '' machine.succeed("test -e /boot/loader/entries/memtest86.conf") machine.succeed("test -e /boot/efi/memtest86/memtest.efi") ''; });
netbootxyz = makeTest { name = "systemd-boot-netbootxyz"; meta.maintainers = with pkgs.lib.maintainers; [ julienmalka ];
nodes.machine = { pkgs, lib, ... }: { imports = [ common ]; boot.loader.systemd-boot.netbootxyz.enable = true; };
testScript = '' machine.succeed("test -e /boot/loader/entries/netbootxyz.conf") machine.succeed("test -e /boot/efi/netbootxyz/netboot.xyz.efi") ''; };
edk2-uefi-shell = makeTest { name = "systemd-boot-edk2-uefi-shell"; meta.maintainers = with pkgs.lib.maintainers; [ iFreilicht ];
nodes.machine = { ... }: { imports = [ common ]; boot.loader.systemd-boot.edk2-uefi-shell.enable = true; };
testScript = '' machine.succeed("test -e /boot/loader/entries/edk2-uefi-shell.conf") machine.succeed("test -e /boot/efi/edk2-uefi-shell/shell.efi") ''; };
windows = makeTest { name = "systemd-boot-windows"; meta.maintainers = with pkgs.lib.maintainers; [ iFreilicht ];
nodes.machine = { ... }: { imports = [ common ]; boot.loader.systemd-boot.windows = { "7" = { efiDeviceHandle = "HD0c1"; sortKey = "before_all_others"; }; "Ten".efiDeviceHandle = "FS0"; "11" = { title = "Title with-_-punctuation ...?!"; efiDeviceHandle = "HD0d4"; sortKey = "zzz"; }; }; };
testScript = '' machine.succeed("test -e /boot/efi/edk2-uefi-shell/shell.efi")
machine.succeed("test -e /boot/loader/entries/windows_7.conf") machine.succeed("test -e /boot/loader/entries/windows_Ten.conf") machine.succeed("test -e /boot/loader/entries/windows_11.conf")
machine.succeed("grep 'efi /efi/edk2-uefi-shell/shell.efi' /boot/loader/entries/windows_7.conf") machine.succeed("grep 'efi /efi/edk2-uefi-shell/shell.efi' /boot/loader/entries/windows_Ten.conf") machine.succeed("grep 'efi /efi/edk2-uefi-shell/shell.efi' /boot/loader/entries/windows_11.conf")
machine.succeed("grep 'HD0c1:EFI\\\\Microsoft\\\\Boot\\\\Bootmgfw.efi' /boot/loader/entries/windows_7.conf") machine.succeed("grep 'FS0:EFI\\\\Microsoft\\\\Boot\\\\Bootmgfw.efi' /boot/loader/entries/windows_Ten.conf") machine.succeed("grep 'HD0d4:EFI\\\\Microsoft\\\\Boot\\\\Bootmgfw.efi' /boot/loader/entries/windows_11.conf")
machine.succeed("grep 'sort-key before_all_others' /boot/loader/entries/windows_7.conf") machine.succeed("grep 'sort-key o_windows_Ten' /boot/loader/entries/windows_Ten.conf") machine.succeed("grep 'sort-key zzz' /boot/loader/entries/windows_11.conf")
machine.succeed("grep 'title Windows 7' /boot/loader/entries/windows_7.conf") machine.succeed("grep 'title Windows Ten' /boot/loader/entries/windows_Ten.conf") machine.succeed('grep "title Title with-_-punctuation ...?!" /boot/loader/entries/windows_11.conf') ''; };
memtestSortKey = makeTest { name = "systemd-boot-memtest-sortkey"; meta.maintainers = with pkgs.lib.maintainers; [ julienmalka ];
nodes.machine = { pkgs, lib, ... }: { imports = [ common ]; boot.loader.systemd-boot.memtest86.enable = true; boot.loader.systemd-boot.memtest86.sortKey = "apple"; };
testScript = '' machine.succeed("test -e /boot/loader/entries/memtest86.conf") machine.succeed("test -e /boot/efi/memtest86/memtest.efi") machine.succeed("grep 'sort-key apple' /boot/loader/entries/memtest86.conf") ''; };
entryFilenameXbootldr = makeTest { name = "systemd-boot-entry-filename-xbootldr"; meta.maintainers = with pkgs.lib.maintainers; [ sdht0 ];
nodes.machine = { pkgs, lib, ... }: { imports = [ commonXbootldr ]; boot.loader.systemd-boot.memtest86.enable = true; };
testScript = { nodes, ... }: '' ${customDiskImage nodes}
machine.start() machine.wait_for_unit("multi-user.target")
machine.succeed("test -e /efi/EFI/systemd/systemd-bootx64.efi") machine.succeed("test -e /boot/loader/entries/memtest86.conf") machine.succeed("test -e /boot/EFI/memtest86/memtest.efi") ''; };
extraEntries = makeTest { name = "systemd-boot-extra-entries"; meta.maintainers = with pkgs.lib.maintainers; [ julienmalka ];
nodes.machine = { pkgs, lib, ... }: { imports = [ common ]; boot.loader.systemd-boot.extraEntries = { "banana.conf" = '' title banana ''; }; };
testScript = '' machine.succeed("test -e /boot/loader/entries/banana.conf") machine.succeed("test -e /boot/efi/nixos/.extra-files/loader/entries/banana.conf") ''; };
extraFiles = makeTest { name = "systemd-boot-extra-files"; meta.maintainers = with pkgs.lib.maintainers; [ julienmalka ];
nodes.machine = { pkgs, lib, ... }: { imports = [ common ]; boot.loader.systemd-boot.extraFiles = { "efi/fruits/tomato.efi" = pkgs.netbootxyz-efi; }; };
testScript = '' machine.succeed("test -e /boot/efi/fruits/tomato.efi") machine.succeed("test -e /boot/efi/nixos/.extra-files/efi/fruits/tomato.efi") ''; };
switch-test = makeTest { name = "systemd-boot-switch-test"; meta.maintainers = with pkgs.lib.maintainers; [ julienmalka ];
nodes = { inherit common;
machine = { pkgs, nodes, ... }: { imports = [ common ]; boot.loader.systemd-boot.extraFiles = { "efi/fruits/tomato.efi" = pkgs.netbootxyz-efi; };
# These are configs for different nodes, but we'll use them here in `machine` system.extraDependencies = [ nodes.common.system.build.toplevel nodes.with_netbootxyz.system.build.toplevel ]; };
with_netbootxyz = { pkgs, ... }: { imports = [ common ]; boot.loader.systemd-boot.netbootxyz.enable = true; }; };
testScript = { nodes, ... }: let originalSystem = nodes.machine.system.build.toplevel; baseSystem = nodes.common.system.build.toplevel; finalSystem = nodes.with_netbootxyz.system.build.toplevel; in '' machine.succeed("test -e /boot/efi/fruits/tomato.efi") machine.succeed("test -e /boot/efi/nixos/.extra-files/efi/fruits/tomato.efi")
with subtest("remove files when no longer needed"): machine.succeed("${baseSystem}/bin/switch-to-configuration boot") machine.fail("test -e /boot/efi/fruits/tomato.efi") machine.fail("test -d /boot/efi/fruits") machine.succeed("test -d /boot/efi/nixos/.extra-files") machine.fail("test -e /boot/efi/nixos/.extra-files/efi/fruits/tomato.efi") machine.fail("test -d /boot/efi/nixos/.extra-files/efi/fruits")
with subtest("files are added back when needed again"): machine.succeed("${originalSystem}/bin/switch-to-configuration boot") machine.succeed("test -e /boot/efi/fruits/tomato.efi") machine.succeed("test -e /boot/efi/nixos/.extra-files/efi/fruits/tomato.efi")
with subtest("simultaneously removing and adding files works"): machine.succeed("${finalSystem}/bin/switch-to-configuration boot") machine.fail("test -e /boot/efi/fruits/tomato.efi") machine.fail("test -e /boot/efi/nixos/.extra-files/efi/fruits/tomato.efi") machine.succeed("test -e /boot/loader/entries/netbootxyz.conf") machine.succeed("test -e /boot/efi/netbootxyz/netboot.xyz.efi") machine.succeed("test -e /boot/efi/nixos/.extra-files/loader/entries/netbootxyz.conf") machine.succeed("test -e /boot/efi/nixos/.extra-files/efi/netbootxyz/netboot.xyz.efi") ''; };
garbage-collect-entry = makeTest { name = "systemd-boot-garbage-collect-entry"; meta.maintainers = with pkgs.lib.maintainers; [ julienmalka ];
nodes = { inherit common; machine = { pkgs, nodes, ... }: { imports = [ common ];
# These are configs for different nodes, but we'll use them here in `machine` system.extraDependencies = [ nodes.common.system.build.toplevel ]; }; };
testScript = { nodes, ... }: let baseSystem = nodes.common.system.build.toplevel; in '' machine.succeed("nix-env -p /nix/var/nix/profiles/system --set ${baseSystem}") machine.succeed("nix-env -p /nix/var/nix/profiles/system --delete-generations 1") machine.succeed("${baseSystem}/bin/switch-to-configuration boot") machine.fail("test -e /boot/loader/entries/nixos-generation-1.conf") machine.succeed("test -e /boot/loader/entries/nixos-generation-2.conf") ''; };
no-bootspec = makeTest { name = "systemd-boot-no-bootspec"; meta.maintainers = with pkgs.lib.maintainers; [ julienmalka ];
nodes.machine = { imports = [ common ]; boot.bootspec.enable = false; };
testScript = '' machine.start() machine.wait_for_unit("multi-user.target") ''; };}