forked from clan/clan-core
API: migrate add machine to inventory
This commit is contained in:
parent
d8380ebb98
commit
df934334a2
@ -1,30 +1,85 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
from dataclasses import dataclass
|
import re
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
from clan_cli.api import API
|
from clan_cli.api import API
|
||||||
from clan_cli.config.machine import set_config_for_machine
|
from clan_cli.errors import ClanError
|
||||||
|
from clan_cli.git import commit_file
|
||||||
|
from clan_cli.inventory import Inventory, Machine, dataclass_to_dict
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class MachineCreateRequest:
|
|
||||||
name: str
|
|
||||||
config: dict[str, Any]
|
|
||||||
|
|
||||||
|
|
||||||
@API.register
|
@API.register
|
||||||
def create_machine(flake_dir: str | Path, machine: MachineCreateRequest) -> None:
|
def create_machine(flake_dir: str | Path, machine: Machine) -> None:
|
||||||
set_config_for_machine(Path(flake_dir), machine.name, machine.config)
|
hostname_regex = r"^(?!-)[A-Za-z0-9-]{1,63}(?<!-)$"
|
||||||
|
if not re.match(hostname_regex, machine.name):
|
||||||
|
raise ClanError("Machine name must be a valid hostname")
|
||||||
|
|
||||||
|
inventory = Inventory(machines={}, services={})
|
||||||
|
|
||||||
|
inventory_file = Path(flake_dir) / "inventory.json"
|
||||||
|
if inventory_file.exists():
|
||||||
|
with open(inventory_file) as f:
|
||||||
|
try:
|
||||||
|
res = json.load(f)
|
||||||
|
inventory = Inventory.from_dict(res)
|
||||||
|
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
raise ClanError(f"Error decoding inventory file: {e}")
|
||||||
|
|
||||||
|
inventory.machines.update({machine.name: machine})
|
||||||
|
|
||||||
|
with open(inventory_file, "w") as g:
|
||||||
|
d = dataclass_to_dict(inventory)
|
||||||
|
json.dump(d, g, indent=2)
|
||||||
|
|
||||||
|
if flake_dir is not None:
|
||||||
|
commit_file(inventory_file, Path(flake_dir))
|
||||||
|
|
||||||
|
|
||||||
def create_command(args: argparse.Namespace) -> None:
|
def create_command(args: argparse.Namespace) -> None:
|
||||||
create_machine(args.flake, MachineCreateRequest(args.machine, dict()))
|
create_machine(
|
||||||
|
args.flake,
|
||||||
|
Machine(
|
||||||
|
name=args.machine,
|
||||||
|
system=args.system,
|
||||||
|
description=args.description,
|
||||||
|
tags=args.tags,
|
||||||
|
icon=args.icon,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def register_create_parser(parser: argparse.ArgumentParser) -> None:
|
def register_create_parser(parser: argparse.ArgumentParser) -> None:
|
||||||
parser.add_argument("machine", type=str)
|
parser.add_argument("machine", type=str)
|
||||||
parser.set_defaults(func=create_command)
|
parser.set_defaults(func=create_command)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--system",
|
||||||
|
type=str,
|
||||||
|
default=None,
|
||||||
|
help="Host platform to use. i.e. 'x86_64-linux' or 'aarch64-darwin' etc.",
|
||||||
|
metavar="PLATFORM",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--description",
|
||||||
|
type=str,
|
||||||
|
default=None,
|
||||||
|
help="A description of the machine.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--icon",
|
||||||
|
type=str,
|
||||||
|
default=None,
|
||||||
|
help="Path to an icon to use for the machine. - Must be a path to icon file relative to the flake directory, or a public url.",
|
||||||
|
metavar="PATH",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--tags",
|
||||||
|
nargs="+",
|
||||||
|
default=[],
|
||||||
|
help="Tags to associate with the machine. Can be used to assign multiple machines to services.",
|
||||||
|
)
|
||||||
|
@ -7,7 +7,8 @@ from clan_cli.config.machine import (
|
|||||||
verify_machine_config,
|
verify_machine_config,
|
||||||
)
|
)
|
||||||
from clan_cli.config.schema import machine_schema
|
from clan_cli.config.schema import machine_schema
|
||||||
from clan_cli.machines.create import MachineCreateRequest, create_machine
|
from clan_cli.inventory import Machine
|
||||||
|
from clan_cli.machines.create import create_machine
|
||||||
from clan_cli.machines.list import list_machines
|
from clan_cli.machines.list import list_machines
|
||||||
|
|
||||||
|
|
||||||
@ -22,14 +23,21 @@ def test_create_machine_on_minimal_clan(test_flake_minimal: FlakeForTest) -> Non
|
|||||||
assert list_machines(test_flake_minimal.path) == []
|
assert list_machines(test_flake_minimal.path) == []
|
||||||
create_machine(
|
create_machine(
|
||||||
test_flake_minimal.path,
|
test_flake_minimal.path,
|
||||||
MachineCreateRequest(
|
Machine(
|
||||||
name="foo", config=dict(nixpkgs=dict(hostSystem="x86_64-linux"))
|
name="foo",
|
||||||
|
system="x86_64-linux",
|
||||||
|
description="A test machine",
|
||||||
|
tags=["test"],
|
||||||
|
icon=None,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
assert list_machines(test_flake_minimal.path) == ["foo"]
|
assert list_machines(test_flake_minimal.path) == ["foo"]
|
||||||
|
|
||||||
|
# Writes into settings.json
|
||||||
set_config_for_machine(
|
set_config_for_machine(
|
||||||
test_flake_minimal.path, "foo", dict(services=dict(openssh=dict(enable=True)))
|
test_flake_minimal.path, "foo", dict(services=dict(openssh=dict(enable=True)))
|
||||||
)
|
)
|
||||||
|
|
||||||
config = config_for_machine(test_flake_minimal.path, "foo")
|
config = config_for_machine(test_flake_minimal.path, "foo")
|
||||||
assert config["services"]["openssh"]["enable"]
|
assert config["services"]["openssh"]["enable"]
|
||||||
assert verify_machine_config(test_flake_minimal.path, "foo") is None
|
assert verify_machine_config(test_flake_minimal.path, "foo") is None
|
||||||
|
Loading…
Reference in New Issue
Block a user