From e1237499d03e7c25d5ee87aa7600bfb1dec3eb33 Mon Sep 17 00:00:00 2001 From: lassulus Date: Tue, 23 Jan 2024 15:04:31 +0100 Subject: [PATCH] clan-cli Machine: make deployment info lazy --- pkgs/clan-cli/clan_cli/machines/machines.py | 113 +++++++++++--------- 1 file changed, 65 insertions(+), 48 deletions(-) diff --git a/pkgs/clan-cli/clan_cli/machines/machines.py b/pkgs/clan-cli/clan_cli/machines/machines.py index 235afa030..20a61cca6 100644 --- a/pkgs/clan-cli/clan_cli/machines/machines.py +++ b/pkgs/clan-cli/clan_cli/machines/machines.py @@ -1,17 +1,20 @@ import json +import logging from pathlib import Path from ..cmd import run from ..nix import nix_build, nix_config, nix_eval from ..ssh import Host, parse_deployment_address +log = logging.getLogger(__name__) + class Machine: def __init__( self, name: str, flake: Path | str, - machine_data: dict | None = None, + deployment_info: dict | None = None, ) -> None: """ Creates a Machine @@ -25,21 +28,45 @@ class Machine: self.eval_cache: dict[str, str] = {} self.build_cache: dict[str, Path] = {} - # TODO do this lazily - if machine_data is None: - self.machine_data = json.loads( - self.build_nix("config.system.clan.deployment.file").read_text() - ) - else: - self.machine_data = machine_data + if deployment_info is not None: + self.deployment_info = deployment_info - self.deployment_address = self.machine_data["deploymentAddress"] - self.secrets_module = self.machine_data.get("secretsModule", None) - if "secretsData" in self.machine_data: - self.secrets_data = json.loads( - Path(self.machine_data["secretsData"]).read_text() - ) - self.secrets_upload_directory = self.machine_data["secretsUploadDirectory"] + def get_deployment_info(self) -> None: + self.deployment_info = json.loads( + self.build_nix("config.system.clan.deployment.file").read_text() + ) + + @property + def deployment_address(self) -> str: + if not hasattr(self, "deployment_info"): + self.get_deployment_info() + return self.deployment_info["deploymentAddress"] + + @property + def secrets_module(self) -> str: + if not hasattr(self, "deployment_info"): + self.get_deployment_info() + return self.deployment_info["secretsModule"] + + @property + def secrets_data(self) -> dict: + if not hasattr(self, "deployment_info"): + self.get_deployment_info() + if self.deployment_info["secretsData"]: + try: + return json.loads(Path(self.deployment_info["secretsData"]).read_text()) + except json.JSONDecodeError: + log.error( + f"Failed to parse secretsData for machine {self.name} as json" + ) + return {} + return {} + + @property + def secrets_upload_directory(self) -> str: + if not hasattr(self, "deployment_info"): + self.get_deployment_info() + return self.deployment_info["secretsUploadDirectory"] @property def flake_dir(self) -> Path: @@ -64,28 +91,24 @@ class Machine: eval a nix attribute of the machine @attr: the attribute to get """ - if attr in self.eval_cache and not refresh: - return self.eval_cache[attr] - config = nix_config() system = config["system"] + attr = f'clanInternals.machines."{system}".{self.name}.{attr}' + + if attr in self.eval_cache and not refresh: + return self.eval_cache[attr] + if isinstance(self.flake, Path): - output = run( - nix_eval( - [ - f'path:{self.flake}#clanInternals.machines."{system}"."{self.name}".{attr}' - ] - ), - ).stdout.strip() + if (self.flake / ".git").exists(): + flake = f"git+file://{self.flake}" + else: + flake = f"path:{self.flake}" else: - output = run( - nix_eval( - [ - f'{self.flake}#clanInternals.machines."{system}"."{self.name}".{attr}' - ] - ), - ).stdout.strip() + flake = self.flake + + log.info(f"evaluating {flake}#{attr}") + output = run(nix_eval([f"{flake}#{attr}"])).stdout.strip() self.eval_cache[attr] = output return output @@ -94,27 +117,21 @@ class Machine: build a nix attribute of the machine @attr: the attribute to get """ - if attr in self.build_cache and not refresh: - return self.build_cache[attr] config = nix_config() system = config["system"] + attr = f'clanInternals.machines."{system}".{self.name}.{attr}' + + if attr in self.build_cache and not refresh: + return self.build_cache[attr] + if isinstance(self.flake, Path): - outpath = run( - nix_build( - [ - f'path:{self.flake}#clanInternals.machines."{system}"."{self.name}".{attr}' - ] - ), - ).stdout.strip() + flake = f"path:{self.flake}" else: - outpath = run( - nix_build( - [ - f'{self.flake}#clanInternals.machines."{system}"."{self.name}".{attr}' - ] - ), - ).stdout.strip() + flake = self.flake + + log.info(f"building {flake}#{attr}") + outpath = run(nix_build([f"{flake}#{attr}"])).stdout.strip() self.build_cache[attr] = Path(outpath) return Path(outpath)