nixos/systemd-boot: autoformat

This commit is contained in:
Felix Uhl 2024-09-25 00:06:59 +02:00
parent 568bfef547
commit 548206583d
2 changed files with 380 additions and 255 deletions

View File

@ -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 "${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 "${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);

View File

@ -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 ];
meta.maintainers = with pkgs.lib.maintainers; [
lukegb
julienmalka
];
nodes.machine = { pkgs, lib, ... }: {
imports = [ common ];
specialisation.something.configuration = {
boot.loader.systemd-boot.sortKey = "something";
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
'');
# 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 ];
meta.maintainers = with pkgs.lib.maintainers; [
danielfullmer
julienmalka
];
nodes.machine = { pkgs, lib, ... }: {
imports = [ common ];
boot.loader.efi.canTouchEfiVariables = mkForce false;
};
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 ];
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;
};
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")
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("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("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")
'';
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 ];
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
];
};
# 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 ];
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")
'';
nodes.machine = {
imports = [ common ];
boot.bootspec.enable = false;
};
testScript = ''
machine.start()
machine.wait_for_unit("multi-user.target")
'';
};
}