summary refs log tree commit diff
path: root/nixos/tests/containers-imperative.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/tests/containers-imperative.nix')
-rw-r--r--nixos/tests/containers-imperative.nix166
1 files changed, 166 insertions, 0 deletions
diff --git a/nixos/tests/containers-imperative.nix b/nixos/tests/containers-imperative.nix
new file mode 100644
index 00000000000..14001657bee
--- /dev/null
+++ b/nixos/tests/containers-imperative.nix
@@ -0,0 +1,166 @@
+import ./make-test-python.nix ({ pkgs, lib, ... }: {
+  name = "containers-imperative";
+  meta = {
+    maintainers = with lib.maintainers; [ aristid aszlig eelco kampfschlaefer ];
+  };
+
+  machine =
+    { config, pkgs, lib, ... }:
+    { imports = [ ../modules/installer/cd-dvd/channel.nix ];
+
+      # XXX: Sandbox setup fails while trying to hardlink files from the host's
+      #      store file system into the prepared chroot directory.
+      nix.settings.sandbox = false;
+      nix.settings.substituters = []; # don't try to access cache.nixos.org
+
+      virtualisation.writableStore = true;
+      # Make sure we always have all the required dependencies for creating a
+      # container available within the VM, because we don't have network access.
+      virtualisation.additionalPaths = let
+        emptyContainer = import ../lib/eval-config.nix {
+          inherit (config.nixpkgs.localSystem) system;
+          modules = lib.singleton {
+            containers.foo.config = {
+              system.stateVersion = "18.03";
+            };
+          };
+        };
+      in with pkgs; [
+        stdenv stdenvNoCC emptyContainer.config.containers.foo.path
+        libxslt desktop-file-utils texinfo docbook5 libxml2
+        docbook_xsl_ns xorg.lndir documentation-highlighter
+      ];
+    };
+
+  testScript = let
+      tmpfilesContainerConfig = pkgs.writeText "container-config-tmpfiles" ''
+        {
+          systemd.tmpfiles.rules = [ "d /foo - - - - -" ];
+          systemd.services.foo = {
+            serviceConfig.Type = "oneshot";
+            script = "ls -al /foo";
+            wantedBy = [ "multi-user.target" ];
+          };
+        }
+      '';
+      brokenCfg = pkgs.writeText "broken.nix" ''
+        {
+          assertions = [
+            { assertion = false;
+              message = "I never evaluate";
+            }
+          ];
+        }
+      '';
+    in ''
+      with subtest("Make sure we have a NixOS tree (required by ‘nixos-container create’)"):
+          machine.succeed("PAGER=cat nix-env -qa -A nixos.hello >&2")
+
+      id1, id2 = None, None
+
+      with subtest("Create some containers imperatively"):
+          id1 = machine.succeed("nixos-container create foo --ensure-unique-name").rstrip()
+          machine.log(f"created container {id1}")
+
+          id2 = machine.succeed("nixos-container create foo --ensure-unique-name").rstrip()
+          machine.log(f"created container {id2}")
+
+          assert id1 != id2
+
+      with subtest(f"Put the root of {id2} into a bind mount"):
+          machine.succeed(
+              f"mv /var/lib/containers/{id2} /id2-bindmount",
+              f"mount --bind /id2-bindmount /var/lib/containers/{id1}",
+          )
+
+          ip1 = machine.succeed(f"nixos-container show-ip {id1}").rstrip()
+          ip2 = machine.succeed(f"nixos-container show-ip {id2}").rstrip()
+          assert ip1 != ip2
+
+      with subtest(
+          "Create a directory and a file we can later check if it still exists "
+          + "after destruction of the container"
+      ):
+          machine.succeed("mkdir /nested-bindmount")
+          machine.succeed("echo important data > /nested-bindmount/dummy")
+
+      with subtest(
+          "Create a directory with a dummy file and bind-mount it into both containers."
+      ):
+          for id in id1, id2:
+              important_path = f"/var/lib/containers/{id}/very/important/data"
+              machine.succeed(
+                  f"mkdir -p {important_path}",
+                  f"mount --bind /nested-bindmount {important_path}",
+              )
+
+      with subtest("Start one of them"):
+          machine.succeed(f"nixos-container start {id1}")
+
+      with subtest("Execute commands via the root shell"):
+          assert "Linux" in machine.succeed(f"nixos-container run {id1} -- uname")
+
+      with subtest("Execute a nix command via the root shell. (regression test for #40355)"):
+          machine.succeed(
+              f"nixos-container run {id1} -- nix-instantiate -E "
+              + '\'derivation { name = "empty"; builder = "false"; system = "false"; }\' '
+          )
+
+      with subtest("Stop and start (regression test for #4989)"):
+          machine.succeed(f"nixos-container stop {id1}")
+          machine.succeed(f"nixos-container start {id1}")
+
+      # clear serial backlog for next tests
+      machine.succeed("logger eat console backlog 3ea46eb2-7f82-4f70-b810-3f00e3dd4c4d")
+      machine.wait_for_console_text(
+          "eat console backlog 3ea46eb2-7f82-4f70-b810-3f00e3dd4c4d"
+      )
+
+      with subtest("Stop a container early"):
+          machine.succeed(f"nixos-container stop {id1}")
+          machine.succeed(f"nixos-container start {id1} >&2 &")
+          machine.wait_for_console_text("Stage 2")
+          machine.succeed(f"nixos-container stop {id1}")
+          machine.wait_for_console_text(f"Container {id1} exited successfully")
+          machine.succeed(f"nixos-container start {id1}")
+
+      with subtest("Stop a container without machined (regression test for #109695)"):
+          machine.systemctl("stop systemd-machined")
+          machine.succeed(f"nixos-container stop {id1}")
+          machine.wait_for_console_text(f"Container {id1} has been shut down")
+          machine.succeed(f"nixos-container start {id1}")
+
+      with subtest("tmpfiles are present"):
+          machine.log("creating container tmpfiles")
+          machine.succeed(
+              "nixos-container create tmpfiles --config-file ${tmpfilesContainerConfig}"
+          )
+          machine.log("created, starting…")
+          machine.succeed("nixos-container start tmpfiles")
+          machine.log("done starting, investigating…")
+          machine.succeed(
+              "echo $(nixos-container run tmpfiles -- systemctl is-active foo.service) | grep -q active;"
+          )
+          machine.succeed("nixos-container destroy tmpfiles")
+
+      with subtest("Execute commands via the root shell"):
+          assert "Linux" in machine.succeed(f"nixos-container run {id1} -- uname")
+
+      with subtest("Destroy the containers"):
+          for id in id1, id2:
+              machine.succeed(f"nixos-container destroy {id}")
+
+      with subtest("Check whether destruction of any container has killed important data"):
+          machine.succeed("grep -qF 'important data' /nested-bindmount/dummy")
+
+      with subtest("Ensure that the container path is gone"):
+          print(machine.succeed("ls -lsa /var/lib/containers"))
+          machine.succeed(f"test ! -e /var/lib/containers/{id1}")
+
+      with subtest("Ensure that a failed container creation doesn'leave any state"):
+          machine.fail(
+              "nixos-container create b0rk --config-file ${brokenCfg}"
+          )
+          machine.succeed("test ! -e /var/lib/containers/b0rk")
+    '';
+})