nixosTests.docker{rootless,registry,tools-overlay,tools-cross}: migrate to runTest (#395516)

This commit is contained in:
Gaétan Lepage
2025-04-03 00:29:39 +02:00
committed by GitHub
6 changed files with 249 additions and 263 deletions
+5 -5
View File
@@ -369,13 +369,13 @@ in
dnscrypt-proxy2 = handleTestOn [ "x86_64-linux" ] ./dnscrypt-proxy2.nix { };
dnsdist = import ./dnsdist.nix { inherit pkgs runTest; };
doas = runTest ./doas.nix;
docker = handleTestOn [ "aarch64-linux" "x86_64-linux" ] ./docker.nix { };
docker-rootless = handleTestOn [ "aarch64-linux" "x86_64-linux" ] ./docker-rootless.nix { };
docker-registry = handleTest ./docker-registry.nix { };
docker = runTestOn [ "aarch64-linux" "x86_64-linux" ] ./docker.nix;
docker-rootless = runTestOn [ "aarch64-linux" "x86_64-linux" ] ./docker-rootless.nix;
docker-registry = runTest ./docker-registry.nix;
docker-tools = handleTestOn [ "x86_64-linux" ] ./docker-tools.nix { };
docker-tools-nix-shell = runTest ./docker-tools-nix-shell.nix;
docker-tools-cross = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./docker-tools-cross.nix { };
docker-tools-overlay = handleTestOn [ "x86_64-linux" ] ./docker-tools-overlay.nix { };
docker-tools-cross = runTestOn [ "x86_64-linux" "aarch64-linux" ] ./docker-tools-cross.nix;
docker-tools-overlay = runTestOn [ "x86_64-linux" ] ./docker-tools-overlay.nix;
docling-serve = runTest ./docling-serve.nix;
documize = handleTest ./documize.nix { };
documentation = pkgs.callPackage ../modules/misc/documentation/test.nix { inherit nixosLib; };
+60 -63
View File
@@ -1,74 +1,71 @@
# This test runs docker-registry and check if it works
{ pkgs, ... }:
{
name = "docker-registry";
meta = with pkgs.lib.maintainers; {
maintainers = [
globin
ironpinguin
cafkafk
];
};
import ./make-test-python.nix (
{ pkgs, ... }:
{
name = "docker-registry";
meta = with pkgs.lib.maintainers; {
maintainers = [
globin
ironpinguin
cafkafk
];
};
nodes = {
registry =
{ ... }:
{
services.dockerRegistry.enable = true;
services.dockerRegistry.enableDelete = true;
services.dockerRegistry.port = 8080;
services.dockerRegistry.listenAddress = "0.0.0.0";
services.dockerRegistry.enableGarbageCollect = true;
services.dockerRegistry.openFirewall = true;
};
nodes = {
registry =
{ ... }:
{
services.dockerRegistry.enable = true;
services.dockerRegistry.enableDelete = true;
services.dockerRegistry.port = 8080;
services.dockerRegistry.listenAddress = "0.0.0.0";
services.dockerRegistry.enableGarbageCollect = true;
services.dockerRegistry.openFirewall = true;
};
client1 =
{ ... }:
{
virtualisation.docker.enable = true;
virtualisation.docker.extraOptions = "--insecure-registry registry:8080";
};
client1 =
{ ... }:
{
virtualisation.docker.enable = true;
virtualisation.docker.extraOptions = "--insecure-registry registry:8080";
};
client2 =
{ ... }:
{
virtualisation.docker.enable = true;
virtualisation.docker.extraOptions = "--insecure-registry registry:8080";
};
};
client2 =
{ ... }:
{
virtualisation.docker.enable = true;
virtualisation.docker.extraOptions = "--insecure-registry registry:8080";
};
};
testScript = ''
client1.start()
client1.wait_for_unit("docker.service")
client1.succeed("tar cv --files-from /dev/null | docker import - scratch")
client1.succeed("docker tag scratch registry:8080/scratch")
testScript = ''
client1.start()
client1.wait_for_unit("docker.service")
client1.succeed("tar cv --files-from /dev/null | docker import - scratch")
client1.succeed("docker tag scratch registry:8080/scratch")
registry.start()
registry.wait_for_unit("docker-registry.service")
registry.wait_for_open_port(8080)
client1.succeed("docker push registry:8080/scratch")
registry.start()
registry.wait_for_unit("docker-registry.service")
registry.wait_for_open_port(8080)
client1.succeed("docker push registry:8080/scratch")
client2.start()
client2.wait_for_unit("docker.service")
client2.succeed("docker pull registry:8080/scratch")
client2.succeed("docker images | grep scratch")
client2.start()
client2.wait_for_unit("docker.service")
client2.succeed("docker pull registry:8080/scratch")
client2.succeed("docker images | grep scratch")
client2.succeed(
"curl -fsS -X DELETE registry:8080/v2/scratch/manifests/$(curl -fsS -I -H\"Accept: application/vnd.docker.distribution.manifest.v2+json\" registry:8080/v2/scratch/manifests/latest | grep Docker-Content-Digest | sed -e 's/Docker-Content-Digest: //' | tr -d '\\r')"
)
client2.succeed(
"curl -fsS -X DELETE registry:8080/v2/scratch/manifests/$(curl -fsS -I -H\"Accept: application/vnd.docker.distribution.manifest.v2+json\" registry:8080/v2/scratch/manifests/latest | grep Docker-Content-Digest | sed -e 's/Docker-Content-Digest: //' | tr -d '\\r')"
)
registry.systemctl("start docker-registry-garbage-collect.service")
registry.wait_until_fails("systemctl status docker-registry-garbage-collect.service")
registry.wait_for_unit("docker-registry.service")
registry.systemctl("start docker-registry-garbage-collect.service")
registry.wait_until_fails("systemctl status docker-registry-garbage-collect.service")
registry.wait_for_unit("docker-registry.service")
registry.fail("ls -l /var/lib/docker-registry/docker/registry/v2/blobs/sha256/*/*/data")
registry.fail("ls -l /var/lib/docker-registry/docker/registry/v2/blobs/sha256/*/*/data")
client1.succeed("docker push registry:8080/scratch")
registry.succeed(
"ls -l /var/lib/docker-registry/docker/registry/v2/blobs/sha256/*/*/data"
)
'';
}
)
client1.succeed("docker push registry:8080/scratch")
registry.succeed(
"ls -l /var/lib/docker-registry/docker/registry/v2/blobs/sha256/*/*/data"
)
'';
}
+41 -44
View File
@@ -1,51 +1,48 @@
# This test runs docker and checks if simple container starts
{ lib, pkgs, ... }:
{
name = "docker-rootless";
meta = with pkgs.lib.maintainers; {
maintainers = [ abbradar ];
};
import ./make-test-python.nix (
{ lib, pkgs, ... }:
{
name = "docker-rootless";
meta = with pkgs.lib.maintainers; {
maintainers = [ abbradar ];
};
nodes = {
machine =
{ pkgs, ... }:
{
virtualisation.docker.rootless.enable = true;
nodes = {
machine =
{ pkgs, ... }:
{
virtualisation.docker.rootless.enable = true;
users.users.alice = {
uid = 1000;
isNormalUser = true;
};
users.users.alice = {
uid = 1000;
isNormalUser = true;
};
};
};
};
testScript =
{ nodes, ... }:
let
user = nodes.machine.config.users.users.alice;
sudo = lib.concatStringsSep " " [
"XDG_RUNTIME_DIR=/run/user/${toString user.uid}"
"DOCKER_HOST=unix:///run/user/${toString user.uid}/docker.sock"
"sudo"
"--preserve-env=XDG_RUNTIME_DIR,DOCKER_HOST"
"-u"
"alice"
];
in
''
machine.wait_for_unit("multi-user.target")
testScript =
{ nodes, ... }:
let
user = nodes.machine.config.users.users.alice;
sudo = lib.concatStringsSep " " [
"XDG_RUNTIME_DIR=/run/user/${toString user.uid}"
"DOCKER_HOST=unix:///run/user/${toString user.uid}/docker.sock"
"sudo"
"--preserve-env=XDG_RUNTIME_DIR,DOCKER_HOST"
"-u"
"alice"
];
in
''
machine.wait_for_unit("multi-user.target")
machine.succeed("loginctl enable-linger alice")
machine.wait_until_succeeds("${sudo} systemctl --user is-active docker.service")
machine.succeed("loginctl enable-linger alice")
machine.wait_until_succeeds("${sudo} systemctl --user is-active docker.service")
machine.succeed("tar cv --files-from /dev/null | ${sudo} docker import - scratchimg")
machine.succeed(
"${sudo} docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
)
machine.succeed("${sudo} docker ps | grep sleeping")
machine.succeed("${sudo} docker stop sleeping")
'';
}
)
machine.succeed("tar cv --files-from /dev/null | ${sudo} docker import - scratchimg")
machine.succeed(
"${sudo} docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
)
machine.succeed("${sudo} docker ps | grep sleeping")
machine.succeed("${sudo} docker stop sleeping")
'';
}
+66 -68
View File
@@ -2,83 +2,81 @@
# tests that _include_ running the result are separate. That way, most people
# can run the majority of the test suite without the extra setup.
import ./make-test-python.nix (
{ pkgs, ... }:
let
{ pkgs, ... }:
let
remoteSystem =
if pkgs.stdenv.hostPlatform.system == "aarch64-linux" then "x86_64-linux" else "aarch64-linux";
remoteSystem =
if pkgs.stdenv.hostPlatform.system == "aarch64-linux" then "x86_64-linux" else "aarch64-linux";
remoteCrossPkgs =
import ../.. # nixpkgs
{
# NOTE: This is the machine that runs the build - local from the
# 'perspective' of the build script.
localSystem = remoteSystem;
remoteCrossPkgs =
import ../.. # nixpkgs
{
# NOTE: This is the machine that runs the build - local from the
# 'perspective' of the build script.
localSystem = remoteSystem;
# NOTE: Since this file can't control where the test will be _run_ we don't
# cross-compile _to_ a different system but _from_ a different system
crossSystem = pkgs.stdenv.hostPlatform.system;
};
hello1 = remoteCrossPkgs.dockerTools.buildImage {
name = "hello1";
tag = "latest";
copyToRoot = remoteCrossPkgs.buildEnv {
name = "image-root";
pathsToLink = [ "/bin" ];
paths = [ remoteCrossPkgs.hello ];
# NOTE: Since this file can't control where the test will be _run_ we don't
# cross-compile _to_ a different system but _from_ a different system
crossSystem = pkgs.stdenv.hostPlatform.system;
};
};
hello2 = remoteCrossPkgs.dockerTools.buildLayeredImage {
name = "hello2";
tag = "latest";
contents = remoteCrossPkgs.hello;
hello1 = remoteCrossPkgs.dockerTools.buildImage {
name = "hello1";
tag = "latest";
copyToRoot = remoteCrossPkgs.buildEnv {
name = "image-root";
pathsToLink = [ "/bin" ];
paths = [ remoteCrossPkgs.hello ];
};
};
in
{
name = "docker-tools";
meta = with pkgs.lib.maintainers; {
maintainers = [ roberth ];
};
hello2 = remoteCrossPkgs.dockerTools.buildLayeredImage {
name = "hello2";
tag = "latest";
contents = remoteCrossPkgs.hello;
};
nodes = {
docker =
{ ... }:
{
virtualisation = {
diskSize = 2048;
docker.enable = true;
};
in
{
name = "docker-tools";
meta = with pkgs.lib.maintainers; {
maintainers = [ roberth ];
};
nodes = {
docker =
{ ... }:
{
virtualisation = {
diskSize = 2048;
docker.enable = true;
};
};
};
};
testScript = ''
docker.wait_for_unit("sockets.target")
testScript = ''
docker.wait_for_unit("sockets.target")
with subtest("Ensure cross compiled buildImage image can run."):
docker.succeed(
"docker load --input='${hello1}'"
)
assert "Hello, world!" in docker.succeed(
"docker run --rm ${hello1.imageName} hello",
)
docker.succeed(
"docker rmi ${hello1.imageName}",
)
with subtest("Ensure cross compiled buildImage image can run."):
docker.succeed(
"docker load --input='${hello1}'"
)
assert "Hello, world!" in docker.succeed(
"docker run --rm ${hello1.imageName} hello",
)
docker.succeed(
"docker rmi ${hello1.imageName}",
)
with subtest("Ensure cross compiled buildLayeredImage image can run."):
docker.succeed(
"docker load --input='${hello2}'"
)
assert "Hello, world!" in docker.succeed(
"docker run --rm ${hello2.imageName} hello",
)
docker.succeed(
"docker rmi ${hello2.imageName}",
)
'';
}
)
with subtest("Ensure cross compiled buildLayeredImage image can run."):
docker.succeed(
"docker load --input='${hello2}'"
)
assert "Hello, world!" in docker.succeed(
"docker run --rm ${hello2.imageName} hello",
)
docker.succeed(
"docker rmi ${hello2.imageName}",
)
'';
}
+30 -33
View File
@@ -1,38 +1,35 @@
# this test creates a simple GNU image with docker tools and sees if it executes
{ pkgs, ... }:
{
name = "docker-tools-overlay";
meta = with pkgs.lib.maintainers; {
maintainers = [
lnl7
roberth
];
};
import ./make-test-python.nix (
{ pkgs, ... }:
{
name = "docker-tools-overlay";
meta = with pkgs.lib.maintainers; {
maintainers = [
lnl7
roberth
];
};
nodes = {
docker =
{ ... }:
{
virtualisation.docker.enable = true;
virtualisation.docker.storageDriver = "overlay2";
};
};
nodes = {
docker =
{ ... }:
{
virtualisation.docker.enable = true;
virtualisation.docker.storageDriver = "overlay2";
};
};
testScript = ''
docker.wait_for_unit("sockets.target")
testScript = ''
docker.wait_for_unit("sockets.target")
docker.succeed(
"docker load --input='${pkgs.dockerTools.examples.bash}'",
"docker run --rm ${pkgs.dockerTools.examples.bash.imageName} bash --version",
)
docker.succeed(
"docker load --input='${pkgs.dockerTools.examples.bash}'",
"docker run --rm ${pkgs.dockerTools.examples.bash.imageName} bash --version",
)
# Check if the nix store has correct user permissions depending on what
# storage driver is used, incorrectly built images can show up as readonly.
# drw------- 3 0 0 3 Apr 14 11:36 /nix
# drw------- 99 0 0 100 Apr 14 11:36 /nix/store
docker.succeed("docker run --rm -u 1000:1000 ${pkgs.dockerTools.examples.bash.imageName} bash --version")
'';
}
)
# Check if the nix store has correct user permissions depending on what
# storage driver is used, incorrectly built images can show up as readonly.
# drw------- 3 0 0 3 Apr 14 11:36 /nix
# drw------- 99 0 0 100 Apr 14 11:36 /nix/store
docker.succeed("docker run --rm -u 1000:1000 ${pkgs.dockerTools.examples.bash.imageName} bash --version")
'';
}
+47 -50
View File
@@ -1,59 +1,56 @@
# This test runs docker and checks if simple container starts
{ pkgs, ... }:
{
name = "docker";
meta = with pkgs.lib.maintainers; {
maintainers = [
nequissimus
offline
];
};
import ./make-test-python.nix (
{ pkgs, ... }:
{
name = "docker";
meta = with pkgs.lib.maintainers; {
maintainers = [
nequissimus
offline
];
};
nodes = {
docker =
{ pkgs, ... }:
{
virtualisation.docker.enable = true;
virtualisation.docker.autoPrune.enable = true;
virtualisation.docker.package = pkgs.docker;
nodes = {
docker =
{ pkgs, ... }:
{
virtualisation.docker.enable = true;
virtualisation.docker.autoPrune.enable = true;
virtualisation.docker.package = pkgs.docker;
users.users = {
noprivs = {
isNormalUser = true;
description = "Can't access the docker daemon";
password = "foobar";
};
users.users = {
noprivs = {
isNormalUser = true;
description = "Can't access the docker daemon";
password = "foobar";
};
hasprivs = {
isNormalUser = true;
description = "Can access the docker daemon";
password = "foobar";
extraGroups = [ "docker" ];
};
hasprivs = {
isNormalUser = true;
description = "Can access the docker daemon";
password = "foobar";
extraGroups = [ "docker" ];
};
};
};
};
};
testScript = ''
start_all()
testScript = ''
start_all()
docker.wait_for_unit("sockets.target")
docker.succeed("tar cv --files-from /dev/null | docker import - scratchimg")
docker.succeed(
"docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
)
docker.succeed("docker ps | grep sleeping")
docker.succeed("sudo -u hasprivs docker ps")
docker.fail("sudo -u noprivs docker ps")
docker.succeed("docker stop sleeping")
docker.wait_for_unit("sockets.target")
docker.succeed("tar cv --files-from /dev/null | docker import - scratchimg")
docker.succeed(
"docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
)
docker.succeed("docker ps | grep sleeping")
docker.succeed("sudo -u hasprivs docker ps")
docker.fail("sudo -u noprivs docker ps")
docker.succeed("docker stop sleeping")
# Must match version 4 times to ensure client and server git commits and versions are correct
docker.succeed('[ $(docker version | grep ${pkgs.docker.version} | wc -l) = "4" ]')
docker.succeed("systemctl restart systemd-sysctl")
docker.succeed("grep 1 /proc/sys/net/ipv4/conf/all/forwarding")
docker.succeed("grep 1 /proc/sys/net/ipv4/conf/default/forwarding")
'';
}
)
# Must match version 4 times to ensure client and server git commits and versions are correct
docker.succeed('[ $(docker version | grep ${pkgs.docker.version} | wc -l) = "4" ]')
docker.succeed("systemctl restart systemd-sysctl")
docker.succeed("grep 1 /proc/sys/net/ipv4/conf/all/forwarding")
docker.succeed("grep 1 /proc/sys/net/ipv4/conf/default/forwarding")
'';
}