0
0
Fork 0
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-07-13 13:40:28 +03:00

Merge pull request #256226 from ElvishJerricco/systemd-stage-1-testing-backdoor

This commit is contained in:
Ryan Lahfa 2023-11-10 14:08:07 +01:00 committed by GitHub
commit b8218af2e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 215 additions and 142 deletions

View file

@ -2,6 +2,7 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: {
name = "systemd-initrd-modprobe";
nodes.machine = { pkgs, ... }: {
testing.initrdBackdoor = true;
boot.initrd.systemd.enable = true;
boot.initrd.kernelModules = [ "loop" ]; # Load module in initrd.
boot.extraModprobeConfig = ''
@ -10,6 +11,12 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: {
};
testScript = ''
machine.wait_for_unit("initrd.target")
max_loop = machine.succeed("cat /sys/module/loop/parameters/max_loop")
assert int(max_loop) == 42, "Parameter should be respected for initrd kernel modules"
# Make sure it sticks in stage 2
machine.switch_root()
machine.wait_for_unit("multi-user.target")
max_loop = machine.succeed("cat /sys/module/loop/parameters/max_loop")
assert int(max_loop) == 42, "Parameter should be respected for initrd kernel modules"

View file

@ -4,34 +4,16 @@ import ./make-test-python.nix ({ lib, ... }: {
nodes = {
server = { config, pkgs, ... }: {
environment.systemPackages = [ pkgs.cryptsetup ];
boot.loader.systemd-boot.enable = true;
boot.loader.timeout = 0;
virtualisation = {
emptyDiskImages = [ 4096 ];
useBootLoader = true;
# Booting off the encrypted disk requires an available init script from
# the Nix store
mountHostNixStore = true;
useEFIBoot = true;
};
specialisation.encrypted-root.configuration = {
virtualisation.rootDevice = "/dev/mapper/root";
virtualisation.fileSystems."/".autoFormat = true;
boot.initrd.luks.devices = lib.mkVMOverride {
root.device = "/dev/vdb";
};
boot.initrd.systemd.enable = true;
boot.initrd.network = {
testing.initrdBackdoor = true;
boot.initrd.systemd.enable = true;
boot.initrd.systemd.contents."/etc/msg".text = "foo";
boot.initrd.network = {
enable = true;
ssh = {
enable = true;
ssh = {
enable = true;
authorizedKeys = [ (lib.readFile ./initrd-network-ssh/id_ed25519.pub) ];
port = 22;
# Terrible hack so it works with useBootLoader
hostKeys = [ { outPath = "${./initrd-network-ssh/ssh_host_ed25519_key}"; } ];
};
authorizedKeys = [ (lib.readFile ./initrd-network-ssh/id_ed25519.pub) ];
port = 22;
hostKeys = [ ./initrd-network-ssh/ssh_host_ed25519_key ];
};
};
};
@ -63,24 +45,16 @@ import ./make-test-python.nix ({ lib, ... }: {
status, _ = client.execute("nc -z server 22")
return status == 0
server.wait_for_unit("multi-user.target")
server.succeed(
"echo somepass | cryptsetup luksFormat --type=luks2 /dev/vdb",
"bootctl set-default nixos-generation-1-specialisation-encrypted-root.conf",
"sync",
)
server.shutdown()
server.start()
client.wait_for_unit("network.target")
with client.nested("waiting for SSH server to come up"):
retry(ssh_is_up)
client.succeed(
"echo somepass | ssh -i /etc/sshKey -o UserKnownHostsFile=/etc/knownHosts server 'systemd-tty-ask-password-agent' & exit"
msg = client.succeed(
"ssh -i /etc/sshKey -o UserKnownHostsFile=/etc/knownHosts server 'cat /etc/msg'"
)
assert "foo" in msg
server.switch_root()
server.wait_for_unit("multi-user.target")
server.succeed("mount | grep '/dev/mapper/root on /'")
'';
})

View file

@ -1,14 +1,36 @@
import ./make-test-python.nix ({ pkgs, lib, ... }: {
name = "systemd-initrd-network";
meta.maintainers = [ lib.maintainers.elvishjerricco ];
{ system ? builtins.currentSystem
, config ? {}
, pkgs ? import ../.. { inherit system config; }
, lib ? pkgs.lib
}:
nodes = let
mkFlushTest = flush: script: { ... }: {
boot.initrd.systemd.enable = true;
boot.initrd.network = {
enable = true;
flushBeforeStage2 = flush;
};
with import ../lib/testing-python.nix { inherit system pkgs; };
let
inherit (lib.maintainers) elvishjerricco;
common = {
boot.initrd.systemd = {
enable = true;
network.wait-online.timeout = 10;
network.wait-online.anyInterface = true;
targets.network-online.requiredBy = [ "initrd.target" ];
services.systemd-networkd-wait-online.requiredBy =
[ "network-online.target" ];
initrdBin = [ pkgs.iproute2 pkgs.iputils pkgs.gnugrep ];
};
testing.initrdBackdoor = true;
boot.initrd.network.enable = true;
};
mkFlushTest = flush: script: makeTest {
name = "systemd-initrd-network-${lib.optionalString (!flush) "no-"}flush";
meta.maintainers = [ elvishjerricco ];
nodes.machine = {
imports = [ common ];
boot.initrd.network.flushBeforeStage2 = flush;
systemd.services.check-flush = {
requiredBy = ["multi-user.target"];
before = ["network-pre.target" "multi-user.target"];
@ -19,57 +41,53 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
inherit script;
};
};
in {
basic = { ... }: {
boot.initrd.network.enable = true;
boot.initrd.systemd = {
enable = true;
# Enable network-online to fail the test in case of timeout
network.wait-online.timeout = 10;
network.wait-online.anyInterface = true;
targets.network-online.requiredBy = [ "initrd.target" ];
services.systemd-networkd-wait-online.requiredBy =
[ "network-online.target" ];
testScript = ''
machine.wait_for_unit("network-online.target")
machine.succeed(
"ip addr | grep 10.0.2.15",
"ping -c1 10.0.2.2",
)
machine.switch_root()
initrdBin = [ pkgs.iproute2 pkgs.iputils pkgs.gnugrep ];
services.check = {
requiredBy = [ "initrd.target" ];
before = [ "initrd.target" ];
after = [ "network-online.target" ];
serviceConfig.Type = "oneshot";
path = [ pkgs.iproute2 pkgs.iputils pkgs.gnugrep ];
script = ''
ip addr | grep 10.0.2.15 || exit 1
ping -c1 10.0.2.2 || exit 1
'';
};
};
};
doFlush = mkFlushTest true ''
if ip addr | grep 10.0.2.15; then
echo "Network configuration survived switch-root; flushBeforeStage2 failed"
exit 1
fi
'';
dontFlush = mkFlushTest false ''
if ! (ip addr | grep 10.0.2.15); then
echo "Network configuration didn't survive switch-root"
exit 1
fi
machine.wait_for_unit("multi-user.target")
'';
};
testScript = ''
start_all()
basic.wait_for_unit("multi-user.target")
doFlush.wait_for_unit("multi-user.target")
dontFlush.wait_for_unit("multi-user.target")
# Make sure the systemd-network user was set correctly in initrd
basic.succeed("[ $(stat -c '%U,%G' /run/systemd/netif/links) = systemd-network,systemd-network ]")
basic.succeed("ip addr show >&2")
basic.succeed("ip route show >&2")
in {
basic = makeTest {
name = "systemd-initrd-network";
meta.maintainers = [ elvishjerricco ];
nodes.machine = common;
testScript = ''
machine.wait_for_unit("network-online.target")
machine.succeed(
"ip addr | grep 10.0.2.15",
"ping -c1 10.0.2.2",
)
machine.switch_root()
# Make sure the systemd-network user was set correctly in initrd
machine.wait_for_unit("multi-user.target")
machine.succeed("[ $(stat -c '%U,%G' /run/systemd/netif/links) = systemd-network,systemd-network ]")
machine.succeed("ip addr show >&2")
machine.succeed("ip route show >&2")
'';
};
doFlush = mkFlushTest true ''
if ip addr | grep 10.0.2.15; then
echo "Network configuration survived switch-root; flushBeforeStage2 failed"
exit 1
fi
'';
})
dontFlush = mkFlushTest false ''
if ! (ip addr | grep 10.0.2.15); then
echo "Network configuration didn't survive switch-root"
exit 1
fi
'';
}

View file

@ -2,16 +2,19 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: {
name = "systemd-initrd-simple";
nodes.machine = { pkgs, ... }: {
boot.initrd.systemd = {
enable = true;
emergencyAccess = true;
};
testing.initrdBackdoor = true;
boot.initrd.systemd.enable = true;
virtualisation.fileSystems."/".autoResize = true;
};
testScript = ''
import subprocess
with subtest("testing initrd backdoor"):
machine.wait_for_unit("initrd.target")
machine.succeed("systemctl status initrd-fs.target")
machine.switch_root()
with subtest("handover to stage-2 systemd works"):
machine.wait_for_unit("multi-user.target")
machine.succeed("systemd-analyze | grep -q '(initrd)'") # direct handover
@ -37,6 +40,7 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: {
subprocess.check_call(["qemu-img", "resize", "vm-state-machine/machine.qcow2", "+1G"])
machine.start()
machine.switch_root()
newAvail = machine.succeed("df --output=avail / | sed 1d")
assert int(oldAvail) < int(newAvail), "File system did not grow"