Loading nixos/modules/system/boot/initrd-network.nix +5 −1 Original line number Diff line number Diff line Loading @@ -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. ''; }; Loading nixos/modules/system/boot/networkd.nix +33 −0 Original line number Diff line number Diff line Loading @@ -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 ''; }; }) ]; Loading nixos/tests/systemd-initrd-networkd.nix +33 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading
nixos/modules/system/boot/initrd-network.nix +5 −1 Original line number Diff line number Diff line Loading @@ -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. ''; }; Loading
nixos/modules/system/boot/networkd.nix +33 −0 Original line number Diff line number Diff line Loading @@ -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 ''; }; }) ]; Loading
nixos/tests/systemd-initrd-networkd.nix +33 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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