diff --git a/pkgs/clan-cli/clan_cli/tests/test_vars.py b/pkgs/clan-cli/clan_cli/tests/test_vars.py index 96078e7e9..306f61615 100644 --- a/pkgs/clan-cli/clan_cli/tests/test_vars.py +++ b/pkgs/clan-cli/clan_cli/tests/test_vars.py @@ -992,7 +992,7 @@ def test_dynamic_invalidation( # before generating, dependent generator validation should be empty; see bogus hardware-configuration.nix above # we have to avoid `*.files.value` in this initial select because the generators haven't been run yet # Generators 0: The initial generators before any 'vars generate' - generators_0 = machine.eval_nix(f"{gen_prefix}.*.{{validationHash}}") + generators_0 = machine.select(f"{gen_prefix}.*.{{validationHash}}") assert generators_0["dependent_generator"]["validationHash"] is None # generate both my_generator and (the dependent) dependent_generator @@ -1001,7 +1001,7 @@ def test_dynamic_invalidation( # after generating once, dependent generator validation should be set # Generators_1: The generators after the first 'vars generate' - generators_1 = machine.eval_nix(gen_prefix) + generators_1 = machine.select(gen_prefix) assert generators_1["dependent_generator"]["validationHash"] is not None # @tangential: after generating once, neither generator should want to run again because `clan vars generate` should have re-evaluated the dependent generator's validationHash after executing the parent generator but before executing the dependent generator @@ -1014,7 +1014,7 @@ def test_dynamic_invalidation( cli.run(["vars", "generate", "--flake", str(flake.path), machine.name]) clan_flake.invalidate_cache() # Generators_2: The generators after the second 'vars generate' - generators_2 = machine.eval_nix(gen_prefix) + generators_2 = machine.select(gen_prefix) assert ( generators_1["dependent_generator"]["validationHash"] == generators_2["dependent_generator"]["validationHash"] diff --git a/pkgs/clan-cli/clan_cli/vars/generate.py b/pkgs/clan-cli/clan_cli/vars/generate.py index 88e4221fc..fc519a2f4 100644 --- a/pkgs/clan-cli/clan_cli/vars/generate.py +++ b/pkgs/clan-cli/clan_cli/vars/generate.py @@ -72,14 +72,20 @@ class Generator: def final_script(self) -> Path: assert self._machine is not None - final_script = self._machine.build_nix( - f'config.clan.core.vars.generators."{self.name}".finalScript' + from clan_lib.nix import nix_test_store + + output = Path( + self._machine.select( + f'config.clan.core.vars.generators."{self.name}".finalScript' + ) ) - return final_script + if tmp_store := nix_test_store(): + output = tmp_store.joinpath(*output.parts[1:]) + return output def validation(self) -> str | None: assert self._machine is not None - return self._machine.eval_nix( + return self._machine.select( f'config.clan.core.vars.generators."{self.name}".validationHash' ) diff --git a/pkgs/clan-cli/clan_cli/vars/secret_modules/password_store.py b/pkgs/clan-cli/clan_cli/vars/secret_modules/password_store.py index 3f56ceccc..48781f394 100644 --- a/pkgs/clan-cli/clan_cli/vars/secret_modules/password_store.py +++ b/pkgs/clan-cli/clan_cli/vars/secret_modules/password_store.py @@ -33,7 +33,7 @@ class SecretStore(StoreBase): @property def _store_backend(self) -> str: - backend = self.machine.eval_nix("config.clan.core.vars.settings.passBackend") + backend = self.machine.select("config.clan.core.vars.settings.passBackend") return backend @property diff --git a/pkgs/clan-cli/clan_cli/vms/inspect.py b/pkgs/clan-cli/clan_cli/vms/inspect.py index 491312a3e..43c3997d6 100644 --- a/pkgs/clan-cli/clan_cli/vms/inspect.py +++ b/pkgs/clan-cli/clan_cli/vms/inspect.py @@ -55,7 +55,7 @@ class VmConfig: def inspect_vm(machine: Machine) -> VmConfig: - data = machine.eval_nix("config.clan.core.vm.inspect") + data = machine.select("config.clan.core.vm.inspect") # HACK! data["flake_url"] = dataclasses.asdict(machine.flake) return VmConfig.from_json(data) diff --git a/pkgs/clan-cli/clan_cli/vms/run.py b/pkgs/clan-cli/clan_cli/vms/run.py index 21696d59c..e8fc228fb 100644 --- a/pkgs/clan-cli/clan_cli/vms/run.py +++ b/pkgs/clan-cli/clan_cli/vms/run.py @@ -49,16 +49,24 @@ def facts_to_nixos_config(facts: dict[str, dict[str, bytes]]) -> dict: # TODO move this to the Machines class -def build_vm(machine: Machine, tmpdir: Path) -> dict[str, str]: +def build_vm( + machine: Machine, tmpdir: Path, nix_options: list[str] | None = None +) -> dict[str, str]: # TODO pass prompt here for the GTK gui - + if nix_options is None: + nix_options = [] secrets_dir = get_secrets(machine, tmpdir) - public_facts = machine.public_facts_store.get_all() + from clan_lib.nix import nix_test_store - nixos_config_file = machine.build_nix( - "config.system.clan.vm.create", extra_config=facts_to_nixos_config(public_facts) + output = Path( + machine.select( + "config.system.clan.vm.create", + ) ) + if tmp_store := nix_test_store(): + output = tmp_store.joinpath(*output.parts[1:]) + nixos_config_file = output try: vm_data = json.loads(Path(nixos_config_file).read_text()) vm_data["secrets_dir"] = str(secrets_dir) diff --git a/pkgs/clan-cli/clan_lib/backups/create.py b/pkgs/clan-cli/clan_lib/backups/create.py index 4edef8cc4..879c15466 100644 --- a/pkgs/clan-cli/clan_lib/backups/create.py +++ b/pkgs/clan-cli/clan_lib/backups/create.py @@ -4,7 +4,7 @@ from clan_lib.machines.machines import Machine def create_backup(machine: Machine, provider: str | None = None) -> None: machine.info(f"creating backup for {machine.name}") - backup_scripts = machine.eval_nix("config.clan.core.backups") + backup_scripts = machine.select("config.clan.core.backups") host = machine.target_host() if provider is None: if not backup_scripts["providers"]: diff --git a/pkgs/clan-cli/clan_lib/backups/list.py b/pkgs/clan-cli/clan_lib/backups/list.py index 4af07f1ee..c68c13a9c 100644 --- a/pkgs/clan-cli/clan_lib/backups/list.py +++ b/pkgs/clan-cli/clan_lib/backups/list.py @@ -15,7 +15,7 @@ class Backup: def list_provider(machine: Machine, host: Remote, provider: str) -> list[Backup]: results = [] - backup_metadata = machine.eval_nix("config.clan.core.backups") + backup_metadata = machine.select("config.clan.core.backups") list_command = backup_metadata["providers"][provider]["list"] proc = host.run( [list_command], @@ -41,7 +41,7 @@ def list_provider(machine: Machine, host: Remote, provider: str) -> list[Backup] def list_backups(machine: Machine, provider: str | None = None) -> list[Backup]: - backup_metadata = machine.eval_nix("config.clan.core.backups") + backup_metadata = machine.select("config.clan.core.backups") results = [] with machine.target_host().ssh_control_master() as host: if provider is None: diff --git a/pkgs/clan-cli/clan_lib/backups/restore.py b/pkgs/clan-cli/clan_lib/backups/restore.py index c813df5be..38fce7751 100644 --- a/pkgs/clan-cli/clan_lib/backups/restore.py +++ b/pkgs/clan-cli/clan_lib/backups/restore.py @@ -7,8 +7,8 @@ from clan_lib.ssh.remote import Remote def restore_service( machine: Machine, host: Remote, name: str, provider: str, service: str ) -> None: - backup_metadata = machine.eval_nix("config.clan.core.backups") - backup_folders = machine.eval_nix("config.clan.core.state") + backup_metadata = machine.select("config.clan.core.backups") + backup_folders = machine.select("config.clan.core.state") if service not in backup_folders: msg = f"Service {service} not found in configuration. Available services are: {', '.join(backup_folders.keys())}" @@ -60,7 +60,7 @@ def restore_backup( errors = [] with machine.target_host().ssh_control_master() as host: if service is None: - backup_folders = machine.eval_nix("config.clan.core.state") + backup_folders = machine.select("config.clan.core.state") for _service in backup_folders: try: restore_service(machine, host, name, provider, _service) diff --git a/pkgs/clan-cli/clan_lib/machines/machines.py b/pkgs/clan-cli/clan_lib/machines/machines.py index aae619c94..ad72f7de8 100644 --- a/pkgs/clan-cli/clan_lib/machines/machines.py +++ b/pkgs/clan-cli/clan_lib/machines/machines.py @@ -81,9 +81,10 @@ class Machine: @property def deployment(self) -> dict: - deployment = json.loads( - self.build_nix("config.system.clan.deployment.file").read_text() - ) + output = Path(self.select("config.system.clan.deployment.file")) + if tmp_store := nix_test_store(): + output = tmp_store.joinpath(*output.parts[1:]) + deployment = json.loads(output.read_text()) return deployment @cached_property @@ -159,13 +160,13 @@ class Machine: return None - def nix( + def select( self, attr: str, ) -> Any: """ - Build the machine and return the path to the result - accepts a secret store and a facts store # TODO + Select a nix attribute of the machine + @attr: the attribute to get """ config = nix_config() @@ -175,36 +176,6 @@ class Machine: f'clanInternals.machines."{system}"."{self.name}".{attr}' ) - def eval_nix(self, attr: str, extra_config: None | dict = None) -> Any: - """ - eval a nix attribute of the machine - @attr: the attribute to get - """ - - if extra_config: - log.warning("extra_config in eval_nix is no longer supported") - - return self.nix(attr) - - def build_nix(self, attr: str, extra_config: None | dict = None) -> Path: - """ - build a nix attribute of the machine - @attr: the attribute to get - """ - - if extra_config: - log.warning("extra_config in build_nix is no longer supported") - - output = self.nix(attr) - 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" - if isinstance(output, Path): - return output - msg = "build_nix returned not a Path" - raise ClanError(msg) - @dataclass(frozen=True) class RemoteSource: @@ -229,7 +200,7 @@ def get_host( machine.debug( f"'{field}' is not set in inventory, falling back to slower Nix config, set it either through the Nix or json interface to improve performance" ) - host_str = machine.eval_nix(f'config.clan.core.networking."{field}"') + host_str = machine.select(f'config.clan.core.networking."{field}"') source = "nix_machine" if not host_str: diff --git a/pkgs/clan-cli/clan_lib/tests/test_create.py b/pkgs/clan-cli/clan_lib/tests/test_create.py index ddb697d8d..261e84bf1 100644 --- a/pkgs/clan-cli/clan_lib/tests/test_create.py +++ b/pkgs/clan-cli/clan_lib/tests/test_create.py @@ -282,5 +282,5 @@ def test_clan_create_api( clan_dir_flake.invalidate_cache() with pytest.raises(ClanError) as exc_info: - machine.build_nix("config.system.build.toplevel") + Path(machine.select("config.system.build.toplevel")) assert "nixos-system-test-clan" in str(exc_info.value) diff --git a/pkgs/generate-test-vars/generate_test_vars/cli.py b/pkgs/generate-test-vars/generate_test_vars/cli.py index 2b9c09992..b22596ca2 100755 --- a/pkgs/generate-test-vars/generate_test_vars/cli.py +++ b/pkgs/generate-test-vars/generate_test_vars/cli.py @@ -63,8 +63,7 @@ class TestMachine(Machine): def flake_dir(self) -> Path: return self.test_dir - @override - def nix(self, attr: str) -> Any: + def select(self, attr: str) -> Any: """ Build the machine and return the path to the result accepts a secret store and a facts store # TODO