From f1b5c6876bc570ff9ac79410d8e47aadcb9aed52 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 27 Nov 2022 16:38:34 +0100 Subject: Add tests for auto-uid-allocation, uid-range and cgroups --- tests/containers.nix | 68 +++++++++++++++++++++++++++++++++++++++++++ tests/id-test.nix | 8 ++++++ tests/systemd-nspawn.nix | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 tests/containers.nix create mode 100644 tests/id-test.nix create mode 100644 tests/systemd-nspawn.nix (limited to 'tests') diff --git a/tests/containers.nix b/tests/containers.nix new file mode 100644 index 000000000..d1e791b8c --- /dev/null +++ b/tests/containers.nix @@ -0,0 +1,68 @@ +# Test whether we can run a NixOS container inside a Nix build using systemd-nspawn. +{ nixpkgs, system, overlay }: + +with import (nixpkgs + "/nixos/lib/testing-python.nix") { + inherit system; + extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ]; +}; + +makeTest ({ + name = "containers"; + + nodes = + { + host = + { config, lib, pkgs, nodes, ... }: + { virtualisation.writableStore = true; + virtualisation.diskSize = 2048; + virtualisation.additionalPaths = + [ pkgs.stdenv + (import ./systemd-nspawn.nix { inherit nixpkgs; }).toplevel + ]; + virtualisation.memorySize = 4096; + nix.binaryCaches = lib.mkForce [ ]; + nix.extraOptions = + '' + extra-experimental-features = nix-command auto-allocate-uids + extra-system-features = uid-range + ''; + nix.nixPath = [ "nixpkgs=${nixpkgs}" ]; + }; + }; + + testScript = { nodes }: '' + start_all() + + host.succeed("nix --version >&2") + + # Test that 'id' gives the expected result in various configurations. + + # Existing UIDs, sandbox. + host.succeed("nix build --no-auto-allocate-uids --sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-1") + host.succeed("[[ $(cat ./result) = 'uid=1000(nixbld) gid=100(nixbld) groups=100(nixbld)' ]]") + + # Existing UIDs, no sandbox. + host.succeed("nix build --no-auto-allocate-uids --no-sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-2") + host.succeed("[[ $(cat ./result) = 'uid=30001(nixbld1) gid=30000(nixbld) groups=30000(nixbld)' ]]") + + # Auto-allocated UIDs, sandbox. + host.succeed("nix build --auto-allocate-uids --sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-3") + host.succeed("[[ $(cat ./result) = 'uid=1000(nixbld) gid=100(nixbld) groups=100(nixbld)' ]]") + + # Auto-allocated UIDs, no sandbox. + host.succeed("nix build --auto-allocate-uids --no-sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-4") + host.succeed("[[ $(cat ./result) = 'uid=872415232 gid=30000(nixbld) groups=30000(nixbld)' ]]") + + # Auto-allocated UIDs, UID range, sandbox. + host.succeed("nix build --auto-allocate-uids --sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-5 --arg uidRange true") + host.succeed("[[ $(cat ./result) = 'uid=0(root) gid=0(root) groups=0(root)' ]]") + + # Auto-allocated UIDs, UID range, no sandbox. + host.fail("nix build --auto-allocate-uids --no-sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-6 --arg uidRange true") + + # Run systemd-nspawn in a Nix build. + host.succeed("nix build --auto-allocate-uids --sandbox -L --offline --impure --file ${./systemd-nspawn.nix} --argstr nixpkgs ${nixpkgs}") + host.succeed("[[ $(cat ./result/msg) = 'Hello World' ]]") + ''; + +}) diff --git a/tests/id-test.nix b/tests/id-test.nix new file mode 100644 index 000000000..8eb9d38f9 --- /dev/null +++ b/tests/id-test.nix @@ -0,0 +1,8 @@ +{ name, uidRange ? false }: + +with import {}; + +runCommand name + { requiredSystemFeatures = if uidRange then ["uid-range"] else []; + } + "id; id > $out" diff --git a/tests/systemd-nspawn.nix b/tests/systemd-nspawn.nix new file mode 100644 index 000000000..49944eba3 --- /dev/null +++ b/tests/systemd-nspawn.nix @@ -0,0 +1,75 @@ +{ nixpkgs }: + +let + + machine = { config, pkgs, ... }: + { + system.stateVersion = "22.05"; + boot.isContainer = true; + systemd.services.console-getty.enable = false; + networking.dhcpcd.enable = false; + + services.httpd = { + enable = true; + adminAddr = "nixos@example.org"; + }; + + systemd.services.test = { + wantedBy = [ "multi-user.target" ]; + after = [ "httpd.service" ]; + script = '' + source /.env + echo "Hello World" > $out/msg + ls -lR /dev > $out/dev + ${pkgs.curl}/bin/curl -sS --fail http://localhost/ > $out/page.html + ''; + unitConfig = { + FailureAction = "exit-force"; + FailureActionExitStatus = 42; + SuccessAction = "exit-force"; + }; + }; + }; + + config = (import (nixpkgs + "/nixos/lib/eval-config.nix") { + modules = [ machine ]; + }).config; + +in + +with import nixpkgs {}; + +runCommand "test" + { buildInputs = [ config.system.path ]; + requiredSystemFeatures = [ "uid-range" ]; + toplevel = config.system.build.toplevel; + } + '' + root=$(pwd)/root + mkdir -p $root $root/etc + + export > $root/.env + + # Make /run a tmpfs to shut up a systemd warning. + mkdir /run + mount -t tmpfs none /run + chmod 0700 /run + + mount -t cgroup2 none /sys/fs/cgroup + + mkdir -p $out + + touch /etc/os-release + echo a5ea3f98dedc0278b6f3cc8c37eeaeac > /etc/machine-id + + SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=1 \ + ${config.systemd.package}/bin/systemd-nspawn \ + --keep-unit \ + -M ${config.networking.hostName} -D "$root" \ + --register=no \ + --resolv-conf=off \ + --bind-ro=/nix/store \ + --bind=$out \ + --private-network \ + $toplevel/init + '' -- cgit v1.2.3 From fc1458561086a6cf2c1311294c9089785288aea3 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 27 Nov 2022 18:58:21 +0100 Subject: Fix evaluation --- tests/systemd-nspawn.nix | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/systemd-nspawn.nix b/tests/systemd-nspawn.nix index 49944eba3..424436b3f 100644 --- a/tests/systemd-nspawn.nix +++ b/tests/systemd-nspawn.nix @@ -31,13 +31,16 @@ let }; }; - config = (import (nixpkgs + "/nixos/lib/eval-config.nix") { + cfg = (import (nixpkgs + "/nixos/lib/eval-config.nix") { modules = [ machine ]; - }).config; + system = "x86_64-linux"; + }); + + config = cfg.config; in -with import nixpkgs {}; +with cfg._module.args.pkgs; runCommand "test" { buildInputs = [ config.system.path ]; -- cgit v1.2.3 From 67bcb99700a0da1395fa063d7c6586740b304598 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 28 Nov 2022 21:54:02 +0100 Subject: Add a setting for enabling cgroups --- tests/containers.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/containers.nix b/tests/containers.nix index d1e791b8c..59e953c3b 100644 --- a/tests/containers.nix +++ b/tests/containers.nix @@ -23,7 +23,7 @@ makeTest ({ nix.binaryCaches = lib.mkForce [ ]; nix.extraOptions = '' - extra-experimental-features = nix-command auto-allocate-uids + extra-experimental-features = nix-command auto-allocate-uids cgroups extra-system-features = uid-range ''; nix.nixPath = [ "nixpkgs=${nixpkgs}" ]; -- cgit v1.2.3 From f1e1ba9fe094a774f0fd05e537228e628d0bc8cb Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 1 Dec 2022 16:29:09 +0100 Subject: Really fix 'nix store make-content-addressed --json' https://hydra.nixos.org/log/mcgypcf9vj4n8vdmw7lj3l05c899v73w-nix-2.12.0pre20221201_16b03f0-x86_64-unknown-linux-musl.drv --- tests/fetchClosure.sh | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/tests/fetchClosure.sh b/tests/fetchClosure.sh index 44050c878..d88c55c3c 100644 --- a/tests/fetchClosure.sh +++ b/tests/fetchClosure.sh @@ -1,7 +1,6 @@ source common.sh enableFeatures "fetch-closure" -needLocalStore "'--no-require-sigs' can’t be used with the daemon" clearStore clearCacheCache @@ -28,15 +27,19 @@ clearStore [ ! -e $nonCaPath ] [ -e $caPath ] -# In impure mode, we can use non-CA paths. -[[ $(nix eval --raw --no-require-sigs --impure --expr " - builtins.fetchClosure { - fromStore = \"file://$cacheDir\"; - fromPath = $nonCaPath; - } -") = $nonCaPath ]] +if [[ "$NIX_REMOTE" != "daemon" ]]; then + + # In impure mode, we can use non-CA paths. + [[ $(nix eval --raw --no-require-sigs --impure --expr " + builtins.fetchClosure { + fromStore = \"file://$cacheDir\"; + fromPath = $nonCaPath; + } + ") = $nonCaPath ]] + + [ -e $nonCaPath ] -[ -e $nonCaPath ] +fi # 'toPath' set to empty string should fail but print the expected path. nix eval -v --json --expr " -- cgit v1.2.3 From 08dcd22582d65e73f29df79b3765e76cea8f3314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Na=C3=AFm=20Favier?= Date: Tue, 6 Dec 2022 16:36:42 +0100 Subject: tests: don't refer to TMPDIR --- tests/check.nix | 2 +- tests/check.sh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/check.nix b/tests/check.nix index ed91ff845..ddab8eea9 100644 --- a/tests/check.nix +++ b/tests/check.nix @@ -44,7 +44,7 @@ with import ./config.nix; }; hashmismatch = import { - url = "file://" + builtins.getEnv "TMPDIR" + "/dummy"; + url = "file://" + builtins.getEnv "TEST_ROOT" + "/dummy"; sha256 = "0mdqa9w1p6cmli6976v4wi0sw9r4p5prkj7lzfd1877wk11c9c73"; }; diff --git a/tests/check.sh b/tests/check.sh index 495202781..fbd784fc5 100644 --- a/tests/check.sh +++ b/tests/check.sh @@ -91,13 +91,13 @@ nix-build check.nix -A fetchurl --no-out-link --check nix-build check.nix -A fetchurl --no-out-link --repair [[ $(cat $path) != foo ]] -echo 'Hello World' > $TMPDIR/dummy +echo 'Hello World' > $TEST_ROOT/dummy nix-build check.nix -A hashmismatch --no-out-link || status=$? [ "$status" = "102" ] -echo -n > $TMPDIR/dummy +echo -n > $TEST_ROOT/dummy nix-build check.nix -A hashmismatch --no-out-link -echo 'Hello World' > $TMPDIR/dummy +echo 'Hello World' > $TEST_ROOT/dummy nix-build check.nix -A hashmismatch --no-out-link --check || status=$? [ "$status" = "102" ] -- cgit v1.2.3 From 6f61f4667fd39d4fa2e02d18a9b818f39cbfd023 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 9 Dec 2022 17:35:40 +0100 Subject: Remove tests for --repeat https://hydra.nixos.org/build/201125739 --- tests/check.sh | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'tests') diff --git a/tests/check.sh b/tests/check.sh index fbd784fc5..e77c0405d 100644 --- a/tests/check.sh +++ b/tests/check.sh @@ -40,14 +40,6 @@ nix-build check.nix -A deterministic --argstr checkBuildId $checkBuildId \ if grep -q 'may not be deterministic' $TEST_ROOT/log; then false; fi checkBuildTempDirRemoved $TEST_ROOT/log -nix build -f check.nix deterministic --rebuild --repeat 1 \ - --argstr checkBuildId $checkBuildId --keep-failed --no-link \ - 2> $TEST_ROOT/log -if grep -q 'checking is not possible' $TEST_ROOT/log; then false; fi -# Repeat is set to 1, ie. nix should build deterministic twice. -if [ "$(grep "checking outputs" $TEST_ROOT/log | wc -l)" -ne 2 ]; then false; fi -checkBuildTempDirRemoved $TEST_ROOT/log - nix-build check.nix -A nondeterministic --argstr checkBuildId $checkBuildId \ --no-out-link 2> $TEST_ROOT/log checkBuildTempDirRemoved $TEST_ROOT/log @@ -58,12 +50,6 @@ grep 'may not be deterministic' $TEST_ROOT/log [ "$status" = "104" ] checkBuildTempDirRemoved $TEST_ROOT/log -nix build -f check.nix nondeterministic --rebuild --repeat 1 \ - --argstr checkBuildId $checkBuildId --keep-failed --no-link \ - 2> $TEST_ROOT/log || status=$? -grep 'may not be deterministic' $TEST_ROOT/log -checkBuildTempDirRemoved $TEST_ROOT/log - nix-build check.nix -A nondeterministic --argstr checkBuildId $checkBuildId \ --no-out-link --check --keep-failed 2> $TEST_ROOT/log || status=$? grep 'may not be deterministic' $TEST_ROOT/log @@ -72,12 +58,6 @@ if checkBuildTempDirRemoved $TEST_ROOT/log; then false; fi clearStore -nix-build dependencies.nix --no-out-link --repeat 3 - -nix-build check.nix -A nondeterministic --no-out-link --repeat 1 2> $TEST_ROOT/log || status=$? -[ "$status" = "1" ] -grep 'differs from previous round' $TEST_ROOT/log - path=$(nix-build check.nix -A fetchurl --no-out-link) chmod +w $path -- cgit v1.2.3