Files
clan-core/pkgs/clan-cli/clan_cli/clan/inspect.py
2024-07-29 17:33:46 +02:00

127 lines
3.4 KiB
Python

import argparse
from dataclasses import dataclass
from pathlib import Path
from ..clan_uri import FlakeId
from ..cmd import run
from ..dirs import machine_gcroot
from ..errors import ClanError
from ..machines.list import list_machines
from ..machines.machines import Machine
from ..nix import nix_add_to_gcroots, nix_build, nix_config, nix_eval, nix_metadata
from ..vms.inspect import VmConfig, inspect_vm
@dataclass
class FlakeConfig:
flake_url: FlakeId
flake_attr: str
clan_name: str
nar_hash: str
icon: str | None
description: str | None
last_updated: str
revision: str | None
vm: VmConfig
def __post_init__(self) -> None:
if isinstance(self.vm, dict):
self.vm = VmConfig(**self.vm)
def run_cmd(cmd: list[str]) -> str:
proc = run(cmd)
return proc.stdout.strip()
def inspect_flake(flake_url: str | Path, machine_name: str) -> FlakeConfig:
config = nix_config()
system = config["system"]
# Check if the machine exists
machines = list_machines(flake_url, False)
if machine_name not in machines:
raise ClanError(
f"Machine {machine_name} not found in {flake_url}. Available machines: {', '.join(machines)}"
)
machine = Machine(machine_name, FlakeId(flake_url))
vm = inspect_vm(machine)
# Make symlink to gcroots from vm.machine_icon
if vm.machine_icon:
gcroot_icon: Path = machine_gcroot(flake_url=str(flake_url)) / vm.machine_name
nix_add_to_gcroots(vm.machine_icon, gcroot_icon)
# Get the Clan name
cmd = nix_eval(
[
f'{flake_url}#clanInternals.machines."{system}"."{machine_name}".config.clan.core.clanName'
]
)
res = run_cmd(cmd)
clan_name = res.strip('"')
# Get the clan icon path
cmd = nix_eval(
[
f'{flake_url}#clanInternals.machines."{system}"."{machine_name}".config.clan.core.clanIcon'
]
)
res = run_cmd(cmd)
# If the icon is null, no icon is set for this Clan
if res == "null":
icon_path = None
else:
icon_path = res.strip('"')
cmd = nix_build(
[
f'{flake_url}#clanInternals.machines."{system}"."{machine_name}".config.clan.core.clanIcon'
],
machine_gcroot(flake_url=str(flake_url)) / "clanIcon",
)
run_cmd(cmd)
# Get the flake metadata
meta = nix_metadata(flake_url)
return FlakeConfig(
vm=vm,
flake_url=FlakeId(flake_url),
clan_name=clan_name,
flake_attr=machine_name,
nar_hash=meta["locked"]["narHash"],
icon=icon_path,
description=meta.get("description"),
last_updated=meta["lastModified"],
revision=meta.get("revision"),
)
@dataclass
class InspectOptions:
machine: str
flake: FlakeId
def inspect_command(args: argparse.Namespace) -> None:
inspect_options = InspectOptions(
machine=args.machine,
flake=args.flake or FlakeId(Path.cwd()),
)
res = inspect_flake(
flake_url=str(inspect_options.flake), machine_name=inspect_options.machine
)
print("Clan name:", res.clan_name)
print("Icon:", res.icon)
print("Description:", res.description)
print("Last updated:", res.last_updated)
print("Revision:", res.revision)
def register_inspect_parser(parser: argparse.ArgumentParser) -> None:
parser.add_argument("--machine", type=str, default="defaultVM")
parser.set_defaults(func=inspect_command)