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:
@@ -391,14 +391,14 @@ const MachineForm = (props: MachineDetailsProps) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const machine_response = await callApi("set_inv_machine", {
|
const machine_response = await callApi("update_machine", {
|
||||||
machine: {
|
machine: {
|
||||||
name: props.initialData.machine.name || "My machine",
|
name: props.initialData.machine.name || "My machine",
|
||||||
flake: {
|
flake: {
|
||||||
identifier: curr_uri,
|
identifier: curr_uri,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
inventory_machine: {
|
update: {
|
||||||
...values.machine,
|
...values.machine,
|
||||||
// TODO: Remove this workaround
|
// TODO: Remove this workaround
|
||||||
tags: Array.from(
|
tags: Array.from(
|
||||||
|
|||||||
@@ -122,8 +122,8 @@ def set_async_ctx(ctx: AsyncContext) -> None:
|
|||||||
|
|
||||||
class AsyncThread(threading.Thread, Generic[P, R]):
|
class AsyncThread(threading.Thread, Generic[P, R]):
|
||||||
function: Callable[P, R]
|
function: Callable[P, R]
|
||||||
args: Any
|
args: tuple[Any, ...]
|
||||||
kwargs: Any
|
kwargs: dict[str, Any]
|
||||||
result: AsyncResult[R] | None
|
result: AsyncResult[R] | None
|
||||||
finished: bool
|
finished: bool
|
||||||
condition: threading.Condition
|
condition: threading.Condition
|
||||||
@@ -155,6 +155,7 @@ class AsyncThread(threading.Thread, Generic[P, R]):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
set_async_ctx(self.async_opts.async_ctx)
|
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))
|
self.result = AsyncResult(_result=self.function(*self.args, **self.kwargs))
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.result = AsyncResult(_result=ex)
|
self.result = AsyncResult(_result=ex)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import urllib
|
import urllib.parse
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ def generate_facts(
|
|||||||
raise ClanError(msg)
|
raise ClanError(msg)
|
||||||
|
|
||||||
if not was_regenerated and len(machines) > 0:
|
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
|
return was_regenerated
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from clan_cli.machines.machines import Machine
|
|||||||
|
|
||||||
|
|
||||||
@API.register
|
@API.register
|
||||||
def get_inv_machine(machine: Machine) -> InventoryMachine:
|
def get_machine(machine: Machine) -> InventoryMachine:
|
||||||
inventory_store = InventoryStore(flake=machine.flake)
|
inventory_store = InventoryStore(flake=machine.flake)
|
||||||
inventory = inventory_store.read()
|
inventory = inventory_store.read()
|
||||||
|
|
||||||
@@ -23,12 +23,12 @@ def get_inv_machine(machine: Machine) -> InventoryMachine:
|
|||||||
|
|
||||||
|
|
||||||
@API.register
|
@API.register
|
||||||
def set_inv_machine(machine: Machine, inventory_machine: InventoryMachine) -> None:
|
def update_machine(machine: Machine, update: InventoryMachine) -> None:
|
||||||
assert machine.name == inventory_machine["name"], "Machine name mismatch"
|
assert machine.name == update.get("name", machine.name), "Machine name mismatch"
|
||||||
inventory_store = InventoryStore(flake=machine.flake)
|
inventory_store = InventoryStore(flake=machine.flake)
|
||||||
inventory = inventory_store.read()
|
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_store.write(
|
||||||
inventory, message=f"Update information about machine {machine.name}"
|
inventory, message=f"Update information about machine {machine.name}"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from dataclasses import dataclass
|
|||||||
from clan_lib.api import API
|
from clan_lib.api import API
|
||||||
from clan_lib.api.disk import MachineDiskMatter
|
from clan_lib.api.disk import MachineDiskMatter
|
||||||
from clan_lib.api.modules import parse_frontmatter
|
from clan_lib.api.modules import parse_frontmatter
|
||||||
|
from clan_lib.errors import ClanError
|
||||||
from clan_lib.flake.flake import Flake
|
from clan_lib.flake.flake import Flake
|
||||||
from clan_lib.nix_models.inventory import Machine as InventoryMachine
|
from clan_lib.nix_models.inventory import Machine as InventoryMachine
|
||||||
from clan_lib.persist.inventory_store import InventoryStore
|
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.completions import add_dynamic_completer, complete_tags
|
||||||
from clan_cli.dirs import specific_machine_dir
|
from clan_cli.dirs import specific_machine_dir
|
||||||
from clan_cli.machines.hardware import HardwareConfig
|
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
|
from clan_cli.machines.machines import Machine
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@@ -42,12 +43,19 @@ def list_machines(
|
|||||||
nix_options = []
|
nix_options = []
|
||||||
|
|
||||||
for inv_machine in inventory.get("machines", {}).values():
|
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(
|
machine = Machine(
|
||||||
name=inv_machine["name"],
|
name=name,
|
||||||
flake=flake,
|
flake=flake,
|
||||||
nix_options=nix_options,
|
nix_options=nix_options,
|
||||||
)
|
)
|
||||||
res[machine.name] = machine
|
res[machine.name] = machine
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
@@ -61,8 +69,9 @@ def query_machines_by_tags(flake: Flake, tags: list[str]) -> dict[str, Machine]:
|
|||||||
|
|
||||||
filtered_machines = {}
|
filtered_machines = {}
|
||||||
for machine in machines.values():
|
for machine in machines.values():
|
||||||
inv_machine = get_inv_machine(machine)
|
inv_machine = get_machine(machine)
|
||||||
if all(tag in inv_machine["tags"] for tag in tags):
|
machine_tags = inv_machine.get("tags", [])
|
||||||
|
if all(tag in machine_tags for tag in tags):
|
||||||
filtered_machines[machine.name] = machine
|
filtered_machines[machine.name] = machine
|
||||||
|
|
||||||
return filtered_machines
|
return filtered_machines
|
||||||
@@ -88,7 +97,7 @@ def extract_header(c: str) -> str:
|
|||||||
|
|
||||||
@API.register
|
@API.register
|
||||||
def get_machine_details(machine: Machine) -> MachineDetails:
|
def get_machine_details(machine: Machine) -> MachineDetails:
|
||||||
machine_inv = get_inv_machine(machine)
|
machine_inv = get_machine(machine)
|
||||||
hw_config = HardwareConfig.detect_type(machine)
|
hw_config = HardwareConfig.detect_type(machine)
|
||||||
|
|
||||||
machine_dir = specific_machine_dir(machine)
|
machine_dir = specific_machine_dir(machine)
|
||||||
|
|||||||
@@ -297,6 +297,13 @@ def get_public_age_keys(contents: str) -> set[str]:
|
|||||||
|
|
||||||
if match:
|
if match:
|
||||||
recipient = match[1]
|
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)
|
keys.add(recipient)
|
||||||
|
|
||||||
if line.startswith("#"):
|
if line.startswith("#"):
|
||||||
|
|||||||
@@ -56,17 +56,33 @@ def list_state_folders(machine: Machine, service: None | str = None) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
for service in state:
|
for service in state:
|
||||||
|
if not service:
|
||||||
|
continue
|
||||||
|
|
||||||
print(f"· service: {service}")
|
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:")
|
print(" folders:")
|
||||||
for folder in folders:
|
for folder in folders:
|
||||||
print(f" - {folder}")
|
print(f" - {folder}")
|
||||||
if pre_backup := state.get(service)["preBackupCommand"]:
|
|
||||||
|
pre_backup = service_cfg.get("preBackupCommand")
|
||||||
|
if pre_backup:
|
||||||
print(f" preBackupCommand: {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}")
|
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(f" postRestoreCommand: {post_restore}")
|
||||||
|
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
from dataclasses import is_dataclass
|
from dataclasses import is_dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import cast
|
||||||
|
|
||||||
from clan_lib.api import API
|
from clan_lib.api import API
|
||||||
from clan_lib.api.util import JSchemaTypeError, type_to_dict
|
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)
|
dataclass_type = getattr(module, class_name, None)
|
||||||
|
|
||||||
if dataclass_type and is_dataclass(dataclass_type):
|
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}"
|
msg = f"Could not load dataclass {class_name} from file: {file_path}"
|
||||||
raise ClanError(msg)
|
raise ClanError(msg)
|
||||||
|
|||||||
Reference in New Issue
Block a user