Merge pull request 'Refactor(cli): name set_inv_machine back to set_machine' (#3681) from hsjobeki/clan-core:chores-2 into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3681
This commit is contained in:
hsjobeki
2025-05-16 16:23:51 +00:00
9 changed files with 54 additions and 20 deletions

View File

@@ -391,14 +391,14 @@ const MachineForm = (props: MachineDetailsProps) => {
return;
}
const machine_response = await callApi("set_inv_machine", {
const machine_response = await callApi("update_machine", {
machine: {
name: props.initialData.machine.name || "My machine",
flake: {
identifier: curr_uri,
},
},
inventory_machine: {
update: {
...values.machine,
// TODO: Remove this workaround
tags: Array.from(

View File

@@ -122,8 +122,8 @@ def set_async_ctx(ctx: AsyncContext) -> None:
class AsyncThread(threading.Thread, Generic[P, R]):
function: Callable[P, R]
args: Any
kwargs: Any
args: tuple[Any, ...]
kwargs: dict[str, Any]
result: AsyncResult[R] | None
finished: bool
condition: threading.Condition
@@ -155,6 +155,7 @@ class AsyncThread(threading.Thread, Generic[P, R]):
"""
try:
set_async_ctx(self.async_opts.async_ctx)
# Arguments for ParamSpec "P@AsyncThread" are missing
self.result = AsyncResult(_result=self.function(*self.args, **self.kwargs))
except Exception as ex:
self.result = AsyncResult(_result=ex)

View File

@@ -1,7 +1,7 @@
import logging
import os
import sys
import urllib
import urllib.parse
from enum import Enum
from pathlib import Path
from typing import TYPE_CHECKING

View File

@@ -218,7 +218,7 @@ def generate_facts(
raise ClanError(msg)
if not was_regenerated and len(machines) > 0:
machine.info("All secrets and facts are already up to date")
log.info("All secrets and facts are already up to date")
return was_regenerated

View File

@@ -10,7 +10,7 @@ from clan_cli.machines.machines import Machine
@API.register
def get_inv_machine(machine: Machine) -> InventoryMachine:
def get_machine(machine: Machine) -> InventoryMachine:
inventory_store = InventoryStore(flake=machine.flake)
inventory = inventory_store.read()
@@ -23,12 +23,12 @@ def get_inv_machine(machine: Machine) -> InventoryMachine:
@API.register
def set_inv_machine(machine: Machine, inventory_machine: InventoryMachine) -> None:
assert machine.name == inventory_machine["name"], "Machine name mismatch"
def update_machine(machine: Machine, update: InventoryMachine) -> None:
assert machine.name == update.get("name", machine.name), "Machine name mismatch"
inventory_store = InventoryStore(flake=machine.flake)
inventory = inventory_store.read()
apply_patch(inventory, f"machines.{machine.name}", inventory_machine)
apply_patch(inventory, f"machines.{machine.name}", update)
inventory_store.write(
inventory, message=f"Update information about machine {machine.name}"
)

View File

@@ -6,6 +6,7 @@ from dataclasses import dataclass
from clan_lib.api import API
from clan_lib.api.disk import MachineDiskMatter
from clan_lib.api.modules import parse_frontmatter
from clan_lib.errors import ClanError
from clan_lib.flake.flake import Flake
from clan_lib.nix_models.inventory import Machine as InventoryMachine
from clan_lib.persist.inventory_store import InventoryStore
@@ -13,7 +14,7 @@ from clan_lib.persist.inventory_store import InventoryStore
from clan_cli.completions import add_dynamic_completer, complete_tags
from clan_cli.dirs import specific_machine_dir
from clan_cli.machines.hardware import HardwareConfig
from clan_cli.machines.inventory import get_inv_machine
from clan_cli.machines.inventory import get_machine
from clan_cli.machines.machines import Machine
log = logging.getLogger(__name__)
@@ -42,12 +43,19 @@ def list_machines(
nix_options = []
for inv_machine in inventory.get("machines", {}).values():
name = inv_machine.get("name")
# Technically, this should not happen, but we are defensive here.
if name is None:
msg = "InternalError: Machine name is required. But got a machine without a name."
raise ClanError(msg)
machine = Machine(
name=inv_machine["name"],
name=name,
flake=flake,
nix_options=nix_options,
)
res[machine.name] = machine
return res
@@ -61,8 +69,9 @@ def query_machines_by_tags(flake: Flake, tags: list[str]) -> dict[str, Machine]:
filtered_machines = {}
for machine in machines.values():
inv_machine = get_inv_machine(machine)
if all(tag in inv_machine["tags"] for tag in tags):
inv_machine = get_machine(machine)
machine_tags = inv_machine.get("tags", [])
if all(tag in machine_tags for tag in tags):
filtered_machines[machine.name] = machine
return filtered_machines
@@ -88,7 +97,7 @@ def extract_header(c: str) -> str:
@API.register
def get_machine_details(machine: Machine) -> MachineDetails:
machine_inv = get_inv_machine(machine)
machine_inv = get_machine(machine)
hw_config = HardwareConfig.detect_type(machine)
machine_dir = specific_machine_dir(machine)

View File

@@ -297,6 +297,13 @@ def get_public_age_keys(contents: str) -> set[str]:
if match:
recipient = match[1]
if not recipient:
msg = (
f"Empty or invalid recipient on line {line_number}. "
"Expected a valid `# recipient: age1...` comment or a recognized recipient format."
)
raise ClanError(msg)
keys.add(recipient)
if line.startswith("#"):

View File

@@ -56,17 +56,33 @@ def list_state_folders(machine: Machine, service: None | str = None) -> None:
)
for service in state:
if not service:
continue
print(f"· service: {service}")
if folders := state.get(service)["folders"]:
service_cfg = state.get(service)
if not service_cfg:
continue # or handle missing config
folders = service_cfg.get("folders")
if folders:
print(" folders:")
for folder in folders:
print(f" - {folder}")
if pre_backup := state.get(service)["preBackupCommand"]:
pre_backup = service_cfg.get("preBackupCommand")
if pre_backup:
print(f" preBackupCommand: {pre_backup}")
if pre_restore := state.get(service)["preRestoreCommand"]:
pre_restore = service_cfg.get("preRestoreCommand")
if pre_restore:
print(f" preRestoreCommand: {pre_restore}")
if post_restore := state.get(service)["postRestoreCommand"]:
post_restore = service_cfg.get("postRestoreCommand")
if post_restore:
print(f" postRestoreCommand: {post_restore}")
print("")

View File

@@ -4,6 +4,7 @@ import os
import sys
from dataclasses import is_dataclass
from pathlib import Path
from typing import cast
from clan_lib.api import API
from clan_lib.api.util import JSchemaTypeError, type_to_dict
@@ -108,7 +109,7 @@ def load_dataclass_from_file(
dataclass_type = getattr(module, class_name, None)
if dataclass_type and is_dataclass(dataclass_type):
return dataclass_type
return cast(type, dataclass_type)
msg = f"Could not load dataclass {class_name} from file: {file_path}"
raise ClanError(msg)