Merge pull request #74218 from tfc/nixos-test-containers-python-port

Nixos test containers python port
This commit is contained in:
Robin Gloster 2019-11-27 17:28:07 +01:00 committed by GitHub
commit 39022bc3e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 192 additions and 230 deletions

View file

@ -63,8 +63,7 @@ in rec {
#(all nixos.tests.containers)
(all nixos.tests.containers-imperative)
(all nixos.tests.containers-ipv4)
(all nixos.tests.containers-ipv6)
(all nixos.tests.containers-ip)
nixos.tests.chromium.x86_64-linux or []
(all nixos.tests.firefox)
(all nixos.tests.firewall)

View file

@ -32,8 +32,7 @@ in rec {
tests = {
inherit (nixos'.tests)
containers-imperative
containers-ipv4
containers-ipv6
containers-ip
firewall
ipv6
login

View file

@ -53,8 +53,7 @@ in
containers-extra_veth = handleTest ./containers-extra_veth.nix {};
containers-hosts = handleTest ./containers-hosts.nix {};
containers-imperative = handleTest ./containers-imperative.nix {};
containers-ipv4 = handleTest ./containers-ipv4.nix {};
containers-ipv6 = handleTest ./containers-ipv6.nix {};
containers-ip = handleTest ./containers-ip.nix {};
containers-macvlans = handleTest ./containers-macvlans.nix {};
containers-physical_interfaces = handleTest ./containers-physical_interfaces.nix {};
containers-restart_networking = handleTest ./containers-restart_networking.nix {};

View file

@ -7,7 +7,7 @@ let
containerIp6 = "fc00::2/7";
in
import ./make-test.nix ({ pkgs, ...} : {
import ./make-test-python.nix ({ pkgs, ...} : {
name = "containers-bridge";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ aristid aszlig eelco kampfschlaefer ];
@ -61,43 +61,42 @@ import ./make-test.nix ({ pkgs, ...} : {
virtualisation.pathsInNixDB = [ pkgs.stdenv ];
};
testScript =
''
$machine->waitForUnit("default.target");
$machine->succeed("nixos-container list") =~ /webserver/ or die;
testScript = ''
machine.wait_for_unit("default.target")
assert "webserver" in machine.succeed("nixos-container list")
# Start the webserver container.
$machine->succeed("nixos-container status webserver") =~ /up/ or die;
with subtest("Start the webserver container"):
assert "up" in machine.succeed("nixos-container status webserver")
# Check if bridges exist inside containers
$machine->succeed("nixos-container run webserver -- ip link show eth0");
$machine->succeed("nixos-container run web-noip -- ip link show eth0");
with subtest("Bridges exist inside containers"):
machine.succeed(
"nixos-container run webserver -- ip link show eth0",
"nixos-container run web-noip -- ip link show eth0",
)
"${containerIp}" =~ /([^\/]+)\/([0-9+])/;
my $ip = $1;
chomp $ip;
$machine->succeed("ping -n -c 1 $ip");
$machine->succeed("curl --fail http://$ip/ > /dev/null");
ip = "${containerIp}".split("/")[0]
machine.succeed(f"ping -n -c 1 {ip}")
machine.succeed(f"curl --fail http://{ip}/ > /dev/null")
"${containerIp6}" =~ /([^\/]+)\/([0-9+])/;
my $ip6 = $1;
chomp $ip6;
$machine->succeed("ping -n -c 1 $ip6");
$machine->succeed("curl --fail http://[$ip6]/ > /dev/null");
ip6 = "${containerIp6}".split("/")[0]
machine.succeed(f"ping -n -c 1 {ip6}")
machine.succeed(f"curl --fail http://[{ip6}]/ > /dev/null")
# Check that nixos-container show-ip works in case of an ipv4 address with
# subnetmask in CIDR notation.
my $result = $machine->succeed("nixos-container show-ip webserver");
chomp $result;
$result eq $ip or die;
with subtest(
"nixos-container show-ip works in case of an ipv4 address "
+ "with subnetmask in CIDR notation."
):
result = machine.succeed("nixos-container show-ip webserver").rstrip()
assert result == ip
# Stop the container.
$machine->succeed("nixos-container stop webserver");
$machine->fail("curl --fail --connect-timeout 2 http://$ip/ > /dev/null");
$machine->fail("curl --fail --connect-timeout 2 http://[$ip6]/ > /dev/null");
with subtest("Stop the container"):
machine.succeed("nixos-container stop webserver")
machine.fail(
f"curl --fail --connect-timeout 2 http://{ip}/ > /dev/null",
f"curl --fail --connect-timeout 2 http://[{ip6}]/ > /dev/null",
)
# Destroying a declarative container should fail.
$machine->fail("nixos-container destroy webserver");
machine.fail("nixos-container destroy webserver")
'';
})

View file

@ -1,6 +1,6 @@
# Test for NixOS' container support.
import ./make-test.nix ({ pkgs, ...} : {
import ./make-test-python.nix ({ pkgs, ...} : {
name = "containers-imperative";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ aristid aszlig eelco kampfschlaefer ];
@ -45,86 +45,90 @@ import ./make-test.nix ({ pkgs, ...} : {
wantedBy = [ "multi-user.target" ];
};
}
''; in
''
# Make sure we have a NixOS tree (required by nixos-container create).
$machine->succeed("PAGER=cat nix-env -qa -A nixos.hello >&2");
# Create some containers imperatively.
my $id1 = $machine->succeed("nixos-container create foo --ensure-unique-name");
chomp $id1;
$machine->log("created container $id1");
my $id2 = $machine->succeed("nixos-container create foo --ensure-unique-name");
chomp $id2;
$machine->log("created container $id2");
die if $id1 eq $id2;
# Put the root of $id2 into a bind mount.
$machine->succeed(
"mv /var/lib/containers/$id2 /id2-bindmount",
"mount --bind /id2-bindmount /var/lib/containers/$id1"
);
my $ip1 = $machine->succeed("nixos-container show-ip $id1");
chomp $ip1;
my $ip2 = $machine->succeed("nixos-container show-ip $id2");
chomp $ip2;
die if $ip1 eq $ip2;
# Create a directory and a file we can later check if it still exists
# after destruction of the container.
$machine->succeed(
"mkdir /nested-bindmount",
"echo important data > /nested-bindmount/dummy",
);
# Create a directory with a dummy file and bind-mount it into both
# containers.
foreach ($id1, $id2) {
my $importantPath = "/var/lib/containers/$_/very/important/data";
$machine->succeed(
"mkdir -p $importantPath",
"mount --bind /nested-bindmount $importantPath"
);
}
# Start one of them.
$machine->succeed("nixos-container start $id1");
# Execute commands via the root shell.
$machine->succeed("nixos-container run $id1 -- uname") =~ /Linux/ or die;
# Execute a nix command via the root shell. (regression test for #40355)
$machine->succeed("nixos-container run $id1 -- nix-instantiate -E 'derivation { name = \"empty\"; builder = \"false\"; system = \"false\"; }'");
# Stop and start (regression test for #4989)
$machine->succeed("nixos-container stop $id1");
$machine->succeed("nixos-container start $id1");
# Ensure 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");
# Execute commands via the root shell.
$machine->succeed("nixos-container run $id1 -- uname") =~ /Linux/ or die;
# Destroy the containers.
$machine->succeed("nixos-container destroy $id1");
$machine->succeed("nixos-container destroy $id2");
$machine->succeed(
# Check whether destruction of any container has killed important data
"grep -qF 'important data' /nested-bindmount/dummy",
# Ensure that the container path is gone
"test ! -e /var/lib/containers/$id1"
);
'';
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}")
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}")
'';
})

View file

@ -0,0 +1,77 @@
# Test for NixOS' container support.
let
webserverFor = hostAddress: localAddress: {
inherit hostAddress localAddress;
privateNetwork = true;
config = {
services.httpd = {
enable = true;
adminAddr = "foo@example.org";
};
networking.firewall.allowedTCPPorts = [ 80 ];
};
};
in import ./make-test-python.nix ({ pkgs, ...} : {
name = "containers-ipv4-ipv6";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ aristid aszlig eelco kampfschlaefer ];
};
machine =
{ pkgs, ... }: {
imports = [ ../modules/installer/cd-dvd/channel.nix ];
virtualisation = {
writableStore = true;
memorySize = 768;
};
containers.webserver4 = webserverFor "10.231.136.1" "10.231.136.2";
containers.webserver6 = webserverFor "fc00::2" "fc00::1";
virtualisation.pathsInNixDB = [ pkgs.stdenv ];
};
testScript = { nodes, ... }: ''
import time
def curl_host(ip):
# put [] around ipv6 addresses for curl
host = ip if ":" not in ip else f"[{ip}]"
return f"curl --fail --connect-timeout 2 http://{host}/ > /dev/null"
def get_ip(container):
# need to distinguish because show-ip won't work for ipv6
if container == "webserver4":
ip = machine.succeed(f"nixos-container show-ip {container}").rstrip()
assert ip == "${nodes.machine.config.containers.webserver4.localAddress}"
return ip
return "${nodes.machine.config.containers.webserver6.localAddress}"
for container in "webserver4", "webserver6":
assert container in machine.succeed("nixos-container list")
with subtest(f"Start container {container}"):
machine.succeed(f"nixos-container start {container}")
# wait 2s for container to start and network to be up
time.sleep(2)
# Since "start" returns after the container has reached
# multi-user.target, we should now be able to access it.
ip = get_ip(container)
with subtest(f"{container} reacts to pings and HTTP requests"):
machine.succeed(f"ping -n -c1 {ip}")
machine.succeed(curl_host(ip))
with subtest(f"Stop container {container}"):
machine.succeed(f"nixos-container stop {container}")
machine.fail(curl_host(ip))
# Destroying a declarative container should fail.
machine.fail(f"nixos-container destroy {container}")
'';
})

View file

@ -1,55 +0,0 @@
# Test for NixOS' container support.
import ./make-test.nix ({ pkgs, ...} : {
name = "containers-ipv4";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ aristid aszlig eelco kampfschlaefer ];
};
machine =
{ pkgs, ... }:
{ imports = [ ../modules/installer/cd-dvd/channel.nix ];
virtualisation.writableStore = true;
virtualisation.memorySize = 768;
containers.webserver =
{ privateNetwork = true;
hostAddress = "10.231.136.1";
localAddress = "10.231.136.2";
config =
{ services.httpd.enable = true;
services.httpd.adminAddr = "foo@example.org";
networking.firewall.allowedTCPPorts = [ 80 ];
system.stateVersion = "18.03";
};
};
virtualisation.pathsInNixDB = [ pkgs.stdenv ];
};
testScript =
''
$machine->succeed("nixos-container list") =~ /webserver/ or die;
# Start the webserver container.
$machine->succeed("nixos-container start webserver");
# wait two seconds for the container to start and the network to be up
sleep 2;
# Since "start" returns after the container has reached
# multi-user.target, we should now be able to access it.
my $ip = $machine->succeed("nixos-container show-ip webserver");
chomp $ip;
$machine->succeed("ping -n -c1 $ip");
$machine->succeed("curl --fail http://$ip/ > /dev/null");
# Stop the container.
$machine->succeed("nixos-container stop webserver");
$machine->fail("curl --fail --connect-timeout 2 http://$ip/ > /dev/null");
# Destroying a declarative container should fail.
$machine->fail("nixos-container destroy webserver");
'';
})

View file

@ -1,60 +0,0 @@
# Test for NixOS' container support.
let
hostIp = "fc00::2";
localIp = "fc00::1";
in
import ./make-test.nix ({ pkgs, ...} : {
name = "containers-ipv6";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ aristid aszlig eelco kampfschlaefer ];
};
machine =
{ pkgs, ... }:
{ imports = [ ../modules/installer/cd-dvd/channel.nix ];
virtualisation.writableStore = true;
virtualisation.memorySize = 768;
containers.webserver =
{ privateNetwork = true;
hostAddress6 = hostIp;
localAddress6 = localIp;
config =
{ services.httpd.enable = true;
services.httpd.adminAddr = "foo@example.org";
networking.firewall.allowedTCPPorts = [ 80 ];
};
};
virtualisation.pathsInNixDB = [ pkgs.stdenv ];
};
testScript =
''
$machine->waitForUnit("default.target");
$machine->succeed("nixos-container list") =~ /webserver/ or die;
# Start the webserver container.
$machine->succeed("nixos-container start webserver");
# wait two seconds for the container to start and the network to be up
sleep 2;
# Since "start" returns after the container has reached
# multi-user.target, we should now be able to access it.
my $ip = "${localIp}";
chomp $ip;
$machine->succeed("ping -n -c 1 $ip");
$machine->succeed("curl --fail http://[$ip]/ > /dev/null");
# Stop the container.
$machine->succeed("nixos-container stop webserver");
$machine->fail("curl --fail --connect-timeout 2 http://[$ip]/ > /dev/null");
# Destroying a declarative container should fail.
$machine->fail("nixos-container destroy webserver");
'';
})