Merge pull request #19128 from kampfschlaefer/fix_device_wait_in_containers
Fix device wait in containers
This commit is contained in:
commit
89e4d72fc8
@ -46,6 +46,23 @@ in
|
||||
systemd.services =
|
||||
let
|
||||
|
||||
deviceDependency = dev:
|
||||
if (config.boot.isContainer == false)
|
||||
then
|
||||
# Trust udev when not in the container
|
||||
[ (subsystemDevice dev) ]
|
||||
else
|
||||
# When in the container, check whether the interface is built from other definitions
|
||||
if (hasAttr dev cfg.bridges) ||
|
||||
(hasAttr dev cfg.bonds) ||
|
||||
(hasAttr dev cfg.macvlans) ||
|
||||
(hasAttr dev cfg.sits) ||
|
||||
(hasAttr dev cfg.vlans) ||
|
||||
(hasAttr dev cfg.vswitches) ||
|
||||
(hasAttr dev cfg.wlanInterfaces)
|
||||
then [ "${dev}-netdev.service" ]
|
||||
else [];
|
||||
|
||||
networkLocalCommands = {
|
||||
after = [ "network-setup.service" ];
|
||||
bindsTo = [ "network-setup.service" ];
|
||||
@ -120,8 +137,8 @@ in
|
||||
# order before network-setup because the routes that are configured
|
||||
# there may need ip addresses configured
|
||||
before = [ "network-setup.service" ];
|
||||
bindsTo = [ (subsystemDevice i.name) ];
|
||||
after = [ (subsystemDevice i.name) "network-pre.target" ];
|
||||
bindsTo = deviceDependency i.name;
|
||||
after = [ "network-pre.target" ] ++ (deviceDependency i.name);
|
||||
serviceConfig.Type = "oneshot";
|
||||
serviceConfig.RemainAfterExit = true;
|
||||
path = [ pkgs.iproute ];
|
||||
@ -179,7 +196,7 @@ in
|
||||
|
||||
createBridgeDevice = n: v: nameValuePair "${n}-netdev"
|
||||
(let
|
||||
deps = map subsystemDevice v.interfaces;
|
||||
deps = concatLists (map deviceDependency v.interfaces);
|
||||
in
|
||||
{ description = "Bridge Interface ${n}";
|
||||
wantedBy = [ "network-setup.service" (subsystemDevice n) ];
|
||||
@ -220,7 +237,7 @@ in
|
||||
|
||||
createVswitchDevice = n: v: nameValuePair "${n}-netdev"
|
||||
(let
|
||||
deps = map subsystemDevice v.interfaces;
|
||||
deps = concatLists (map deviceDependency v.interfaces);
|
||||
ofRules = pkgs.writeText "vswitch-${n}-openFlowRules" v.openFlowRules;
|
||||
in
|
||||
{ description = "Open vSwitch Interface ${n}";
|
||||
@ -253,7 +270,7 @@ in
|
||||
|
||||
createBondDevice = n: v: nameValuePair "${n}-netdev"
|
||||
(let
|
||||
deps = map subsystemDevice v.interfaces;
|
||||
deps = concatLists (map deviceDependency v.interfaces);
|
||||
in
|
||||
{ description = "Bond Interface ${n}";
|
||||
wantedBy = [ "network-setup.service" (subsystemDevice n) ];
|
||||
@ -291,7 +308,7 @@ in
|
||||
|
||||
createMacvlanDevice = n: v: nameValuePair "${n}-netdev"
|
||||
(let
|
||||
deps = [ (subsystemDevice v.interface) ];
|
||||
deps = deviceDependency v.interface;
|
||||
in
|
||||
{ description = "Vlan Interface ${n}";
|
||||
wantedBy = [ "network-setup.service" (subsystemDevice n) ];
|
||||
@ -316,7 +333,7 @@ in
|
||||
|
||||
createSitDevice = n: v: nameValuePair "${n}-netdev"
|
||||
(let
|
||||
deps = optional (v.dev != null) (subsystemDevice v.dev);
|
||||
deps = optional (v.dev != null) (deviceDependency v.dev);
|
||||
in
|
||||
{ description = "6-to-4 Tunnel Interface ${n}";
|
||||
wantedBy = [ "network-setup.service" (subsystemDevice n) ];
|
||||
@ -344,7 +361,7 @@ in
|
||||
|
||||
createVlanDevice = n: v: nameValuePair "${n}-netdev"
|
||||
(let
|
||||
deps = [ (subsystemDevice v.interface) ];
|
||||
deps = deviceDependency v.interface;
|
||||
in
|
||||
{ description = "Vlan Interface ${n}";
|
||||
wantedBy = [ "network-setup.service" (subsystemDevice n) ];
|
||||
|
@ -310,9 +310,9 @@ in
|
||||
generate a random 32-bit ID using the following commands:
|
||||
|
||||
<literal>cksum /etc/machine-id | while read c rest; do printf "%x" $c; done</literal>
|
||||
|
||||
|
||||
(this derives it from the machine-id that systemd generates) or
|
||||
|
||||
|
||||
<literal>head -c4 /dev/urandom | od -A none -t x4</literal>
|
||||
'';
|
||||
};
|
||||
@ -972,12 +972,17 @@ in
|
||||
'';
|
||||
};
|
||||
} // (listToAttrs (flip map interfaces (i:
|
||||
let
|
||||
deviceDependency = if config.boot.isContainer
|
||||
then []
|
||||
else [ (subsystemDevice i.name) ];
|
||||
in
|
||||
nameValuePair "network-link-${i.name}"
|
||||
{ description = "Link configuration of ${i.name}";
|
||||
wantedBy = [ "network-interfaces.target" ];
|
||||
before = [ "network-interfaces.target" ];
|
||||
bindsTo = [ (subsystemDevice i.name) ];
|
||||
after = [ (subsystemDevice i.name) "network-pre.target" ];
|
||||
bindsTo = deviceDependency;
|
||||
after = [ "network-pre.target" ] ++ deviceDependency;
|
||||
path = [ pkgs.iproute ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
|
@ -227,6 +227,7 @@ in rec {
|
||||
tests.containers-bridge = callTest tests/containers-bridge.nix {};
|
||||
tests.containers-imperative = callTest tests/containers-imperative.nix {};
|
||||
tests.containers-extra_veth = callTest tests/containers-extra_veth.nix {};
|
||||
tests.containers-physical_interfaces = callTest tests/containers-physical_interfaces.nix {};
|
||||
tests.docker = hydraJob (import tests/docker.nix { system = "x86_64-linux"; });
|
||||
tests.dnscrypt-proxy = callTest tests/dnscrypt-proxy.nix { system = "x86_64-linux"; };
|
||||
tests.ecryptfs = callTest tests/ecryptfs.nix {};
|
||||
|
133
nixos/tests/containers-physical_interfaces.nix
Normal file
133
nixos/tests/containers-physical_interfaces.nix
Normal file
@ -0,0 +1,133 @@
|
||||
|
||||
import ./make-test.nix ({ pkgs, ...} : {
|
||||
name = "containers-physical_interfaces";
|
||||
meta = with pkgs.stdenv.lib.maintainers; {
|
||||
maintainers = [ kampfschlaefer ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
server = { config, pkgs, ... }:
|
||||
{
|
||||
virtualisation.memorySize = 256;
|
||||
virtualisation.vlans = [ 1 ];
|
||||
|
||||
containers.server = {
|
||||
privateNetwork = true;
|
||||
interfaces = [ "eth1" ];
|
||||
|
||||
config = {
|
||||
networking.interfaces.eth1 = {
|
||||
ip4 = [ { address = "10.10.0.1"; prefixLength = 24; } ];
|
||||
};
|
||||
networking.firewall.enable = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
bridged = { config, pkgs, ... }: {
|
||||
virtualisation.memorySize = 128;
|
||||
virtualisation.vlans = [ 1 ];
|
||||
|
||||
containers.bridged = {
|
||||
privateNetwork = true;
|
||||
interfaces = [ "eth1" ];
|
||||
|
||||
config = {
|
||||
networking.bridges.br0.interfaces = [ "eth1" ];
|
||||
networking.interfaces.br0 = {
|
||||
ip4 = [ { address = "10.10.0.2"; prefixLength = 24; } ];
|
||||
};
|
||||
networking.firewall.enable = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
bonded = { config, pkgs, ... }: {
|
||||
virtualisation.memorySize = 128;
|
||||
virtualisation.vlans = [ 1 ];
|
||||
|
||||
containers.bonded = {
|
||||
privateNetwork = true;
|
||||
interfaces = [ "eth1" ];
|
||||
|
||||
config = {
|
||||
networking.bonds.bond0 = {
|
||||
interfaces = [ "eth1" ];
|
||||
mode = "active-backup";
|
||||
};
|
||||
networking.interfaces.bond0 = {
|
||||
ip4 = [ { address = "10.10.0.3"; prefixLength = 24; } ];
|
||||
};
|
||||
networking.firewall.enable = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
bridgedbond = { config, pkgs, ... }: {
|
||||
virtualisation.memorySize = 128;
|
||||
virtualisation.vlans = [ 1 ];
|
||||
|
||||
containers.bridgedbond = {
|
||||
privateNetwork = true;
|
||||
interfaces = [ "eth1" ];
|
||||
|
||||
config = {
|
||||
networking.bonds.bond0 = {
|
||||
interfaces = [ "eth1" ];
|
||||
mode = "active-backup";
|
||||
};
|
||||
networking.bridges.br0.interfaces = [ "bond0" ];
|
||||
networking.interfaces.br0 = {
|
||||
ip4 = [ { address = "10.10.0.4"; prefixLength = 24; } ];
|
||||
};
|
||||
networking.firewall.enable = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
startAll;
|
||||
|
||||
subtest "prepare server", sub {
|
||||
$server->waitForUnit("default.target");
|
||||
$server->succeed("ip link show dev eth1 >&2");
|
||||
};
|
||||
|
||||
subtest "simple physical interface", sub {
|
||||
$server->succeed("nixos-container start server");
|
||||
$server->waitForUnit("container\@server");
|
||||
$server->succeed("systemctl -M server list-dependencies network-addresses-eth1.service >&2");
|
||||
|
||||
# The other tests will ping this container on its ip. Here we just check
|
||||
# that the device is present in the container.
|
||||
$server->succeed("nixos-container run server -- ip a show dev eth1 >&2");
|
||||
};
|
||||
|
||||
subtest "physical device in bridge in container", sub {
|
||||
$bridged->waitForUnit("default.target");
|
||||
$bridged->succeed("nixos-container start bridged");
|
||||
$bridged->waitForUnit("container\@bridged");
|
||||
$bridged->succeed("systemctl -M bridged list-dependencies network-addresses-br0.service >&2");
|
||||
$bridged->succeed("systemctl -M bridged status -n 30 -l network-addresses-br0.service");
|
||||
$bridged->succeed("nixos-container run bridged -- ping -w 10 -c 1 -n 10.10.0.1");
|
||||
};
|
||||
|
||||
subtest "physical device in bond in container", sub {
|
||||
$bonded->waitForUnit("default.target");
|
||||
$bonded->succeed("nixos-container start bonded");
|
||||
$bonded->waitForUnit("container\@bonded");
|
||||
$bonded->succeed("systemctl -M bonded list-dependencies network-addresses-bond0 >&2");
|
||||
$bonded->succeed("systemctl -M bonded status -n 30 -l network-addresses-bond0 >&2");
|
||||
$bonded->succeed("nixos-container run bonded -- ping -w 10 -c 1 -n 10.10.0.1");
|
||||
};
|
||||
|
||||
subtest "physical device in bond in bridge in container", sub {
|
||||
$bridgedbond->waitForUnit("default.target");
|
||||
$bridgedbond->succeed("nixos-container start bridgedbond");
|
||||
$bridgedbond->waitForUnit("container\@bridgedbond");
|
||||
$bridgedbond->succeed("systemctl -M bridgedbond list-dependencies network-addresses-br0.service >&2");
|
||||
$bridgedbond->succeed("systemctl -M bridgedbond status -n 30 -l network-addresses-br0.service");
|
||||
$bridgedbond->succeed("nixos-container run bridgedbond -- ping -w 10 -c 1 -n 10.10.0.1");
|
||||
};
|
||||
'';
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user