1
0
forked from clan/clan-core

clan-cli Machine: make deployment info lazy

This commit is contained in:
lassulus 2024-01-23 15:04:31 +01:00
parent 3284224440
commit e1237499d0

View File

@ -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)