testing: migrate build-remote-trustless-*
Change-Id: I3edc3fe5babc93833bfe1e7c4bdeb02dc6ac17cd
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
outPath=$(readlink -f $TEST_ROOT/result)
|
||||
grep 'FOO BAR BAZ' ${remoteDir}/${outPath}
|
||||
@@ -1,29 +0,0 @@
|
||||
source common.sh
|
||||
|
||||
enableFeatures "daemon-trust-override"
|
||||
|
||||
restartDaemon
|
||||
|
||||
requireSandboxSupport
|
||||
[[ $busybox =~ busybox ]] || skipTest "no busybox"
|
||||
|
||||
unset NIX_STORE_DIR
|
||||
|
||||
# We first build a dependency of the derivation we eventually want to
|
||||
# build.
|
||||
nix-build build-hook.nix -A passthru.input2 \
|
||||
-o "$TEST_ROOT/input2" \
|
||||
--arg busybox "$busybox" \
|
||||
--store "$TEST_ROOT/local" \
|
||||
--option system-features bar
|
||||
|
||||
# Now when we go to build that downstream derivation, Lix will try to
|
||||
# copy our already-build `input2` to the remote store. That store object
|
||||
# is input-addressed, so this will fail.
|
||||
|
||||
file=build-hook.nix
|
||||
prog=$(readlink -e ./nix-daemon-untrusting.sh)
|
||||
proto=ssh-ng
|
||||
|
||||
expectStderr 1 source build-remote-trustless.sh \
|
||||
| grepQuiet "cannot add path '[^ ]*' because it lacks a signature by a trusted key"
|
||||
@@ -1,9 +0,0 @@
|
||||
source common.sh
|
||||
|
||||
# Remote trusts us
|
||||
file=build-hook.nix
|
||||
prog=nix-store
|
||||
proto=ssh
|
||||
|
||||
source build-remote-trustless.sh
|
||||
source build-remote-trustless-after.sh
|
||||
@@ -1,9 +0,0 @@
|
||||
source common.sh
|
||||
|
||||
# Remote trusts us
|
||||
file=build-hook.nix
|
||||
prog=nix-daemon
|
||||
proto=ssh-ng
|
||||
|
||||
source build-remote-trustless.sh
|
||||
source build-remote-trustless-after.sh
|
||||
@@ -1,13 +0,0 @@
|
||||
source common.sh
|
||||
|
||||
enableFeatures "daemon-trust-override"
|
||||
|
||||
restartDaemon
|
||||
|
||||
# Remote doesn't trust us
|
||||
file=build-hook.nix
|
||||
prog=$(readlink -e ./nix-daemon-untrusting.sh)
|
||||
proto=ssh-ng
|
||||
|
||||
source build-remote-trustless.sh
|
||||
source build-remote-trustless-after.sh
|
||||
@@ -1,14 +0,0 @@
|
||||
source common.sh
|
||||
|
||||
enableFeatures "daemon-trust-override"
|
||||
|
||||
restartDaemon
|
||||
|
||||
# Remote doesn't trusts us, but this is fine because we are only
|
||||
# building (fixed) CA derivations.
|
||||
file=build-hook-ca-fixed.nix
|
||||
prog=$(readlink -e ./nix-daemon-untrusting.sh)
|
||||
proto=ssh-ng
|
||||
|
||||
source build-remote-trustless.sh
|
||||
source build-remote-trustless-after.sh
|
||||
@@ -1,13 +0,0 @@
|
||||
requireSandboxSupport
|
||||
[[ $busybox =~ busybox ]] || skipTest "no busybox"
|
||||
|
||||
unset NIX_STORE_DIR
|
||||
|
||||
remoteDir=$TEST_ROOT/remote
|
||||
|
||||
# Note: ssh{-ng}://localhost bypasses ssh. See tests/functional/build-remote.sh for
|
||||
# more details.
|
||||
nix-build $file -o $TEST_ROOT/result --max-jobs 0 \
|
||||
--arg busybox $busybox \
|
||||
--store $TEST_ROOT/local \
|
||||
--builders "$proto://localhost?remote-program=$prog&remote-store=${remoteDir}%3Fsystem-features=foo%20bar%20baz - - 1 1 foo,bar,baz"
|
||||
@@ -98,11 +98,6 @@ functional_tests_scripts = [
|
||||
'dependencies.sh',
|
||||
'check-reqs.sh',
|
||||
'build-remote-content-addressed-fixed.sh',
|
||||
'build-remote-trustless-should-pass-0.sh',
|
||||
'build-remote-trustless-should-pass-1.sh',
|
||||
'build-remote-trustless-should-pass-2.sh',
|
||||
'build-remote-trustless-should-pass-3.sh',
|
||||
'build-remote-trustless-should-fail-0.sh',
|
||||
'build-jobless.sh',
|
||||
'nar-access.sh',
|
||||
'impure-eval.sh',
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
exec nix-daemon --force-untrusted "$@"
|
||||
@@ -0,0 +1,152 @@
|
||||
import pytest
|
||||
import re
|
||||
import textwrap
|
||||
from urllib.parse import urlencode, quote
|
||||
import sys
|
||||
|
||||
from functional2.testlib.fixtures.nix import Nix
|
||||
from functional2.testlib.fixtures.file_helper import with_files
|
||||
from functional2.testlib.utils import get_global_asset
|
||||
from functional2.testlib.fixtures.env import ManagedEnv
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def busybox_args(env: ManagedEnv) -> list[str]:
|
||||
return ["--arg", "busybox", env.path.which("busybox")]
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _setup_for_remote_builds(nix: Nix, env: ManagedEnv):
|
||||
# always add bash, otherwise lix can't execute the build hook
|
||||
env.path.add_program("bash")
|
||||
# we don't always use this feature, but it also doesn't hurt
|
||||
nix.settings.feature("daemon-trust-override")
|
||||
|
||||
|
||||
def _builders(proto: str, flags: list[str], env: ManagedEnv) -> str:
|
||||
prog = "nix-store" if proto == "ssh" else "nix-daemon"
|
||||
script = f"""\
|
||||
#!{sys.executable}
|
||||
import os, sys
|
||||
os.execvp("{env.dirs.nix_bin_dir}/nix", [*{[prog, *flags]!s}, *sys.argv[1:]])
|
||||
"""
|
||||
path = env.dirs.test_root / "remote-builder" / "launch.py"
|
||||
path.parent.mkdir()
|
||||
path.write_text(textwrap.dedent(script))
|
||||
path.chmod(0o755)
|
||||
|
||||
remote_store = "local?" + urlencode(
|
||||
{"system-features": "foo bar baz", "root": str(env.dirs.home / "remote")}, quote_via=quote
|
||||
)
|
||||
uri_args = urlencode(
|
||||
{"remote-program": str(path), "remote-store": remote_store}, quote_via=quote
|
||||
)
|
||||
return textwrap.dedent(f"""
|
||||
version = 1
|
||||
|
||||
[machines.remote]
|
||||
uri = "{proto}://localhost?{uri_args}"
|
||||
jobs = 8
|
||||
speed-factor = 1
|
||||
supported-features = [ "foo", "bar", "baz" ]
|
||||
""")
|
||||
|
||||
|
||||
@pytest.mark.full_sandbox
|
||||
@with_files(
|
||||
{
|
||||
"build-hook.nix": get_global_asset("build-hook.nix"),
|
||||
"config.nix": get_global_asset("config.nix"),
|
||||
}
|
||||
)
|
||||
def test_remote_trustless_unsigned(nix: Nix, env: ManagedEnv, busybox_args: list[str]):
|
||||
# We first build a dependency of the derivation we eventually want to build.
|
||||
nix.nix_build(
|
||||
[
|
||||
"build-hook.nix",
|
||||
"-A",
|
||||
"passthru.input2",
|
||||
*busybox_args,
|
||||
"--option",
|
||||
"system-features",
|
||||
"bar",
|
||||
]
|
||||
).run().ok()
|
||||
|
||||
# Now when we go to build that downstream derivation, Lix will try to
|
||||
# copy our already-build `input2` to the remote store. That store object
|
||||
# is input-addressed, so this will fail.
|
||||
|
||||
result = nix.nix_build(
|
||||
[
|
||||
"build-hook.nix",
|
||||
"--max-jobs",
|
||||
"0",
|
||||
*busybox_args,
|
||||
"--builders",
|
||||
_builders("ssh-ng", ["--force-untrusted"], env),
|
||||
]
|
||||
).run()
|
||||
result.expect(1)
|
||||
assert re.findall(
|
||||
r"cannot add path '[^ ]*' because it lacks a signature by a trusted key",
|
||||
result.stderr_plain,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.full_sandbox
|
||||
@pytest.mark.parametrize(
|
||||
("protocol", "flags"), [("ssh", []), ("ssh-ng", []), ("ssh-ng", ["--force-untrusted"])]
|
||||
)
|
||||
@with_files(
|
||||
{
|
||||
"build-hook.nix": get_global_asset("build-hook.nix"),
|
||||
"config.nix": get_global_asset("config.nix"),
|
||||
}
|
||||
)
|
||||
def test_remote_trustless_ia(
|
||||
nix: Nix, env: ManagedEnv, busybox_args: list[str], protocol: str, flags: list[str]
|
||||
):
|
||||
result = nix.nix_build(
|
||||
[
|
||||
"build-hook.nix",
|
||||
"--max-jobs",
|
||||
"0",
|
||||
*busybox_args,
|
||||
"--builders",
|
||||
_builders(protocol, flags, env),
|
||||
]
|
||||
).run()
|
||||
result.ok()
|
||||
|
||||
out_path = (env.dirs.home / "result").readlink()
|
||||
assert nix.physical_store_path_for(out_path).read_text() == "FOO BAR BAZ\n"
|
||||
|
||||
|
||||
@pytest.mark.full_sandbox
|
||||
@pytest.mark.parametrize(("protocol", "flags"), [("ssh", []), ("ssh-ng", ["--force-untrusted"])])
|
||||
@with_files(
|
||||
{
|
||||
"build-hook-ca-fixed.nix": get_global_asset("build-hook-ca-fixed.nix"),
|
||||
"config.nix": get_global_asset("config.nix"),
|
||||
}
|
||||
)
|
||||
def test_remote_trustless_ca(
|
||||
nix: Nix, env: ManagedEnv, busybox_args: list[str], protocol: str, flags: list[str]
|
||||
):
|
||||
# Remote doesn't trusts us, but this is fine because we are only
|
||||
# building (fixed) CA derivations.
|
||||
result = nix.nix_build(
|
||||
[
|
||||
"build-hook-ca-fixed.nix",
|
||||
"--max-jobs",
|
||||
"0",
|
||||
*busybox_args,
|
||||
"--builders",
|
||||
_builders(protocol, flags, env),
|
||||
]
|
||||
).run()
|
||||
result.ok()
|
||||
|
||||
out_path = (env.dirs.home / "result").readlink()
|
||||
assert nix.physical_store_path_for(out_path).read_text() == "FOO BAR BAZ\n"
|
||||
@@ -0,0 +1,62 @@
|
||||
{ busybox }:
|
||||
|
||||
with import ./config.nix;
|
||||
|
||||
let
|
||||
|
||||
mkDerivation = args:
|
||||
derivation ({
|
||||
inherit system;
|
||||
builder = busybox;
|
||||
args = ["sh" "-e" args.builder or (builtins.toFile "builder-${args.name}.sh" ''
|
||||
if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi;
|
||||
eval "$buildCommand"
|
||||
'')];
|
||||
outputHashMode = "recursive";
|
||||
outputHashAlgo = "sha256";
|
||||
} // removeAttrs args ["builder" "meta" "passthru"])
|
||||
// { meta = args.meta or {}; passthru = args.passthru or {}; };
|
||||
|
||||
input1 = mkDerivation {
|
||||
shell = busybox;
|
||||
name = "build-remote-input-1";
|
||||
buildCommand = "echo hi-input1; echo FOO > $out";
|
||||
requiredSystemFeatures = ["foo"];
|
||||
outputHash = "sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=";
|
||||
};
|
||||
|
||||
input2 = mkDerivation {
|
||||
shell = busybox;
|
||||
name = "build-remote-input-2";
|
||||
buildCommand = "echo hi; echo BAR > $out";
|
||||
requiredSystemFeatures = ["bar"];
|
||||
outputHash = "sha256-XArauVH91AVwP9hBBQNlkX9ccuPpSYx9o0zeIHb6e+Q=";
|
||||
};
|
||||
|
||||
input3 = mkDerivation {
|
||||
shell = busybox;
|
||||
name = "build-remote-input-3";
|
||||
# `echo -n` tests handling of logs without trailing newlines
|
||||
buildCommand = ''
|
||||
echo -n hi-input3
|
||||
read x < ${input2}
|
||||
echo $x BAZ > $out
|
||||
'';
|
||||
requiredSystemFeatures = ["baz"];
|
||||
outputHash = "sha256-daKAcPp/+BYMQsVi/YYMlCKoNAxCNDsaivwSHgQqD2s=";
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
mkDerivation {
|
||||
shell = busybox;
|
||||
name = "build-remote";
|
||||
passthru = { inherit input1 input2 input3; };
|
||||
buildCommand =
|
||||
''
|
||||
read x < ${input1}
|
||||
read y < ${input3}
|
||||
echo "$x $y" > $out
|
||||
'';
|
||||
outputHash = "sha256-5SxbkUw6xe2l9TE1uwCvTtTDysD1vhRor38OtDF0LqQ=";
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
{ busybox, contentAddressed ? false }:
|
||||
|
||||
with import ./config.nix;
|
||||
|
||||
let
|
||||
|
||||
caArgs = if contentAddressed then {
|
||||
outputHashMode = "recursive";
|
||||
outputHashAlgo = "sha256";
|
||||
__contentAddressed = true;
|
||||
} else {};
|
||||
|
||||
mkDerivation = args:
|
||||
derivation ({
|
||||
inherit system;
|
||||
builder = busybox;
|
||||
args = ["sh" "-e" args.builder or (builtins.toFile "builder-${args.name}.sh" ''
|
||||
if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi;
|
||||
eval "$buildCommand"
|
||||
'')];
|
||||
} // removeAttrs args ["builder" "meta" "passthru"]
|
||||
// caArgs)
|
||||
// { meta = args.meta or {}; passthru = args.passthru or {}; };
|
||||
|
||||
input1 = mkDerivation {
|
||||
shell = busybox;
|
||||
name = "build-remote-input-1";
|
||||
buildCommand = "echo hi-input1; echo FOO > $out";
|
||||
requiredSystemFeatures = ["foo"];
|
||||
};
|
||||
|
||||
input2 = mkDerivation {
|
||||
shell = busybox;
|
||||
name = "build-remote-input-2";
|
||||
buildCommand = "echo hi; echo BAR > $out";
|
||||
requiredSystemFeatures = ["bar"];
|
||||
};
|
||||
|
||||
input3 = mkDerivation {
|
||||
shell = busybox;
|
||||
name = "build-remote-input-3";
|
||||
# `echo -n` tests handling of logs without trailing newlines
|
||||
buildCommand = ''
|
||||
echo -n hi-input3
|
||||
read x < ${input2}
|
||||
echo $x BAZ > $out
|
||||
'';
|
||||
requiredSystemFeatures = ["baz"];
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
mkDerivation {
|
||||
shell = busybox;
|
||||
name = "build-remote";
|
||||
passthru = { inherit input1 input2 input3; };
|
||||
buildCommand =
|
||||
''
|
||||
read x < ${input1}
|
||||
read y < ${input3}
|
||||
echo "$x $y" > $out
|
||||
'';
|
||||
}
|
||||
Reference in New Issue
Block a user