1# Test for NixOS' container support.
2
3import ./make-test.nix ({ pkgs, ...} : {
4 name = "containers-imperative";
5 meta = with pkgs.stdenv.lib.maintainers; {
6 maintainers = [ aristid aszlig eelco chaoflow kampfschlaefer ];
7 };
8
9 machine =
10 { config, pkgs, lib, ... }:
11 { imports = [ ../modules/installer/cd-dvd/channel.nix ];
12
13 # XXX: Sandbox setup fails while trying to hardlink files from the host's
14 # store file system into the prepared chroot directory.
15 nix.useSandbox = false;
16
17 virtualisation.writableStore = true;
18 virtualisation.memorySize = 1024;
19 # Make sure we always have all the required dependencies for creating a
20 # container available within the VM, because we don't have network access.
21 virtualisation.pathsInNixDB = let
22 emptyContainer = import ../lib/eval-config.nix {
23 inherit (config.nixpkgs.localSystem) system;
24 modules = lib.singleton {
25 containers.foo.config = {
26 system.stateVersion = "18.03";
27 };
28 };
29 };
30 in [
31 pkgs.stdenv pkgs.stdenvNoCC emptyContainer.config.containers.foo.path
32 pkgs.libxslt
33 ];
34 };
35
36 testScript =
37 ''
38 # Make sure we have a NixOS tree (required by ‘nixos-container create’).
39 $machine->succeed("PAGER=cat nix-env -qa -A nixos.hello >&2");
40
41 # Create some containers imperatively.
42 my $id1 = $machine->succeed("nixos-container create foo --ensure-unique-name");
43 chomp $id1;
44 $machine->log("created container $id1");
45
46 my $id2 = $machine->succeed("nixos-container create foo --ensure-unique-name");
47 chomp $id2;
48 $machine->log("created container $id2");
49
50 die if $id1 eq $id2;
51
52 # Put the root of $id2 into a bind mount.
53 $machine->succeed(
54 "mv /var/lib/containers/$id2 /id2-bindmount",
55 "mount --bind /id2-bindmount /var/lib/containers/$id1"
56 );
57
58 my $ip1 = $machine->succeed("nixos-container show-ip $id1");
59 chomp $ip1;
60 my $ip2 = $machine->succeed("nixos-container show-ip $id2");
61 chomp $ip2;
62 die if $ip1 eq $ip2;
63
64 # Create a directory and a file we can later check if it still exists
65 # after destruction of the container.
66 $machine->succeed(
67 "mkdir /nested-bindmount",
68 "echo important data > /nested-bindmount/dummy",
69 );
70
71 # Create a directory with a dummy file and bind-mount it into both
72 # containers.
73 foreach ($id1, $id2) {
74 my $importantPath = "/var/lib/containers/$_/very/important/data";
75 $machine->succeed(
76 "mkdir -p $importantPath",
77 "mount --bind /nested-bindmount $importantPath"
78 );
79 }
80
81 # Start one of them.
82 $machine->succeed("nixos-container start $id1");
83
84 # Execute commands via the root shell.
85 $machine->succeed("nixos-container run $id1 -- uname") =~ /Linux/ or die;
86
87 # Stop and start (regression test for #4989)
88 $machine->succeed("nixos-container stop $id1");
89 $machine->succeed("nixos-container start $id1");
90
91 # Execute commands via the root shell.
92 $machine->succeed("nixos-container run $id1 -- uname") =~ /Linux/ or die;
93
94 # Destroy the containers.
95 $machine->succeed("nixos-container destroy $id1");
96 $machine->succeed("nixos-container destroy $id2");
97
98 $machine->succeed(
99 # Check whether destruction of any container has killed important data
100 "grep -qF 'important data' /nested-bindmount/dummy",
101 # Ensure that the container path is gone
102 "test ! -e /var/lib/containers/$id1"
103 );
104 '';
105
106})