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