From 548206583deab634ddfdd26fa08655198022f1a3 Mon Sep 17 00:00:00 2001 From: Felix Uhl Date: Wed, 25 Sep 2024 00:06:59 +0200 Subject: [PATCH] nixos/systemd-boot: autoformat --- .../boot/loader/systemd-boot/systemd-boot.nix | 217 ++++++--- nixos/tests/systemd-boot.nix | 436 ++++++++++-------- 2 files changed, 389 insertions(+), 264 deletions(-) diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix index 6cab35820c88c..cbaddf25f9259 100644 --- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix +++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix @@ -1,4 +1,9 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: with lib; @@ -10,16 +15,19 @@ let # We check the source code in a derivation that does not depend on the # system configuration so that most users don't have to redo the check and require # the necessary dependencies. - checkedSource = pkgs.runCommand "systemd-boot" { - preferLocalBuild = true; - } '' - install -m755 -D ${./systemd-boot-builder.py} $out - ${lib.getExe pkgs.buildPackages.mypy} \ - --no-implicit-optional \ - --disallow-untyped-calls \ - --disallow-untyped-defs \ - $out - ''; + checkedSource = + pkgs.runCommand "systemd-boot" + { + preferLocalBuild = true; + } + '' + install -m755 -D ${./systemd-boot-builder.py} $out + ${lib.getExe pkgs.buildPackages.mypy} \ + --no-implicit-optional \ + --disallow-untyped-calls \ + --disallow-untyped-defs \ + $out + ''; systemdBootBuilder = pkgs.substituteAll rec { name = "systemd-boot"; @@ -44,13 +52,17 @@ let configurationLimit = if cfg.configurationLimit == null then 0 else cfg.configurationLimit; - inherit (cfg) consoleMode graceful editor rebootForBitlocker; + inherit (cfg) + consoleMode + graceful + editor + rebootForBitlocker + ; inherit (efi) efiSysMountPoint canTouchEfiVariables; - bootMountPoint = if cfg.xbootldrMountPoint != null - then cfg.xbootldrMountPoint - else efi.efiSysMountPoint; + bootMountPoint = + if cfg.xbootldrMountPoint != null then cfg.xbootldrMountPoint else efi.efiSysMountPoint; nixosDir = "/EFI/nixos"; @@ -66,23 +78,27 @@ let exit 1 } ${pkgs.util-linuxMinimal}/bin/findmnt ${efiSysMountPoint} > /dev/null || fail efiSysMountPoint ${efiSysMountPoint} - ${lib.optionalString - (cfg.xbootldrMountPoint != null) - "${pkgs.util-linuxMinimal}/bin/findmnt ${cfg.xbootldrMountPoint} > /dev/null || fail xbootldrMountPoint ${cfg.xbootldrMountPoint}"} + ${lib.optionalString (cfg.xbootldrMountPoint != null) + "${pkgs.util-linuxMinimal}/bin/findmnt ${cfg.xbootldrMountPoint} > /dev/null || fail xbootldrMountPoint ${cfg.xbootldrMountPoint}" + } ''; copyExtraFiles = pkgs.writeShellScript "copy-extra-files" '' empty_file=$(${pkgs.coreutils}/bin/mktemp) - ${concatStrings (mapAttrsToList (n: v: '' - ${pkgs.coreutils}/bin/install -Dp "${v}" "${bootMountPoint}/"${escapeShellArg n} - ${pkgs.coreutils}/bin/install -D $empty_file "${bootMountPoint}/${nixosDir}/.extra-files/"${escapeShellArg n} - '') cfg.extraFiles)} - - ${concatStrings (mapAttrsToList (n: v: '' - ${pkgs.coreutils}/bin/install -Dp "${pkgs.writeText n v}" "${bootMountPoint}/loader/entries/"${escapeShellArg n} - ${pkgs.coreutils}/bin/install -D $empty_file "${bootMountPoint}/${nixosDir}/.extra-files/loader/entries/"${escapeShellArg n} - '') cfg.extraEntries)} + ${concatStrings ( + mapAttrsToList (n: v: '' + ${pkgs.coreutils}/bin/install -Dp "${v}" "${bootMountPoint}/"${escapeShellArg n} + ${pkgs.coreutils}/bin/install -D $empty_file "${bootMountPoint}/${nixosDir}/.extra-files/"${escapeShellArg n} + '') cfg.extraFiles + )} + + ${concatStrings ( + mapAttrsToList (n: v: '' + ${pkgs.coreutils}/bin/install -Dp "${pkgs.writeText n v}" "${bootMountPoint}/loader/entries/"${escapeShellArg n} + ${pkgs.coreutils}/bin/install -D $empty_file "${bootMountPoint}/${nixosDir}/.extra-files/loader/entries/"${escapeShellArg n} + '') cfg.extraEntries + )} ''; }; @@ -91,23 +107,61 @@ let ${systemdBootBuilder}/bin/systemd-boot "$@" ${cfg.extraInstallCommands} ''; -in { +in +{ meta.maintainers = with lib.maintainers; [ julienmalka ]; - imports = - [ (mkRenamedOptionModule [ "boot" "loader" "gummiboot" "enable" ] [ "boot" "loader" "systemd-boot" "enable" ]) - (lib.mkChangedOptionModule - [ "boot" "loader" "systemd-boot" "memtest86" "entryFilename" ] - [ "boot" "loader" "systemd-boot" "memtest86" "sortKey" ] - (config: lib.strings.removeSuffix ".conf" config.boot.loader.systemd-boot.memtest86.entryFilename) - ) - (lib.mkChangedOptionModule - [ "boot" "loader" "systemd-boot" "netbootxyz" "entryFilename" ] - [ "boot" "loader" "systemd-boot" "netbootxyz" "sortKey" ] - (config: lib.strings.removeSuffix ".conf" config.boot.loader.systemd-boot.netbootxyz.entryFilename) - ) - ]; + imports = [ + (mkRenamedOptionModule + [ + "boot" + "loader" + "gummiboot" + "enable" + ] + [ + "boot" + "loader" + "systemd-boot" + "enable" + ] + ) + (lib.mkChangedOptionModule + [ + "boot" + "loader" + "systemd-boot" + "memtest86" + "entryFilename" + ] + [ + "boot" + "loader" + "systemd-boot" + "memtest86" + "sortKey" + ] + (config: lib.strings.removeSuffix ".conf" config.boot.loader.systemd-boot.memtest86.entryFilename) + ) + (lib.mkChangedOptionModule + [ + "boot" + "loader" + "systemd-boot" + "netbootxyz" + "entryFilename" + ] + [ + "boot" + "loader" + "systemd-boot" + "netbootxyz" + "sortKey" + ] + (config: lib.strings.removeSuffix ".conf" config.boot.loader.systemd-boot.netbootxyz.entryFilename) + ) + ]; options.boot.loader.systemd-boot = { enable = mkOption { @@ -218,7 +272,15 @@ in { consoleMode = mkOption { default = "keep"; - type = types.enum [ "0" "1" "2" "5" "auto" "max" "keep" ]; + type = types.enum [ + "0" + "1" + "2" + "5" + "auto" + "max" + "keep" + ]; description = '' The resolution of the console. The following values are valid: @@ -283,7 +345,7 @@ in { extraEntries = mkOption { type = types.attrsOf types.lines; - default = {}; + default = { }; example = literalExpression '' { "memtest86.conf" = ''' title Memtest86+ @@ -306,7 +368,7 @@ in { extraFiles = mkOption { type = types.attrsOf types.path; - default = {}; + default = { }; example = literalExpression '' { "efi/memtest86/memtest.efi" = "''${pkgs.memtest86plus}/memtest.efi"; } ''; @@ -352,37 +414,42 @@ in { }; config = mkIf cfg.enable { - assertions = [ - { - assertion = (hasPrefix "/" efi.efiSysMountPoint); - message = "The ESP mount point '${toString efi.efiSysMountPoint}' must be an absolute path"; - } - { - assertion = cfg.xbootldrMountPoint == null || (hasPrefix "/" cfg.xbootldrMountPoint); - message = "The XBOOTLDR mount point '${toString cfg.xbootldrMountPoint}' must be an absolute path"; - } - { - assertion = cfg.xbootldrMountPoint != efi.efiSysMountPoint; - message = "The XBOOTLDR mount point '${toString cfg.xbootldrMountPoint}' cannot be the same as the ESP mount point '${toString efi.efiSysMountPoint}'"; - } - { - assertion = (config.boot.kernelPackages.kernel.features or { efiBootStub = true; }) ? efiBootStub; - message = "This kernel does not support the EFI boot stub"; - } - { - assertion = cfg.installDeviceTree -> config.hardware.deviceTree.enable -> config.hardware.deviceTree.name != null; - message = "Cannot install devicetree without 'config.hardware.deviceTree.enable' enabled and 'config.hardware.deviceTree.name' set"; - } - ] ++ concatMap (filename: [ - { - assertion = !(hasInfix "/" filename); - message = "boot.loader.systemd-boot.extraEntries.${lib.strings.escapeNixIdentifier filename} is invalid: entries within folders are not supported"; - } - { - assertion = hasSuffix ".conf" filename; - message = "boot.loader.systemd-boot.extraEntries.${lib.strings.escapeNixIdentifier filename} is invalid: entries must have a .conf file extension"; - } - ]) (builtins.attrNames cfg.extraEntries) + assertions = + [ + { + assertion = (hasPrefix "/" efi.efiSysMountPoint); + message = "The ESP mount point '${toString efi.efiSysMountPoint}' must be an absolute path"; + } + { + assertion = cfg.xbootldrMountPoint == null || (hasPrefix "/" cfg.xbootldrMountPoint); + message = "The XBOOTLDR mount point '${toString cfg.xbootldrMountPoint}' must be an absolute path"; + } + { + assertion = cfg.xbootldrMountPoint != efi.efiSysMountPoint; + message = "The XBOOTLDR mount point '${toString cfg.xbootldrMountPoint}' cannot be the same as the ESP mount point '${toString efi.efiSysMountPoint}'"; + } + { + assertion = (config.boot.kernelPackages.kernel.features or { efiBootStub = true; }) ? efiBootStub; + message = "This kernel does not support the EFI boot stub"; + } + { + assertion = + cfg.installDeviceTree + -> config.hardware.deviceTree.enable + -> config.hardware.deviceTree.name != null; + message = "Cannot install devicetree without 'config.hardware.deviceTree.enable' enabled and 'config.hardware.deviceTree.name' set"; + } + ] + ++ concatMap (filename: [ + { + assertion = !(hasInfix "/" filename); + message = "boot.loader.systemd-boot.extraEntries.${lib.strings.escapeNixIdentifier filename} is invalid: entries within folders are not supported"; + } + { + assertion = hasSuffix ".conf" filename; + message = "boot.loader.systemd-boot.extraEntries.${lib.strings.escapeNixIdentifier filename} is invalid: entries must have a .conf file extension"; + } + ]) (builtins.attrNames cfg.extraEntries) ++ concatMap (filename: [ { assertion = !(hasPrefix "/" filename); diff --git a/nixos/tests/systemd-boot.nix b/nixos/tests/systemd-boot.nix index 79bfcb84ebd76..6b710180b3684 100644 --- a/nixos/tests/systemd-boot.nix +++ b/nixos/tests/systemd-boot.nix @@ -1,6 +1,7 @@ -{ system ? builtins.currentSystem, - config ? {}, - pkgs ? import ../.. { inherit system config; } +{ + system ? builtins.currentSystem, + config ? { }, + pkgs ? import ../.. { inherit system config; }, }: with import ../lib/testing-python.nix { inherit system pkgs; }; @@ -16,7 +17,13 @@ let system.switch.enable = true; }; - commonXbootldr = { config, lib, pkgs, ... }: + commonXbootldr = + { + config, + lib, + pkgs, + ... + }: let diskImage = import ../lib/make-disk-image.nix { inherit config lib pkgs; @@ -85,7 +92,10 @@ in { basic = makeTest { name = "systemd-boot"; - meta.maintainers = with pkgs.lib.maintainers; [ danielfullmer julienmalka ]; + meta.maintainers = with pkgs.lib.maintainers; [ + danielfullmer + julienmalka + ]; nodes.machine = common; @@ -117,22 +127,25 @@ in virtualisation.useSecureBoot = true; }; - testScript = let - efiArch = pkgs.stdenv.hostPlatform.efiArch; - in { nodes, ... }: '' - machine.start(allow_reboot=True) - machine.wait_for_unit("multi-user.target") + 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.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() + machine.reboot() - assert "Secure Boot: enabled (user)" in machine.succeed("bootctl status") - ''; + assert "Secure Boot: enabled (user)" in machine.succeed("bootctl status") + ''; }; basicXbootldr = makeTest { @@ -141,80 +154,97 @@ in nodes.machine = commonXbootldr; - testScript = { nodes, ... }: '' - ${customDiskImage nodes} + testScript = + { nodes, ... }: + '' + ${customDiskImage nodes} - machine.start() - machine.wait_for_unit("multi-user.target") + 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") + 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" - ) + # 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"') - ''; + # "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 - ''); + 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") + 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" - ) - ''; + 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; - }; + meta.maintainers = with pkgs.lib.maintainers; [ + danielfullmer + julienmalka + ]; + + nodes.machine = + { pkgs, lib, ... }: + { + imports = [ common ]; + boot.loader.efi.canTouchEfiVariables = mkForce false; + }; testScript = '' machine.start() @@ -235,7 +265,10 @@ in update = makeTest { name = "systemd-boot-update"; - meta.maintainers = with pkgs.lib.maintainers; [ danielfullmer julienmalka ]; + meta.maintainers = with pkgs.lib.maintainers; [ + danielfullmer + julienmalka + ]; nodes.machine = common; @@ -270,29 +303,35 @@ in ''; }; - 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; - }; + 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") - ''; - }); + 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; - }; + nodes.machine = + { pkgs, lib, ... }: + { + imports = [ common ]; + boot.loader.systemd-boot.netbootxyz.enable = true; + }; testScript = '' machine.succeed("test -e /boot/loader/entries/netbootxyz.conf") @@ -304,11 +343,13 @@ in 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"; - }; + 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") @@ -321,35 +362,41 @@ in 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; - }; + nodes.machine = + { pkgs, lib, ... }: + { + imports = [ commonXbootldr ]; + boot.loader.systemd-boot.memtest86.enable = true; + }; - testScript = { nodes, ... }: '' - ${customDiskImage nodes} + testScript = + { nodes, ... }: + '' + ${customDiskImage nodes} - machine.start() - machine.wait_for_unit("multi-user.target") + 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") - ''; + 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 - ''; + 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") @@ -361,12 +408,14 @@ in 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; + 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") @@ -381,55 +430,62 @@ in nodes = { inherit common; - machine = { pkgs, nodes, ... }: { - imports = [ common ]; - boot.loader.systemd-boot.extraFiles = { - "efi/fruits/tomato.efi" = pkgs.netbootxyz-efi; + 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 + ]; }; - # 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; - }; + 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") - ''; + 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 { @@ -438,17 +494,20 @@ in 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 - ]; - }; + 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, ... }: + testScript = + { nodes, ... }: let baseSystem = nodes.common.system.build.toplevel; in @@ -461,19 +520,18 @@ in ''; }; - no-bootspec = makeTest - { - name = "systemd-boot-no-bootspec"; - meta.maintainers = with pkgs.lib.maintainers; [ julienmalka ]; - - nodes.machine = { - imports = [ common ]; - boot.bootspec.enable = false; - }; + no-bootspec = makeTest { + name = "systemd-boot-no-bootspec"; + meta.maintainers = with pkgs.lib.maintainers; [ julienmalka ]; - testScript = '' - machine.start() - machine.wait_for_unit("multi-user.target") - ''; + nodes.machine = { + imports = [ common ]; + boot.bootspec.enable = false; }; + + testScript = '' + machine.start() + machine.wait_for_unit("multi-user.target") + ''; + }; }