diff --git a/pkgs/clan-cli/clan_cli/machines/inventory.py b/pkgs/clan-cli/clan_cli/machines/inventory.py index a2b6397bf..ea8229fe7 100644 --- a/pkgs/clan-cli/clan_cli/machines/inventory.py +++ b/pkgs/clan-cli/clan_cli/machines/inventory.py @@ -1,10 +1,9 @@ import json -import os from pathlib import Path from clan_cli.clan_uri import FlakeId 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 @@ -13,15 +12,16 @@ from .machines import Machine def get_all_machines(flake: FlakeId, nix_options: list[str]) -> list[Machine]: config = nix_config() system = config["system"] - json_path = run( - nix_build([f'{flake}#clanInternals.all-machines-json."{system}"']) - ).stdout + json_path = Path( + run( + nix_build([f'{flake}#clanInternals.all-machines-json."{system}"']) + ).stdout.rstrip() + ) - tmp_store = os.environ.get("TMP_STORE", None) - if tmp_store: - json_path = f"{tmp_store}/{json_path}" + if test_store := nix_test_store(): + json_path = test_store.joinpath(*json_path.parts[1:]) - machines_json = json.loads(Path(json_path.rstrip()).read_text()) + machines_json = json.loads(json_path.read_text()) machines = [] for name, machine_data in machines_json.items(): diff --git a/pkgs/clan-cli/clan_cli/machines/machines.py b/pkgs/clan-cli/clan_cli/machines/machines.py index 48a1d872d..7fe9ee93f 100644 --- a/pkgs/clan-cli/clan_cli/machines/machines.py +++ b/pkgs/clan-cli/clan_cli/machines/machines.py @@ -1,7 +1,6 @@ import importlib import json import logging -import os from dataclasses import dataclass, field from functools import cached_property 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.facts import public_modules as facts_public_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_key import HostKeyCheck from clan_cli.ssh.parse import parse_deployment_address @@ -325,9 +324,8 @@ class Machine: output = self.nix("build", attr, extra_config, nix_options) assert isinstance(output, Path), "Nix build did not result in a single path" - tmp_store = os.environ.get("TMP_STORE", None) - if tmp_store is not None: - output = Path(f"{tmp_store}/{output!s}") + if tmp_store := nix_test_store(): + output = tmp_store.joinpath(*output.parts[1:]) if isinstance(output, Path): self._build_cache[attr] = output return output diff --git a/pkgs/clan-cli/clan_cli/nix/__init__.py b/pkgs/clan-cli/clan_cli/nix/__init__.py index f0011a778..cba4e3562 100644 --- a/pkgs/clan-cli/clan_cli/nix/__init__.py +++ b/pkgs/clan-cli/clan_cli/nix/__init__.py @@ -1,7 +1,6 @@ import json import logging import os -import tempfile from pathlib import Path from typing import Any @@ -14,9 +13,8 @@ log = logging.getLogger(__name__) def nix_command(flags: list[str]) -> list[str]: args = ["nix", "--extra-experimental-features", "nix-command flakes", *flags] - store = os.environ.get("TMP_STORE", None) - if store: - args += ["--store", store] + if store := nix_test_store(): + args += ["--store", str(store)] return args @@ -60,6 +58,15 @@ def nix_config() -> dict[str, Any]: 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]: default_flags = nix_command( [ @@ -70,18 +77,13 @@ def nix_eval(flags: list[str]) -> list[str]: ] ) if os.environ.get("IN_NIX_SANDBOX"): - with tempfile.TemporaryDirectory(prefix="nix-store-") as nix_store: - return [ - *default_flags, - "--override-input", - "nixpkgs", - str(nixpkgs_source()), - # --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, + "--override-input", + "nixpkgs", + str(nixpkgs_source()), + *flags, + ] return default_flags + flags diff --git a/pkgs/clan-cli/default.nix b/pkgs/clan-cli/default.nix index dcfc96454..fa00c7cdc 100644 --- a/pkgs/clan-cli/default.nix +++ b/pkgs/clan-cli/default.nix @@ -176,12 +176,12 @@ python3.pkgs.buildPythonApplication { export NIX_STATE_DIR=$TMPDIR/nix export IN_NIX_SANDBOX=1 export PYTHONWARNINGS=error - export TMP_STORE=$TMPDIR/store + export CLAN_TEST_STORE=$TMPDIR/store # required to prevent concurrent 'nix flake lock' operations export LOCK_NIX=$TMPDIR/nix_lock - mkdir -p $TMP_STORE/nix/store - xargs cp --recursive --target "$TMP_STORE/nix/store" < "$closureInfo/store-paths" - nix-store --load-db --store $TMP_STORE < "$closureInfo/registration" + mkdir -p "$CLAN_TEST_STORE/nix/store" + xargs cp --recursive --target "$CLAN_TEST_STORE/nix/store" < "$closureInfo/store-paths" + nix-store --load-db --store "$CLAN_TEST_STORE" < "$closureInfo/registration" ${pythonWithTestDeps}/bin/python -m pytest -m "not impure and with_core" ./tests touch $out '';