generate-test-vars: improve caching and reduce number of overrides in base class

This commit is contained in:
Jörg Thalheim
2025-04-21 14:58:03 +02:00
parent b4880d09a9
commit 74ef833dd3

View File

@@ -4,14 +4,15 @@ import argparse
import json import json
import os import os
import subprocess import subprocess
from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from tempfile import NamedTemporaryFile from tempfile import NamedTemporaryFile
from typing import Any from typing import Any, override
from clan_cli.dirs import find_git_repo_root from clan_cli.dirs import find_git_repo_root
from clan_cli.flake import Flake from clan_cli.flake import Flake
from clan_cli.machines.machines import Machine from clan_cli.machines.machines import Machine
from clan_cli.nix import nix_build, nix_config, nix_eval from clan_cli.nix import nix_config, nix_eval
from clan_cli.vars.generate import generate_vars from clan_cli.vars.generate import generate_vars
sops_priv_key = ( sops_priv_key = (
@@ -26,7 +27,7 @@ def machine_names(repo_root: Path, check_attr: str) -> list[str]:
""" """
cmd = nix_eval( cmd = nix_eval(
[ [
f"{repo_root}#checks.{nix_config()['system']}.{check_attr}.nodes", f"git+file://{repo_root}#checks.{nix_config()['system']}.{check_attr}.nodes",
"--apply", "--apply",
"builtins.attrNames", "builtins.attrNames",
] ]
@@ -42,79 +43,48 @@ class TestMachine(Machine):
clan-core#checks.<system>.<test_name>.nodes.<machine_name>.<attr> clan-core#checks.<system>.<test_name>.nodes.<machine_name>.<attr>
""" """
def __init__(self, name: str, flake: Flake, check_attr: str) -> None: @override
def __init__(
self, name: str, flake: Flake, test_dir: Path, check_attr: str
) -> None:
super().__init__(name, flake) super().__init__(name, flake)
self.check_attr = check_attr self.check_attr = check_attr
self.test_dir = test_dir
@property @property
def deployment(self) -> dict: def flake_dir(self) -> Path:
if getattr(self, "_deployment", None): return self.test_dir
return self._deployment
cmd = nix_build(
[
f"{self.flake.path.resolve()}#checks.{nix_config()['system']}.{self.check_attr}.nodes.{self.name}.system.clan.deployment.file"
]
)
out = subprocess.run(cmd, check=True, text=True, stdout=subprocess.PIPE)
self._deployment = json.loads(Path(out.stdout.strip()).read_text())
return self._deployment
def eval_nix( @override
def nix(
self, self,
attr: str, attr: str,
refresh: bool = False,
extra_config: None | dict = None,
nix_options: list[str] | None = None, nix_options: list[str] | None = None,
) -> Any: ) -> Any:
""" """
eval a nix attribute of the machine Build the machine and return the path to the result
@attr: the attribute to get accepts a secret store and a facts store # TODO
""" """
if nix_options is None: if nix_options is None:
nix_options = [] nix_options = []
# return self.nix("eval", attr, nix_options) config = nix_config()
cmd = nix_eval( system = config["system"]
[
f"{self.flake.path.resolve()}#checks.{nix_config()['system']}.{self.check_attr}.nodes.{self.name}.{attr}" return self.flake.select(
] f'checks."{system}".{self.check_attr}.nodes.{self.name}.{attr}',
nix_options=nix_options,
) )
out = subprocess.run(cmd, check=True, text=True, stdout=subprocess.PIPE)
return json.loads(out.stdout.strip())
def build_nix(
self,
attr: str,
extra_config: None | dict = None,
nix_options: list[str] | None = None,
) -> Path:
"""
build a nix attribute of the machine
@attr: the attribute to get
"""
if nix_options is None:
nix_options = []
cmd = nix_build(
[
f"{self.flake.path.resolve()}#checks.{nix_config()['system']}.{self.check_attr}.nodes.{self.name}.{attr}"
]
)
out = subprocess.run(cmd, check=True, text=True, stdout=subprocess.PIPE)
return Path(out.stdout.strip())
def flush_caches(self) -> None:
"""
Disable flush, because it calls prefetch() which resets the overridden Flake._path
"""
return
def parse_args() -> argparse.Namespace: @dataclass
import argparse class Options:
repo_root: Path
test_dir: Path
check_attr: str
def parse_args() -> Options:
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description=""" description="""
Update the vars of a 'makeTestClan' integration test. Update the vars of a 'makeTestClan' integration test.
@@ -145,26 +115,29 @@ def parse_args() -> argparse.Namespace:
type=str, type=str,
help="The attribute name of the flake#checks to update", help="The attribute name of the flake#checks to update",
) )
return parser.parse_args() args = parser.parse_args()
return Options(
repo_root=args.repo_root,
test_dir=args.test_dir,
check_attr=args.check_attr,
)
def main() -> None: def main() -> None:
os.environ["CLAN_NO_COMMIT"] = "1" os.environ["CLAN_NO_COMMIT"] = "1"
args = parse_args() opts = parse_args()
test_dir = args.repo_root / args.test_dir test_dir = opts.repo_root / opts.test_dir
subprocess.run(["rm", "-rf", f"{test_dir}/vars", f"{test_dir}/sops"]) subprocess.run(["rm", "-rf", f"{test_dir}/vars", f"{test_dir}/sops"])
flake = Flake(str(test_dir)) flake = Flake(str(opts.repo_root))
flake._path = test_dir # noqa SLF001
flake._is_local = True # noqa SLF001
machines = [ machines = [
TestMachine(name, flake, args.check_attr) TestMachine(name, flake, test_dir, opts.check_attr)
for name in machine_names( for name in machine_names(
args.repo_root, opts.repo_root,
args.check_attr, opts.check_attr,
) )
] ]
user = "admin" user = "admin"
admin_key_path = Path(flake.path.resolve() / "sops" / "users" / user / "key.json") admin_key_path = Path(test_dir.resolve() / "sops" / "users" / user / "key.json")
admin_key_path.parent.mkdir(parents=True, exist_ok=True) admin_key_path.parent.mkdir(parents=True, exist_ok=True)
admin_key_path.write_text( admin_key_path.write_text(
json.dumps( json.dumps(