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:
Jörg Thalheim
2025-08-27 14:30:03 +02:00
committed by Mic92
parent 5962149e55
commit 758eacd27e
5 changed files with 156 additions and 1 deletions

View File

@@ -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)

View 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)

View 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,
]
)