systemd-initrd: Flush networkd
This commit is contained in:
parent
8598234651
commit
3cb9534df6
3 changed files with 71 additions and 2 deletions
|
@ -67,11 +67,15 @@ in
|
|||
|
||||
boot.initrd.network.flushBeforeStage2 = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
default = !config.boot.initrd.systemd.enable;
|
||||
defaultText = "!config.boot.initrd.systemd.enable";
|
||||
description = lib.mdDoc ''
|
||||
Whether to clear the configuration of the interfaces that were set up in
|
||||
the initrd right before stage 2 takes over. Stage 2 will do the regular network
|
||||
configuration based on the NixOS networking options.
|
||||
|
||||
The default is false when systemd is enabled in initrd,
|
||||
because the systemd-networkd documentation suggests it.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
|
@ -3186,6 +3186,39 @@ let
|
|||
];
|
||||
kernelModules = [ "af_packet" ];
|
||||
|
||||
systemd.services.nixos-flush-networkd = mkIf config.boot.initrd.network.flushBeforeStage2 {
|
||||
description = "Flush Network Configuration";
|
||||
wantedBy = ["initrd.target"];
|
||||
after = ["systemd-networkd.service" "dbus.socket" "dbus.service"];
|
||||
before = ["shutdown.target" "initrd-switch-root.target"];
|
||||
conflicts = ["shutdown.target" "initrd-switch-root.target"];
|
||||
unitConfig.DefaultDependencies = false;
|
||||
serviceConfig = {
|
||||
# This service does nothing when starting, but brings down
|
||||
# interfaces when switching root. This is the easiest way to
|
||||
# ensure proper ordering while stopping. See systemd.unit(5)
|
||||
# section on Before= and After=. The important part is that
|
||||
# we are stopped before units we need, like dbus.service,
|
||||
# and that we are stopped before starting units like
|
||||
# initrd-switch-root.target
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = "/bin/true";
|
||||
};
|
||||
# systemd-networkd doesn't bring down interfaces on its own
|
||||
# when it exits (see: systemd-networkd(8)), so we have to do
|
||||
# it ourselves. The networkctl command doesn't have a way to
|
||||
# bring all interfaces down, so we have to iterate over the
|
||||
# list and filter out unmanaged interfaces to bring them down
|
||||
# individually.
|
||||
preStop = ''
|
||||
networkctl list --full --no-legend | while read _idx link _type _operational setup _; do
|
||||
[ "$setup" = unmanaged ] && continue
|
||||
networkctl down "$link"
|
||||
done
|
||||
'';
|
||||
};
|
||||
|
||||
})
|
||||
];
|
||||
|
||||
|
|
|
@ -2,7 +2,23 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
|
|||
name = "systemd-initrd-network";
|
||||
meta.maintainers = [ lib.maintainers.elvishjerricco ];
|
||||
|
||||
nodes = {
|
||||
nodes = let
|
||||
mkFlushTest = flush: script: { ... }: {
|
||||
boot.initrd.systemd.enable = true;
|
||||
boot.initrd.network = {
|
||||
enable = true;
|
||||
flushBeforeStage2 = flush;
|
||||
};
|
||||
systemd.services.check-flush = {
|
||||
requiredBy = ["multi-user.target"];
|
||||
before = ["network-pre.target" "multi-user.target"];
|
||||
unitConfig.DefaultDependencies = false;
|
||||
serviceConfig.Type = "oneshot";
|
||||
path = [ pkgs.iproute2 pkgs.iputils pkgs.gnugrep ];
|
||||
inherit script;
|
||||
};
|
||||
};
|
||||
in {
|
||||
basic = { ... }: {
|
||||
boot.initrd.network.enable = true;
|
||||
|
||||
|
@ -29,11 +45,27 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
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
|
||||
'';
|
||||
};
|
||||
|
||||
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")
|
||||
|
|
Loading…
Reference in a new issue