lol

containers: Improve device dependency tracking

Now the tracking works with aggregated devices on aggregated devices.

So container with physical device where the device is put in a bond
which is the basis for a bridge is now handled correctly.

+86 -19
+3 -3
nixos/modules/tasks/network-interfaces-scripted.nix
··· 196 196 197 197 createBridgeDevice = n: v: nameValuePair "${n}-netdev" 198 198 (let 199 - deps = if config.boot.isContainer then [] else map subsystemDevice v.interfaces; 199 + deps = concatLists (map deviceDependency v.interfaces); 200 200 in 201 201 { description = "Bridge Interface ${n}"; 202 202 wantedBy = [ "network-setup.service" (subsystemDevice n) ]; ··· 237 237 238 238 createVswitchDevice = n: v: nameValuePair "${n}-netdev" 239 239 (let 240 - deps = if config.boot.isContainer then [] else map subsystemDevice v.interfaces; 240 + deps = concatLists (map deviceDependency v.interfaces); 241 241 ofRules = pkgs.writeText "vswitch-${n}-openFlowRules" v.openFlowRules; 242 242 in 243 243 { description = "Open vSwitch Interface ${n}"; ··· 270 270 271 271 createBondDevice = n: v: nameValuePair "${n}-netdev" 272 272 (let 273 - deps = if config.boot.isContainer then [] else map subsystemDevice v.interfaces; 273 + deps = concatLists (map deviceDependency v.interfaces); 274 274 in 275 275 { description = "Bond Interface ${n}"; 276 276 wantedBy = [ "network-setup.service" (subsystemDevice n) ];
+83 -16
nixos/tests/containers-physical_interfaces.nix
··· 23 23 }; 24 24 }; 25 25 }; 26 - client = { config, pkgs, ... }: { 27 - virtualisation.memorySize = 256; 26 + bridged = { config, pkgs, ... }: { 27 + virtualisation.memorySize = 128; 28 28 virtualisation.vlans = [ 1 ]; 29 29 30 - containers.client = { 30 + containers.bridged = { 31 31 privateNetwork = true; 32 32 interfaces = [ "eth1" ]; 33 33 ··· 40 40 }; 41 41 }; 42 42 }; 43 + 44 + bonded = { config, pkgs, ... }: { 45 + virtualisation.memorySize = 128; 46 + virtualisation.vlans = [ 1 ]; 47 + 48 + containers.bonded = { 49 + privateNetwork = true; 50 + interfaces = [ "eth1" ]; 51 + 52 + config = { 53 + networking.bonds.bond0 = { 54 + interfaces = [ "eth1" ]; 55 + mode = "active-backup"; 56 + }; 57 + networking.interfaces.bond0 = { 58 + ip4 = [ { address = "10.10.0.3"; prefixLength = 24; } ]; 59 + }; 60 + networking.firewall.enable = false; 61 + }; 62 + }; 63 + }; 64 + 65 + bridgedbond = { config, pkgs, ... }: { 66 + virtualisation.memorySize = 128; 67 + virtualisation.vlans = [ 1 ]; 68 + 69 + containers.bridgedbond = { 70 + privateNetwork = true; 71 + interfaces = [ "eth1" ]; 72 + 73 + config = { 74 + networking.bonds.bond0 = { 75 + interfaces = [ "eth1" ]; 76 + mode = "active-backup"; 77 + }; 78 + networking.bridges.br0.interfaces = [ "bond0" ]; 79 + networking.interfaces.br0 = { 80 + ip4 = [ { address = "10.10.0.4"; prefixLength = 24; } ]; 81 + }; 82 + networking.firewall.enable = false; 83 + }; 84 + }; 85 + }; 43 86 }; 44 87 45 88 testScript = '' 46 89 startAll; 47 90 48 - $server->waitForUnit("default.target"); 49 - $server->execute("ip link >&2"); 91 + subtest "prepare server", sub { 92 + $server->waitForUnit("default.target"); 93 + $server->succeed("ip link show dev eth1 >&2"); 94 + }; 95 + 96 + subtest "simple physical interface", sub { 97 + $server->succeed("nixos-container start server"); 98 + $server->waitForUnit("container\@server"); 99 + $server->succeed("systemctl -M server list-dependencies network-addresses-eth1.service >&2"); 50 100 51 - $server->succeed("ip link show dev eth1 >&2"); 101 + # The other tests will ping this container on its ip. Here we just check 102 + # that the device is present in the container. 103 + $server->succeed("nixos-container run server -- ip a show dev eth1 >&2"); 104 + }; 52 105 53 - $server->succeed("nixos-container start server"); 54 - $server->waitForUnit("container\@server"); 55 - $server->succeed("systemctl -M server list-dependencies network-addresses-eth1.service >&2"); 106 + subtest "physical device in bridge in container", sub { 107 + $bridged->waitForUnit("default.target"); 108 + $bridged->succeed("nixos-container start bridged"); 109 + $bridged->waitForUnit("container\@bridged"); 110 + $bridged->succeed("systemctl -M bridged list-dependencies network-addresses-br0.service >&2"); 111 + $bridged->succeed("systemctl -M bridged status -n 30 -l network-addresses-br0.service"); 112 + $bridged->succeed("nixos-container run bridged -- ping -w 10 -c 1 -n 10.10.0.1"); 113 + }; 56 114 57 - $server->succeed("nixos-container run server -- ip a show dev eth1 >&2"); 115 + subtest "physical device in bond in container", sub { 116 + $bonded->waitForUnit("default.target"); 117 + $bonded->succeed("nixos-container start bonded"); 118 + $bonded->waitForUnit("container\@bonded"); 119 + $bonded->succeed("systemctl -M bonded list-dependencies network-addresses-bond0 >&2"); 120 + $bonded->succeed("systemctl -M bonded status -n 30 -l network-addresses-bond0 >&2"); 121 + $bonded->succeed("nixos-container run bonded -- ping -w 10 -c 1 -n 10.10.0.1"); 122 + }; 58 123 59 - $client->waitForUnit("default.target"); 60 - $client->succeed("nixos-container start client"); 61 - $client->waitForUnit("container\@client"); 62 - $client->succeed("systemctl -M client list-dependencies network-addresses-br0.service >&2"); 63 - $client->succeed("systemctl -M client status -n 30 -l network-addresses-br0.service"); 64 - $client->succeed("nixos-container run client -- ping -w 10 -c 1 -n 10.10.0.1"); 124 + subtest "physical device in bond in bridge in container", sub { 125 + $bridgedbond->waitForUnit("default.target"); 126 + $bridgedbond->succeed("nixos-container start bridgedbond"); 127 + $bridgedbond->waitForUnit("container\@bridgedbond"); 128 + $bridgedbond->succeed("systemctl -M bridgedbond list-dependencies network-addresses-br0.service >&2"); 129 + $bridgedbond->succeed("systemctl -M bridgedbond status -n 30 -l network-addresses-br0.service"); 130 + $bridgedbond->succeed("nixos-container run bridgedbond -- ping -w 10 -c 1 -n 10.10.0.1"); 131 + }; 65 132 ''; 66 133 })