nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{ pkgs, lib, ... }:
2{
3 name = "containers-imperative";
4 meta = {
5 maintainers = with lib.maintainers; [
6 aristid
7 aszlig
8 kampfschlaefer
9 ];
10 };
11
12 nodes.machine =
13 {
14 config,
15 pkgs,
16 lib,
17 ...
18 }:
19 {
20 imports = [ ../modules/installer/cd-dvd/channel.nix ];
21
22 # XXX: Sandbox setup fails while trying to hardlink files from the host's
23 # store file system into the prepared chroot directory.
24 nix.settings.sandbox = false;
25 nix.settings.substituters = [ ]; # don't try to access cache.nixos.org
26
27 virtualisation.memorySize = 2048;
28 virtualisation.writableStore = true;
29 # Make sure we always have all the required dependencies for creating a
30 # container available within the VM, because we don't have network access.
31 virtualisation.additionalPaths =
32 let
33 emptyContainer = import ../lib/eval-config.nix {
34 modules = lib.singleton {
35 nixpkgs.hostPlatform = { inherit (pkgs.stdenv.hostPlatform) system; };
36
37 containers.foo.config = { };
38 };
39
40 # The system is inherited from the host above.
41 # Set it to null, to remove the "legacy" entrypoint's non-hermetic default.
42 system = null;
43 };
44 in
45 with pkgs;
46 [
47 stdenv
48 stdenvNoCC
49 emptyContainer.config.containers.foo.path
50 libxslt
51 desktop-file-utils
52 texinfo
53 docbook5
54 libxml2
55 docbook_xsl_ns
56 xorg.lndir
57 documentation-highlighter
58 perlPackages.ConfigIniFiles
59 ];
60 };
61
62 testScript =
63 let
64 tmpfilesContainerConfig = pkgs.writeText "container-config-tmpfiles" ''
65 {
66 systemd.tmpfiles.rules = [ "d /foo - - - - -" ];
67 systemd.services.foo = {
68 serviceConfig.Type = "oneshot";
69 script = "ls -al /foo";
70 wantedBy = [ "multi-user.target" ];
71 };
72 }
73 '';
74 brokenCfg = pkgs.writeText "broken.nix" ''
75 {
76 assertions = [
77 { assertion = false;
78 message = "I never evaluate";
79 }
80 ];
81 }
82 '';
83 in
84 ''
85 with subtest("Make sure we have a NixOS tree (required by ‘nixos-container create’)"):
86 machine.succeed("PAGER=cat nix-env -qa -A nixos.hello >&2")
87
88 id1, id2 = None, None
89
90 with subtest("Create some containers imperatively"):
91 id1 = machine.succeed("nixos-container create foo --ensure-unique-name").rstrip()
92 machine.log(f"created container {id1}")
93
94 id2 = machine.succeed("nixos-container create foo --ensure-unique-name").rstrip()
95 machine.log(f"created container {id2}")
96
97 assert id1 != id2
98
99 with subtest(f"Put the root of {id2} into a bind mount"):
100 machine.succeed(
101 f"mv /var/lib/nixos-containers/{id2} /id2-bindmount",
102 f"mount --bind /id2-bindmount /var/lib/nixos-containers/{id1}",
103 )
104
105 ip1 = machine.succeed(f"nixos-container show-ip {id1}").rstrip()
106 ip2 = machine.succeed(f"nixos-container show-ip {id2}").rstrip()
107 assert ip1 != ip2
108
109 with subtest(
110 "Create a directory and a file we can later check if it still exists "
111 + "after destruction of the container"
112 ):
113 machine.succeed("mkdir /nested-bindmount")
114 machine.succeed("echo important data > /nested-bindmount/dummy")
115
116 with subtest(
117 "Create a directory with a dummy file and bind-mount it into both containers."
118 ):
119 for id in id1, id2:
120 important_path = f"/var/lib/nixos-containers/{id}/very/important/data"
121 machine.succeed(
122 f"mkdir -p {important_path}",
123 f"mount --bind /nested-bindmount {important_path}",
124 )
125
126 with subtest("Start one of them"):
127 machine.succeed(f"nixos-container start {id1}")
128
129 with subtest("Execute commands via the root shell"):
130 assert "Linux" in machine.succeed(f"nixos-container run {id1} -- uname")
131
132 with subtest("Execute a nix command via the root shell. (regression test for #40355)"):
133 machine.succeed(
134 f"nixos-container run {id1} -- nix-instantiate -E "
135 + '\'derivation { name = "empty"; builder = "false"; system = "false"; }\' '
136 )
137
138 with subtest("Stop and start (regression test for #4989)"):
139 machine.succeed(f"nixos-container stop {id1}")
140 machine.succeed(f"nixos-container start {id1}")
141
142 # clear serial backlog for next tests
143 machine.succeed("logger eat console backlog 3ea46eb2-7f82-4f70-b810-3f00e3dd4c4d")
144 machine.wait_for_console_text(
145 "eat console backlog 3ea46eb2-7f82-4f70-b810-3f00e3dd4c4d"
146 )
147
148 with subtest("Stop a container early"):
149 machine.succeed(f"nixos-container stop {id1}")
150 machine.succeed(f"nixos-container start {id1} >&2 &")
151 machine.wait_for_console_text("Stage 2")
152 machine.succeed(f"nixos-container stop {id1}")
153 machine.wait_for_console_text(f"Container {id1} exited successfully")
154 machine.succeed(f"nixos-container start {id1}")
155
156 with subtest("Stop a container without machined (regression test for #109695)"):
157 machine.systemctl("stop systemd-machined")
158 machine.succeed(f"nixos-container stop {id1}")
159 machine.wait_for_console_text(f"Container {id1} has been shut down")
160 machine.succeed(f"nixos-container start {id1}")
161
162 with subtest("tmpfiles are present"):
163 machine.log("creating container tmpfiles")
164 machine.succeed(
165 "nixos-container create tmpfiles --config-file ${tmpfilesContainerConfig}"
166 )
167 machine.log("created, starting…")
168 machine.succeed("nixos-container start tmpfiles")
169 machine.log("done starting, investigating…")
170 machine.succeed(
171 "echo $(nixos-container run tmpfiles -- systemctl is-active foo.service) | grep -q active;"
172 )
173 machine.succeed("nixos-container destroy tmpfiles")
174
175 with subtest("Execute commands via the root shell"):
176 assert "Linux" in machine.succeed(f"nixos-container run {id1} -- uname")
177
178 with subtest("Destroy the containers"):
179 for id in id1, id2:
180 machine.succeed(f"nixos-container destroy {id}")
181
182 with subtest("Check whether destruction of any container has killed important data"):
183 machine.succeed("grep -qF 'important data' /nested-bindmount/dummy")
184
185 with subtest("Ensure that the container path is gone"):
186 print(machine.succeed("ls -lsa /var/lib/nixos-containers"))
187 machine.succeed(f"test ! -e /var/lib/nixos-containers/{id1}")
188
189 with subtest("Ensure that a failed container creation doesn'leave any state"):
190 machine.fail(
191 "nixos-container create b0rk --config-file ${brokenCfg}"
192 )
193 machine.succeed("test ! -e /var/lib/nixos-containers/b0rk")
194 '';
195}