1# Test for NixOS' container support.
2
3import ./make-test.nix ({ pkgs, ...} : {
4 name = "containers";
5 meta = with pkgs.stdenv.lib.maintainers; {
6 maintainers = [ aristid aszlig eelco chaoflow ];
7 };
8
9 machine =
10 { config, pkgs, ... }:
11 { imports = [ ../modules/installer/cd-dvd/channel.nix ];
12 virtualisation.writableStore = true;
13 virtualisation.memorySize = 768;
14
15 containers.webserver =
16 { privateNetwork = true;
17 hostAddress = "10.231.136.1";
18 localAddress = "10.231.136.2";
19 config =
20 { services.httpd.enable = true;
21 services.httpd.adminAddr = "foo@example.org";
22 networking.firewall.allowedTCPPorts = [ 80 ];
23 networking.firewall.allowPing = true;
24 };
25 };
26
27 virtualisation.pathsInNixDB = [ pkgs.stdenv ];
28 };
29
30 testScript =
31 ''
32 $machine->succeed("nixos-container list") =~ /webserver/ or die;
33
34 # Start the webserver container.
35 $machine->succeed("nixos-container start webserver");
36
37 # Since "start" returns after the container has reached
38 # multi-user.target, we should now be able to access it.
39 my $ip = $machine->succeed("nixos-container show-ip webserver");
40 chomp $ip;
41 #$machine->succeed("ping -c1 $ip"); # FIXME
42 $machine->succeed("curl --fail http://$ip/ > /dev/null");
43
44 # Stop the container.
45 $machine->succeed("nixos-container stop webserver");
46 $machine->fail("curl --fail --connect-timeout 2 http://$ip/ > /dev/null");
47
48 # Make sure we have a NixOS tree (required by ‘nixos-container create’).
49 $machine->succeed("PAGER=cat nix-env -qa -A nixos.hello >&2");
50
51 # Create some containers imperatively.
52 my $id1 = $machine->succeed("nixos-container create foo --ensure-unique-name");
53 chomp $id1;
54 $machine->log("created container $id1");
55
56 my $id2 = $machine->succeed("nixos-container create foo --ensure-unique-name");
57 chomp $id2;
58 $machine->log("created container $id2");
59
60 die if $id1 eq $id2;
61
62 # Put the root of $id2 into a bind mount.
63 $machine->succeed(
64 "mv /var/lib/containers/$id2 /id2-bindmount",
65 "mount --bind /id2-bindmount /var/lib/containers/$id1"
66 );
67
68 my $ip1 = $machine->succeed("nixos-container show-ip $id1");
69 chomp $ip1;
70 my $ip2 = $machine->succeed("nixos-container show-ip $id2");
71 chomp $ip2;
72 die if $ip1 eq $ip2;
73
74 # Create a directory and a file we can later check if it still exists
75 # after destruction of the container.
76 $machine->succeed(
77 "mkdir /nested-bindmount",
78 "echo important data > /nested-bindmount/dummy",
79 );
80
81 # Create a directory with a dummy file and bind-mount it into both
82 # containers.
83 foreach ($id1, $id2) {
84 my $importantPath = "/var/lib/containers/$_/very/important/data";
85 $machine->succeed(
86 "mkdir -p $importantPath",
87 "mount --bind /nested-bindmount $importantPath"
88 );
89 }
90
91 # Start one of them.
92 $machine->succeed("nixos-container start $id1");
93
94 # Execute commands via the root shell.
95 $machine->succeed("nixos-container run $id1 -- uname") =~ /Linux/ or die;
96
97 # Stop and start (regression test for #4989)
98 $machine->succeed("nixos-container stop $id1");
99 $machine->succeed("nixos-container start $id1");
100
101 # Execute commands via the root shell.
102 $machine->succeed("nixos-container run $id1 -- uname") =~ /Linux/ or die;
103
104 # Destroy the containers.
105 $machine->succeed("nixos-container destroy $id1");
106 $machine->succeed("nixos-container destroy $id2");
107
108 $machine->succeed(
109 # Check whether destruction of any container has killed important data
110 "grep -qF 'important data' /nested-bindmount/dummy",
111 # Ensure that the container path is gone
112 "test ! -e /var/lib/containers/$id1"
113 );
114
115 # Destroying a declarative container should fail.
116 $machine->fail("nixos-container destroy webserver");
117 '';
118
119})