depot/third_party/nixpkgs/nixos/tests/containers-imperative.nix

171 lines
6.8 KiB
Nix
Raw Normal View History

import ./make-test-python.nix ({ pkgs, lib, ... }: {
name = "containers-imperative";
meta = {
maintainers = with lib.maintainers; [ aristid aszlig eelco kampfschlaefer ];
};
nodes.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.memorySize = 2048;
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 {
modules = lib.singleton {
nixpkgs = { inherit (config.nixpkgs) localSystem; };
containers.foo.config = {};
};
# The system is inherited from the host above.
# Set it to null, to remove the "legacy" entrypoint's non-hermetic default.
system = null;
};
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/nixos-containers/{id2} /id2-bindmount",
f"mount --bind /id2-bindmount /var/lib/nixos-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/nixos-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/nixos-containers"))
machine.succeed(f"test ! -e /var/lib/nixos-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/nixos-containers/b0rk")
'';
})