1let
2 hostIp = "192.168.0.1";
3 containerIp = "192.168.0.100/24";
4 hostIp6 = "fc00::1";
5 containerIp6 = "fc00::2/7";
6in
7
8{ pkgs, lib, ... }:
9{
10 name = "containers-bridge";
11 meta = {
12 maintainers = with lib.maintainers; [
13 aristid
14 aszlig
15 kampfschlaefer
16 ];
17 };
18
19 nodes.machine =
20 { pkgs, ... }:
21 {
22 imports = [ ../modules/installer/cd-dvd/channel.nix ];
23 virtualisation.writableStore = true;
24
25 networking.bridges = {
26 br0 = {
27 interfaces = [ ];
28 };
29 };
30 networking.interfaces = {
31 br0 = {
32 ipv4.addresses = [
33 {
34 address = hostIp;
35 prefixLength = 24;
36 }
37 ];
38 ipv6.addresses = [
39 {
40 address = hostIp6;
41 prefixLength = 7;
42 }
43 ];
44 };
45 };
46
47 containers.webserver = {
48 autoStart = true;
49 privateNetwork = true;
50 hostBridge = "br0";
51 localAddress = containerIp;
52 localAddress6 = containerIp6;
53 config = {
54 services.httpd.enable = true;
55 services.httpd.adminAddr = "foo@example.org";
56 networking.firewall.allowedTCPPorts = [ 80 ];
57 };
58 };
59
60 containers.web-noip = {
61 autoStart = true;
62 privateNetwork = true;
63 hostBridge = "br0";
64 config = {
65 services.httpd.enable = true;
66 services.httpd.adminAddr = "foo@example.org";
67 networking.firewall.allowedTCPPorts = [ 80 ];
68 };
69 };
70
71 virtualisation.additionalPaths = [ pkgs.stdenv ];
72 };
73
74 testScript = ''
75 machine.wait_for_unit("default.target")
76 assert "webserver" in machine.succeed("nixos-container list")
77
78 with subtest("Start the webserver container"):
79 assert "up" in machine.succeed("nixos-container status webserver")
80
81 with subtest("Bridges exist inside containers"):
82 machine.succeed(
83 "nixos-container run webserver -- ip link show eth0",
84 "nixos-container run web-noip -- ip link show eth0",
85 )
86
87 ip = "${containerIp}".split("/")[0]
88 machine.succeed(f"ping -n -c 1 {ip}")
89 machine.succeed(f"curl --fail http://{ip}/ > /dev/null")
90
91 ip6 = "${containerIp6}".split("/")[0]
92 machine.succeed(f"ping -n -c 1 {ip6}")
93 machine.succeed(f"curl --fail http://[{ip6}]/ > /dev/null")
94
95 with subtest(
96 "nixos-container show-ip works in case of an ipv4 address "
97 + "with subnetmask in CIDR notation."
98 ):
99 result = machine.succeed("nixos-container show-ip webserver").rstrip()
100 assert result == ip
101
102 with subtest("Stop the container"):
103 machine.succeed("nixos-container stop webserver")
104 machine.fail(
105 f"curl --fail --connect-timeout 2 http://{ip}/ > /dev/null",
106 f"curl --fail --connect-timeout 2 http://[{ip6}]/ > /dev/null",
107 )
108
109 # Destroying a declarative container should fail.
110 machine.fail("nixos-container destroy webserver")
111 '';
112}