Merge pull request 'extract nix_test_store helper for sandbox builds' (#2562) from sandbox into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2562
This commit is contained in:
Mic92
2024-12-05 10:46:41 +00:00
4 changed files with 34 additions and 34 deletions

View File

@@ -1,10 +1,9 @@
import json import json
import os
from pathlib import Path from pathlib import Path
from clan_cli.clan_uri import FlakeId from clan_cli.clan_uri import FlakeId
from clan_cli.cmd import run from clan_cli.cmd import run
from clan_cli.nix import nix_build, nix_config from clan_cli.nix import nix_build, nix_config, nix_test_store
from .machines import Machine from .machines import Machine
@@ -13,15 +12,16 @@ from .machines import Machine
def get_all_machines(flake: FlakeId, nix_options: list[str]) -> list[Machine]: def get_all_machines(flake: FlakeId, nix_options: list[str]) -> list[Machine]:
config = nix_config() config = nix_config()
system = config["system"] system = config["system"]
json_path = run( json_path = Path(
nix_build([f'{flake}#clanInternals.all-machines-json."{system}"']) run(
).stdout nix_build([f'{flake}#clanInternals.all-machines-json."{system}"'])
).stdout.rstrip()
)
tmp_store = os.environ.get("TMP_STORE", None) if test_store := nix_test_store():
if tmp_store: json_path = test_store.joinpath(*json_path.parts[1:])
json_path = f"{tmp_store}/{json_path}"
machines_json = json.loads(Path(json_path.rstrip()).read_text()) machines_json = json.loads(json_path.read_text())
machines = [] machines = []
for name, machine_data in machines_json.items(): for name, machine_data in machines_json.items():

View File

@@ -1,7 +1,6 @@
import importlib import importlib
import json import json
import logging import logging
import os
from dataclasses import dataclass, field from dataclasses import dataclass, field
from functools import cached_property from functools import cached_property
from pathlib import Path from pathlib import Path
@@ -13,7 +12,7 @@ from clan_cli.cmd import run_no_stdout
from clan_cli.errors import ClanError 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.nix import nix_build, nix_config, nix_eval, nix_metadata from clan_cli.nix import nix_build, nix_config, nix_eval, nix_metadata, nix_test_store
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
@@ -325,9 +324,8 @@ class Machine:
output = self.nix("build", attr, extra_config, nix_options) output = self.nix("build", attr, extra_config, nix_options)
assert isinstance(output, Path), "Nix build did not result in a single path" assert isinstance(output, Path), "Nix build did not result in a single path"
tmp_store = os.environ.get("TMP_STORE", None) if tmp_store := nix_test_store():
if tmp_store is not None: output = tmp_store.joinpath(*output.parts[1:])
output = Path(f"{tmp_store}/{output!s}")
if isinstance(output, Path): if isinstance(output, Path):
self._build_cache[attr] = output self._build_cache[attr] = output
return output return output

View File

@@ -1,7 +1,6 @@
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
@@ -14,9 +13,8 @@ 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]
store = os.environ.get("TMP_STORE", None) if store := nix_test_store():
if store: args += ["--store", str(store)]
args += ["--store", store]
return args return args
@@ -60,6 +58,15 @@ def nix_config() -> dict[str, Any]:
return config return config
def nix_test_store() -> Path | None:
if not os.environ.get("IN_NIX_SANDBOX"):
return None
store = os.environ.get("CLAN_TEST_STORE", None)
if store:
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(
[ [
@@ -70,18 +77,13 @@ def nix_eval(flags: list[str]) -> list[str]:
] ]
) )
if os.environ.get("IN_NIX_SANDBOX"): if os.environ.get("IN_NIX_SANDBOX"):
with tempfile.TemporaryDirectory(prefix="nix-store-") as nix_store: return [
return [ *default_flags,
*default_flags, "--override-input",
"--override-input", "nixpkgs",
"nixpkgs", str(nixpkgs_source()),
str(nixpkgs_source()), *flags,
# --store is required to prevent this error: ]
# error: cannot unlink '/nix/store/6xg259477c90a229xwmb53pdfkn6ig3g-default-builder.sh': Operation not permitted
"--store",
nix_store,
*flags,
]
return default_flags + flags return default_flags + flags

View File

@@ -176,12 +176,12 @@ python3.pkgs.buildPythonApplication {
export NIX_STATE_DIR=$TMPDIR/nix export NIX_STATE_DIR=$TMPDIR/nix
export IN_NIX_SANDBOX=1 export IN_NIX_SANDBOX=1
export PYTHONWARNINGS=error export PYTHONWARNINGS=error
export TMP_STORE=$TMPDIR/store 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 $TMP_STORE/nix/store mkdir -p "$CLAN_TEST_STORE/nix/store"
xargs cp --recursive --target "$TMP_STORE/nix/store" < "$closureInfo/store-paths" xargs cp --recursive --target "$CLAN_TEST_STORE/nix/store" < "$closureInfo/store-paths"
nix-store --load-db --store $TMP_STORE < "$closureInfo/registration" nix-store --load-db --store "$CLAN_TEST_STORE" < "$closureInfo/registration"
${pythonWithTestDeps}/bin/python -m pytest -m "not impure and with_core" ./tests ${pythonWithTestDeps}/bin/python -m pytest -m "not impure and with_core" ./tests
touch $out touch $out
''; '';