use recursive-nix for integration tests
This commit is contained in:
@@ -15,7 +15,6 @@ from clan_cli.nix import (
|
|||||||
nix_command,
|
nix_command,
|
||||||
nix_config,
|
nix_config,
|
||||||
nix_metadata,
|
nix_metadata,
|
||||||
nix_test_store,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@@ -476,18 +475,12 @@ class Flake:
|
|||||||
builtins.toJSON [ ({" ".join([f"flake.clanInternals.lib.select ''{attr}'' flake" for attr in selectors])}) ]
|
builtins.toJSON [ ({" ".join([f"flake.clanInternals.lib.select ''{attr}'' flake" for attr in selectors])}) ]
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
if tmp_store := nix_test_store():
|
|
||||||
nix_options += ["--store", str(tmp_store)]
|
|
||||||
nix_options.append("--impure")
|
|
||||||
|
|
||||||
build_output = Path(
|
build_output = Path(
|
||||||
run(
|
run(
|
||||||
nix_build(["--expr", nix_code, *nix_options]), RunOpts(log=Log.NONE)
|
nix_build(["--expr", nix_code, *nix_options]), RunOpts(log=Log.NONE)
|
||||||
).stdout.strip()
|
).stdout.strip()
|
||||||
)
|
)
|
||||||
|
|
||||||
if tmp_store:
|
|
||||||
build_output = tmp_store.joinpath(*build_output.parts[1:])
|
|
||||||
outputs = json.loads(build_output.read_text())
|
outputs = json.loads(build_output.read_text())
|
||||||
if len(outputs) != len(selectors):
|
if len(outputs) != len(selectors):
|
||||||
msg = f"flake_prepare_cache: Expected {len(outputs)} outputs, got {len(outputs)}"
|
msg = f"flake_prepare_cache: Expected {len(outputs)} outputs, got {len(outputs)}"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from pathlib import Path
|
|||||||
|
|
||||||
from clan_cli.cmd import run
|
from clan_cli.cmd import run
|
||||||
from clan_cli.flake import Flake
|
from clan_cli.flake import Flake
|
||||||
from clan_cli.nix import nix_build, nix_config, nix_test_store
|
from clan_cli.nix import nix_build, nix_config
|
||||||
|
|
||||||
from .machines import Machine
|
from .machines import Machine
|
||||||
|
|
||||||
@@ -18,9 +18,6 @@ def get_all_machines(flake: Flake, nix_options: list[str]) -> list[Machine]:
|
|||||||
).stdout.rstrip()
|
).stdout.rstrip()
|
||||||
)
|
)
|
||||||
|
|
||||||
if test_store := nix_test_store():
|
|
||||||
json_path = test_store.joinpath(*json_path.parts[1:])
|
|
||||||
|
|
||||||
machines_json = json.loads(json_path.read_text())
|
machines_json = json.loads(json_path.read_text())
|
||||||
|
|
||||||
machines = []
|
machines = []
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from clan_cli.errors import ClanError
|
|||||||
from clan_cli.facts import public_modules as facts_public_modules
|
from clan_cli.facts import public_modules as facts_public_modules
|
||||||
from clan_cli.facts import secret_modules as facts_secret_modules
|
from clan_cli.facts import secret_modules as facts_secret_modules
|
||||||
from clan_cli.flake import Flake
|
from clan_cli.flake import Flake
|
||||||
from clan_cli.nix import nix_config, nix_test_store
|
from clan_cli.nix import nix_config
|
||||||
from clan_cli.ssh.host import Host
|
from clan_cli.ssh.host import Host
|
||||||
from clan_cli.ssh.host_key import HostKeyCheck
|
from clan_cli.ssh.host_key import HostKeyCheck
|
||||||
from clan_cli.ssh.parse import parse_deployment_address
|
from clan_cli.ssh.parse import parse_deployment_address
|
||||||
@@ -243,8 +243,6 @@ class Machine:
|
|||||||
|
|
||||||
output = self.nix("build", attr, nix_options)
|
output = self.nix("build", attr, nix_options)
|
||||||
output = Path(output)
|
output = Path(output)
|
||||||
if tmp_store := nix_test_store():
|
|
||||||
output = tmp_store.joinpath(*output.parts[1:])
|
|
||||||
assert output.exists(), f"The output {output} doesn't exist"
|
assert output.exists(), f"The output {output} doesn't exist"
|
||||||
if isinstance(output, Path):
|
if isinstance(output, Path):
|
||||||
return output
|
return output
|
||||||
|
|||||||
@@ -1,22 +1,18 @@
|
|||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import tempfile
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from clan_cli.cmd import run, run_no_stdout
|
from clan_cli.cmd import run, run_no_stdout
|
||||||
from clan_cli.dirs import nixpkgs_flake, nixpkgs_source
|
from clan_cli.dirs import nixpkgs_flake, nixpkgs_source
|
||||||
from clan_cli.errors import ClanError
|
from clan_cli.errors import ClanError
|
||||||
from clan_cli.locked_open import locked_open
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def nix_command(flags: list[str]) -> list[str]:
|
def nix_command(flags: list[str]) -> list[str]:
|
||||||
args = ["nix", "--extra-experimental-features", "nix-command flakes", *flags]
|
args = ["nix", "--extra-experimental-features", "nix-command flakes", *flags]
|
||||||
if store := nix_test_store():
|
|
||||||
args += ["--store", str(store)]
|
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
|
||||||
@@ -61,21 +57,6 @@ def nix_config() -> dict[str, Any]:
|
|||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
def nix_test_store() -> Path | None:
|
|
||||||
store = os.environ.get("CLAN_TEST_STORE", None)
|
|
||||||
lock_nix = os.environ.get("LOCK_NIX", "")
|
|
||||||
|
|
||||||
if not lock_nix:
|
|
||||||
lock_nix = tempfile.NamedTemporaryFile().name # NOQA: SIM115
|
|
||||||
if not os.environ.get("IN_NIX_SANDBOX"):
|
|
||||||
return None
|
|
||||||
if store:
|
|
||||||
Path.mkdir(Path(store), exist_ok=True)
|
|
||||||
with locked_open(Path(lock_nix), "w"):
|
|
||||||
return Path(store)
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def nix_eval(flags: list[str]) -> list[str]:
|
def nix_eval(flags: list[str]) -> list[str]:
|
||||||
default_flags = nix_command(
|
default_flags = nix_command(
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ from clan_cli.completions import (
|
|||||||
from clan_cli.errors import ClanError
|
from clan_cli.errors import ClanError
|
||||||
from clan_cli.git import commit_files
|
from clan_cli.git import commit_files
|
||||||
from clan_cli.machines.inventory import get_all_machines, get_selected_machines
|
from clan_cli.machines.inventory import get_all_machines, get_selected_machines
|
||||||
from clan_cli.nix import nix_shell, nix_test_store
|
from clan_cli.nix import nix_shell
|
||||||
from clan_cli.vars._types import StoreBase
|
from clan_cli.vars._types import StoreBase
|
||||||
|
|
||||||
from .check import check_vars
|
from .check import check_vars
|
||||||
@@ -78,8 +78,6 @@ class Generator:
|
|||||||
|
|
||||||
|
|
||||||
def bubblewrap_cmd(generator: str, tmpdir: Path) -> list[str]:
|
def bubblewrap_cmd(generator: str, tmpdir: Path) -> list[str]:
|
||||||
test_store = nix_test_store()
|
|
||||||
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
return nix_shell(
|
return nix_shell(
|
||||||
[
|
[
|
||||||
@@ -91,7 +89,6 @@ def bubblewrap_cmd(generator: str, tmpdir: Path) -> list[str]:
|
|||||||
"--unshare-all",
|
"--unshare-all",
|
||||||
"--tmpfs", "/",
|
"--tmpfs", "/",
|
||||||
"--ro-bind", "/nix/store", "/nix/store",
|
"--ro-bind", "/nix/store", "/nix/store",
|
||||||
*(["--ro-bind", str(test_store), str(test_store)] if test_store else []),
|
|
||||||
"--dev", "/dev",
|
"--dev", "/dev",
|
||||||
# not allowed to bind procfs in some sandboxes
|
# not allowed to bind procfs in some sandboxes
|
||||||
"--bind", str(tmpdir), str(tmpdir),
|
"--bind", str(tmpdir), str(tmpdir),
|
||||||
|
|||||||
@@ -133,12 +133,13 @@ pythonRuntime.pkgs.buildPythonApplication {
|
|||||||
runCommand "clan-pytest-without-core"
|
runCommand "clan-pytest-without-core"
|
||||||
{
|
{
|
||||||
nativeBuildInputs = testDependencies;
|
nativeBuildInputs = testDependencies;
|
||||||
|
requiredSystemFeatures = [ "recursive-nix" ];
|
||||||
|
|
||||||
closureInfo = pkgs.closureInfo {
|
closureInfo = pkgs.closureInfo {
|
||||||
rootPaths = [
|
rootPaths = [
|
||||||
templateDerivation
|
templateDerivation
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
set -u -o pipefail
|
set -u -o pipefail
|
||||||
@@ -146,12 +147,10 @@ pythonRuntime.pkgs.buildPythonApplication {
|
|||||||
chmod +w -R ./src
|
chmod +w -R ./src
|
||||||
cd ./src
|
cd ./src
|
||||||
|
|
||||||
export NIX_STATE_DIR=$TMPDIR/nix IN_NIX_SANDBOX=1 PYTHONWARNINGS=error
|
export IN_NIX_SANDBOX=1 PYTHONWARNINGS=error
|
||||||
|
|
||||||
# required to prevent concurrent 'nix flake lock' operations
|
# required to prevent concurrent 'nix flake lock' operations
|
||||||
export CLAN_TEST_STORE=$TMPDIR/store
|
|
||||||
export LOCK_NIX=$TMPDIR/nix_lock
|
export LOCK_NIX=$TMPDIR/nix_lock
|
||||||
mkdir -p "$CLAN_TEST_STORE/nix/store"
|
|
||||||
|
|
||||||
# limit build cores to 16
|
# limit build cores to 16
|
||||||
jobs="$((NIX_BUILD_CORES>16 ? 16 : NIX_BUILD_CORES))"
|
jobs="$((NIX_BUILD_CORES>16 ? 16 : NIX_BUILD_CORES))"
|
||||||
@@ -159,15 +158,24 @@ pythonRuntime.pkgs.buildPythonApplication {
|
|||||||
python -m pytest -m "not impure and not with_core" -n $jobs ./tests
|
python -m pytest -m "not impure and not with_core" -n $jobs ./tests
|
||||||
touch $out
|
touch $out
|
||||||
'';
|
'';
|
||||||
}
|
|
||||||
// lib.optionalAttrs (!stdenv.isDarwin) {
|
|
||||||
clan-pytest-with-core =
|
clan-pytest-with-core =
|
||||||
runCommand "clan-pytest-with-core"
|
runCommand "clan-pytest-with-core"
|
||||||
{
|
{
|
||||||
nativeBuildInputs = testDependencies;
|
nativeBuildInputs = testDependencies;
|
||||||
|
requiredSystemFeatures = [ "recursive-nix" ];
|
||||||
|
|
||||||
|
closureInfo = pkgs.closureInfo {
|
||||||
|
rootPaths = [
|
||||||
|
templateDerivation
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
buildInputs = [
|
buildInputs = [
|
||||||
pkgs.bash
|
pkgs.bash
|
||||||
pkgs.coreutils
|
pkgs.coreutils
|
||||||
|
pkgs.jq.dev
|
||||||
|
pkgs.stdenv
|
||||||
|
pkgs.stdenvNoCC
|
||||||
# looks like Nix 2.26 fixes the profile creation race condition we were running into on Nix 2.24
|
# looks like Nix 2.26 fixes the profile creation race condition we were running into on Nix 2.24
|
||||||
# Switch this back to `pkgs.nix` when `pkgs.nix` is Nix 2.26+
|
# Switch this back to `pkgs.nix` when `pkgs.nix` is Nix 2.26+
|
||||||
(
|
(
|
||||||
@@ -177,16 +185,6 @@ pythonRuntime.pkgs.buildPythonApplication {
|
|||||||
pkgs.nixVersions.latest
|
pkgs.nixVersions.latest
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
closureInfo = pkgs.closureInfo {
|
|
||||||
rootPaths = [
|
|
||||||
templateDerivation
|
|
||||||
pkgs.bash
|
|
||||||
pkgs.coreutils
|
|
||||||
pkgs.jq.dev
|
|
||||||
pkgs.stdenv
|
|
||||||
pkgs.stdenvNoCC
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
set -u -o pipefail
|
set -u -o pipefail
|
||||||
@@ -195,16 +193,10 @@ pythonRuntime.pkgs.buildPythonApplication {
|
|||||||
cd ./src
|
cd ./src
|
||||||
|
|
||||||
export CLAN_CORE_PATH=${clan-core-path}
|
export CLAN_CORE_PATH=${clan-core-path}
|
||||||
export NIX_STATE_DIR=$TMPDIR/nix
|
|
||||||
export IN_NIX_SANDBOX=1
|
export IN_NIX_SANDBOX=1
|
||||||
export PYTHONWARNINGS=error
|
export PYTHONWARNINGS=error
|
||||||
export CLAN_TEST_STORE=$TMPDIR/store
|
|
||||||
# required to prevent concurrent 'nix flake lock' operations
|
# required to prevent concurrent 'nix flake lock' operations
|
||||||
export LOCK_NIX=$TMPDIR/nix_lock
|
export LOCK_NIX=$TMPDIR/nix_lock
|
||||||
mkdir -p "$CLAN_TEST_STORE/nix/store"
|
|
||||||
mkdir -p "$CLAN_TEST_STORE/nix/var/nix/gcroots"
|
|
||||||
xargs cp --recursive --target "$CLAN_TEST_STORE/nix/store" < "$closureInfo/store-paths"
|
|
||||||
nix-store --load-db --store "$CLAN_TEST_STORE" < "$closureInfo/registration"
|
|
||||||
|
|
||||||
# limit build cores to 16
|
# limit build cores to 16
|
||||||
jobs="$((NIX_BUILD_CORES>16 ? 16 : NIX_BUILD_CORES))"
|
jobs="$((NIX_BUILD_CORES>16 ? 16 : NIX_BUILD_CORES))"
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import age_keys
|
|||||||
import pytest
|
import pytest
|
||||||
from clan_cli.dirs import TemplateType, clan_templates, nixpkgs_source
|
from clan_cli.dirs import TemplateType, clan_templates, nixpkgs_source
|
||||||
from clan_cli.locked_open import locked_open
|
from clan_cli.locked_open import locked_open
|
||||||
from clan_cli.nix import nix_test_store
|
|
||||||
from fixture_error import FixtureError
|
from fixture_error import FixtureError
|
||||||
from root import CLAN_CORE
|
from root import CLAN_CORE
|
||||||
from temporary_dir import TEMPDIR
|
from temporary_dir import TEMPDIR
|
||||||
@@ -290,9 +289,6 @@ def create_flake(
|
|||||||
flake_nix = flake / "flake.nix"
|
flake_nix = flake / "flake.nix"
|
||||||
# this is where we would install the sops key to, when updating
|
# this is where we would install the sops key to, when updating
|
||||||
substitute(flake_nix, clan_core_flake, flake)
|
substitute(flake_nix, clan_core_flake, flake)
|
||||||
nix_options = []
|
|
||||||
if tmp_store := nix_test_store():
|
|
||||||
nix_options += ["--store", str(tmp_store)]
|
|
||||||
|
|
||||||
with locked_open(Path(lock_nix), "w"):
|
with locked_open(Path(lock_nix), "w"):
|
||||||
sp.run(
|
sp.run(
|
||||||
@@ -303,7 +299,6 @@ def create_flake(
|
|||||||
flake,
|
flake,
|
||||||
"--extra-experimental-features",
|
"--extra-experimental-features",
|
||||||
"nix-command flakes",
|
"nix-command flakes",
|
||||||
*nix_options,
|
|
||||||
],
|
],
|
||||||
check=True,
|
check=True,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user