From 71cdbc989c6c9eb1b21a8dc27b13aeec67ce248d Mon Sep 17 00:00:00 2001 From: DavHau Date: Sat, 3 May 2025 14:44:34 +0700 Subject: [PATCH] GUI/vars: add endpoints for getting prompts and generating vars --- pkgs/clan-cli/clan_cli/tests/test_vars.py | 20 ++--- pkgs/clan-cli/clan_cli/vars/generate.py | 89 ++++++++++++++++++----- pkgs/clan-cli/clan_cli/vars/migration.py | 4 +- 3 files changed, 84 insertions(+), 29 deletions(-) diff --git a/pkgs/clan-cli/clan_cli/tests/test_vars.py b/pkgs/clan-cli/clan_cli/tests/test_vars.py index 503984d3c..a3549a2ec 100644 --- a/pkgs/clan-cli/clan_cli/tests/test_vars.py +++ b/pkgs/clan-cli/clan_cli/tests/test_vars.py @@ -12,7 +12,7 @@ from clan_cli.tests.age_keys import SopsSetup from clan_cli.tests.fixtures_flakes import ClanFlake from clan_cli.tests.helpers import cli from clan_cli.vars.check import check_vars -from clan_cli.vars.generate import Generator, generate_vars_for_machine +from clan_cli.vars.generate import Generator, generate_vars_for_machine_interactive from clan_cli.vars.get import get_var from clan_cli.vars.graph import all_missing_closure, requested_closure from clan_cli.vars.list import stringify_all_vars @@ -706,11 +706,11 @@ def test_stdout_of_generate( flake_.refresh() monkeypatch.chdir(flake_.path) flake = Flake(str(flake_.path)) - from clan_cli.vars.generate import generate_vars_for_machine + from clan_cli.vars.generate import generate_vars_for_machine_interactive # with capture_output as output: with caplog.at_level(logging.INFO): - generate_vars_for_machine( + generate_vars_for_machine_interactive( Machine(name="my_machine", flake=flake), "my_generator", regenerate=False, @@ -723,7 +723,7 @@ def test_stdout_of_generate( set_var("my_machine", "my_generator/my_value", b"world", flake) with caplog.at_level(logging.INFO): - generate_vars_for_machine( + generate_vars_for_machine_interactive( Machine(name="my_machine", flake=flake), "my_generator", regenerate=True, @@ -734,7 +734,7 @@ def test_stdout_of_generate( caplog.clear() # check the output when nothing gets regenerated with caplog.at_level(logging.INFO): - generate_vars_for_machine( + generate_vars_for_machine_interactive( Machine(name="my_machine", flake=flake), "my_generator", regenerate=True, @@ -743,7 +743,7 @@ def test_stdout_of_generate( assert "hello" in caplog.text caplog.clear() with caplog.at_level(logging.INFO): - generate_vars_for_machine( + generate_vars_for_machine_interactive( Machine(name="my_machine", flake=flake), "my_secret_generator", regenerate=False, @@ -758,7 +758,7 @@ def test_stdout_of_generate( Flake(str(flake.path)), ) with caplog.at_level(logging.INFO): - generate_vars_for_machine( + generate_vars_for_machine_interactive( Machine(name="my_machine", flake=flake), "my_secret_generator", regenerate=True, @@ -848,7 +848,7 @@ def test_fails_when_files_are_left_from_other_backend( flake.refresh() monkeypatch.chdir(flake.path) for generator in ["my_secret_generator", "my_value_generator"]: - generate_vars_for_machine( + generate_vars_for_machine_interactive( Machine(name="my_machine", flake=Flake(str(flake.path))), generator, regenerate=False, @@ -865,13 +865,13 @@ def test_fails_when_files_are_left_from_other_backend( # This should raise an error if generator == "my_secret_generator": with pytest.raises(ClanError): - generate_vars_for_machine( + generate_vars_for_machine_interactive( Machine(name="my_machine", flake=Flake(str(flake.path))), generator, regenerate=False, ) else: - generate_vars_for_machine( + generate_vars_for_machine_interactive( Machine(name="my_machine", flake=Flake(str(flake.path))), generator, regenerate=False, diff --git a/pkgs/clan-cli/clan_cli/vars/generate.py b/pkgs/clan-cli/clan_cli/vars/generate.py index 50699124f..dff827e7f 100644 --- a/pkgs/clan-cli/clan_cli/vars/generate.py +++ b/pkgs/clan-cli/clan_cli/vars/generate.py @@ -15,11 +15,13 @@ from clan_cli.completions import ( complete_services_for_machine, ) from clan_cli.errors import ClanError +from clan_cli.flake import Flake from clan_cli.git import commit_files from clan_cli.machines.inventory import get_all_machines, get_selected_machines from clan_cli.nix import nix_config, nix_shell, nix_test_store from clan_cli.vars._types import StoreBase -from clan_cli.vars.migration import _check_can_migrate, _migrate_files +from clan_cli.vars.migration import check_can_migrate, migrate_files +from clan_lib.api import API from .check import check_vars from .graph import ( @@ -309,7 +311,64 @@ def get_closure( return minimal_closure([generator_name], generators) +@API.register +def get_generators_closure( + machine_name: str, + base_dir: Path, + regenerate: bool = False, +) -> list[Generator]: + from clan_cli.machines.machines import Machine + + return get_closure( + machine=Machine(name=machine_name, flake=Flake(str(base_dir))), + generator_name=None, + regenerate=regenerate, + ) + + +def _generate_vars_for_machine( + machine: "Machine", + generators: list[Generator], + all_prompt_values: dict[str, dict], + no_sandbox: bool = False, +) -> bool: + for generator in generators: + if check_can_migrate(machine, generator): + migrate_files(machine, generator) + else: + execute_generator( + machine=machine, + generator=generator, + secret_vars_store=machine.secret_vars_store, + public_vars_store=machine.public_vars_store, + prompt_values=all_prompt_values[generator.name], + no_sandbox=no_sandbox, + ) + return True + + +@API.register def generate_vars_for_machine( + machine_name: str, + generators: list[Generator], + all_prompt_values: dict[str, dict[str, str]], + base_dir: Path, + no_sandbox: bool = False, +) -> bool: + from clan_cli.machines.machines import Machine + + return _generate_vars_for_machine( + machine=Machine( + name=machine_name, + flake=Flake(str(base_dir)), + ), + generators=generators, + all_prompt_values=all_prompt_values, + no_sandbox=no_sandbox, + ) + + +def generate_vars_for_machine_interactive( machine: "Machine", generator_name: str | None, regenerate: bool, @@ -333,22 +392,18 @@ def generate_vars_for_machine( msg += f"Secret vars store: {sec_healtcheck_msg}" raise ClanError(msg) - closure = get_closure(machine, generator_name, regenerate) - if len(closure) == 0: + generators = get_closure(machine, generator_name, regenerate) + if len(generators) == 0: return False - for generator in closure: - if _check_can_migrate(machine, generator): - _migrate_files(machine, generator) - else: - execute_generator( - machine=machine, - generator=generator, - secret_vars_store=machine.secret_vars_store, - public_vars_store=machine.public_vars_store, - prompt_values=_ask_prompts(generator), - no_sandbox=no_sandbox, - ) - return True + all_prompt_values = {} + for generator in generators: + all_prompt_values[generator.name] = _ask_prompts(generator) + return _generate_vars_for_machine( + machine, + generators, + all_prompt_values, + no_sandbox=no_sandbox, + ) def generate_vars( @@ -361,7 +416,7 @@ def generate_vars( for machine in machines: errors = [] try: - was_regenerated |= generate_vars_for_machine( + was_regenerated |= generate_vars_for_machine_interactive( machine, generator_name, regenerate, no_sandbox=no_sandbox ) except Exception as exc: diff --git a/pkgs/clan-cli/clan_cli/vars/migration.py b/pkgs/clan-cli/clan_cli/vars/migration.py index 71085fadf..fa22e55f5 100644 --- a/pkgs/clan-cli/clan_cli/vars/migration.py +++ b/pkgs/clan-cli/clan_cli/vars/migration.py @@ -74,7 +74,7 @@ def _migrate_file( return paths -def _migrate_files( +def migrate_files( machine: "Machine", generator: "Generator", ) -> None: @@ -98,7 +98,7 @@ def _migrate_files( ) -def _check_can_migrate( +def check_can_migrate( machine: "Machine", generator: "Generator", ) -> bool: