add apply "machine" as an alias to clan machines create
I was a bit confused that I was able to list templates but not apply them. Turns out that "apply" only supported disk templates
This commit is contained in:
@@ -198,7 +198,7 @@ This subcommand provides an interface to templates provided by clan.
|
||||
Examples:
|
||||
|
||||
$ clan templates list
|
||||
List all the machines managed by Clan.
|
||||
List all available templates
|
||||
|
||||
Usage differs based on the template type
|
||||
|
||||
@@ -227,6 +227,16 @@ Disk templates
|
||||
|
||||
Real world example
|
||||
$ clan templates apply disk single-disk jon --set mainDisk "/dev/disk/by-id/nvme-WD_PC_SN740_SDDQNQD-512G-1201_232557804368"
|
||||
|
||||
---
|
||||
|
||||
Machine templates
|
||||
|
||||
$ clan templates apply machine [TEMPLATE] [MACHINE_NAME]
|
||||
Will create a new machine [MACHINE_NAME] from the specified [TEMPLATE]
|
||||
|
||||
Real world example
|
||||
$ clan templates apply machine flash-installer my-installer
|
||||
"""
|
||||
),
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
|
||||
@@ -303,6 +303,27 @@ def complete_templates_clan(
|
||||
return []
|
||||
|
||||
|
||||
def complete_templates_machine(
|
||||
_prefix: str,
|
||||
parsed_args: argparse.Namespace,
|
||||
**_kwargs: Any,
|
||||
) -> Iterable[str]:
|
||||
"""Provides completion functionality for machine templates"""
|
||||
flake = (
|
||||
clan_dir_result
|
||||
if (clan_dir_result := clan_dir(getattr(parsed_args, "flake", None)))
|
||||
is not None
|
||||
else "."
|
||||
)
|
||||
|
||||
list_all_templates = list_templates(Flake(flake))
|
||||
machine_template_list = list_all_templates.builtins.get("machine")
|
||||
if machine_template_list:
|
||||
machine_templates = list(machine_template_list)
|
||||
return dict.fromkeys(machine_templates, "machine")
|
||||
return []
|
||||
|
||||
|
||||
def complete_vars_for_machine(
|
||||
_prefix: str,
|
||||
parsed_args: argparse.Namespace,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import argparse
|
||||
|
||||
from .apply_disk import register_apply_disk_template_parser
|
||||
from .apply_machine import register_apply_machine_template_parser
|
||||
|
||||
|
||||
def register_apply_parser(parser: argparse.ArgumentParser) -> None:
|
||||
@@ -11,5 +12,7 @@ def register_apply_parser(parser: argparse.ArgumentParser) -> None:
|
||||
required=True,
|
||||
)
|
||||
disk_parser = subparser.add_parser("disk", help="Apply a disk template")
|
||||
machine_parser = subparser.add_parser("machine", help="Apply a machine template")
|
||||
|
||||
register_apply_disk_template_parser(disk_parser)
|
||||
register_apply_machine_template_parser(machine_parser)
|
||||
|
||||
42
pkgs/clan-cli/clan_cli/templates/apply_machine.py
Normal file
42
pkgs/clan-cli/clan_cli/templates/apply_machine.py
Normal file
@@ -0,0 +1,42 @@
|
||||
import argparse
|
||||
import logging
|
||||
|
||||
from clan_lib.nix_models.clan import InventoryMachine
|
||||
from clan_lib.nix_models.clan import InventoryMachineDeploy as MachineDeploy
|
||||
|
||||
from clan_cli.machines.create import CreateOptions, create_machine
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def apply_command(args: argparse.Namespace) -> None:
|
||||
"""Apply a machine template - actually an alias for machines create --template."""
|
||||
# Create machine using the create_machine API directly
|
||||
machine = InventoryMachine(
|
||||
name=args.machine,
|
||||
tags=[],
|
||||
deploy=MachineDeploy(targetHost=None),
|
||||
)
|
||||
|
||||
opts = CreateOptions(
|
||||
clan_dir=args.flake,
|
||||
machine=machine,
|
||||
template=args.template,
|
||||
)
|
||||
|
||||
create_machine(opts)
|
||||
|
||||
|
||||
def register_apply_machine_template_parser(parser: argparse.ArgumentParser) -> None:
|
||||
parser.add_argument(
|
||||
"template",
|
||||
type=str,
|
||||
help="The name of the machine template to apply",
|
||||
)
|
||||
parser.add_argument(
|
||||
"machine",
|
||||
type=str,
|
||||
help="The name of the machine to create from the template",
|
||||
)
|
||||
|
||||
parser.set_defaults(func=apply_command)
|
||||
79
pkgs/clan-cli/clan_cli/templates/apply_test.py
Normal file
79
pkgs/clan-cli/clan_cli/templates/apply_test.py
Normal file
@@ -0,0 +1,79 @@
|
||||
import json
|
||||
|
||||
import pytest
|
||||
from clan_lib.errors import ClanError
|
||||
from clan_lib.flake import Flake
|
||||
from clan_lib.machines.machines import Machine
|
||||
from clan_lib.templates.disk import set_machine_disk_schema
|
||||
|
||||
from clan_cli.tests.fixtures_flakes import FlakeForTest
|
||||
from clan_cli.tests.helpers import cli
|
||||
|
||||
|
||||
@pytest.mark.with_core
|
||||
def test_templates_apply_machine_and_disk(
|
||||
test_flake_with_core: FlakeForTest,
|
||||
) -> None:
|
||||
"""Test both machine template creation and disk template application."""
|
||||
flake_path = str(test_flake_with_core.path)
|
||||
|
||||
cli.run(
|
||||
[
|
||||
"templates",
|
||||
"apply",
|
||||
"machine",
|
||||
"new-machine",
|
||||
"test-apply-machine",
|
||||
"--flake",
|
||||
flake_path,
|
||||
]
|
||||
)
|
||||
|
||||
# Verify machine was created
|
||||
machine_dir = test_flake_with_core.path / "machines" / "test-apply-machine"
|
||||
assert machine_dir.exists(), "Machine directory should be created"
|
||||
assert (machine_dir / "configuration.nix").exists(), (
|
||||
"Configuration file should exist"
|
||||
)
|
||||
|
||||
facter_content = {
|
||||
"disks": [
|
||||
{
|
||||
"name": "test-disk",
|
||||
"path": "/dev/sda",
|
||||
"size": 107374182400,
|
||||
"type": "disk",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
facter_path = machine_dir / "facter.json"
|
||||
facter_path.write_text(json.dumps(facter_content, indent=2))
|
||||
|
||||
machine = Machine(name="test-apply-machine", flake=Flake(flake_path))
|
||||
set_machine_disk_schema(
|
||||
machine,
|
||||
"single-disk",
|
||||
{"mainDisk": "/dev/sda"},
|
||||
force=False,
|
||||
check_hw=False, # Skip hardware validation for test
|
||||
)
|
||||
|
||||
# Verify disk template was applied by checking that disko.nix exists or was updated
|
||||
disko_file = machine_dir / "disko.nix"
|
||||
assert disko_file.exists(), "Disko configuration should be created"
|
||||
|
||||
# Verify error handling - try to create duplicate machine
|
||||
# Since apply machine now uses machines create, it raises ClanError for duplicates
|
||||
with pytest.raises(ClanError, match="already exists"):
|
||||
cli.run(
|
||||
[
|
||||
"templates",
|
||||
"apply",
|
||||
"machine",
|
||||
"new-machine",
|
||||
"test-apply-machine", # Same name as existing
|
||||
"--flake",
|
||||
flake_path,
|
||||
]
|
||||
)
|
||||
Reference in New Issue
Block a user