pkgs/clan: Add machine validator with suggestion logic
Add machine validator with suggestion logic to: - `clan machines update` - `clan machines delete` - `clan machines update-hardware-config`
This commit is contained in:
@@ -3,6 +3,7 @@ import logging
|
||||
|
||||
from clan_lib.machines.delete import delete_machine
|
||||
from clan_lib.machines.machines import Machine
|
||||
from clan_lib.machines.suggestions import validate_machine_names
|
||||
|
||||
from clan_cli.completions import add_dynamic_completer, complete_machines
|
||||
|
||||
@@ -10,6 +11,7 @@ log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def delete_command(args: argparse.Namespace) -> None:
|
||||
validate_machine_names([args.name], args.flake)
|
||||
delete_machine(Machine(flake=args.flake, name=args.name))
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ from clan_lib.machines.hardware import (
|
||||
generate_machine_hardware_info,
|
||||
)
|
||||
from clan_lib.machines.machines import Machine
|
||||
from clan_lib.machines.suggestions import validate_machine_names
|
||||
from clan_lib.ssh.remote import Remote
|
||||
|
||||
from clan_cli.completions import add_dynamic_completer, complete_machines
|
||||
@@ -17,6 +18,7 @@ log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def update_hardware_config_command(args: argparse.Namespace) -> None:
|
||||
validate_machine_names([args.machine], args.flake)
|
||||
host_key_check = args.host_key_check
|
||||
machine = Machine(flake=args.flake, name=args.machine)
|
||||
opts = HardwareGenerateOptions(
|
||||
|
||||
@@ -5,6 +5,7 @@ import sys
|
||||
from clan_lib.async_run import AsyncContext, AsyncOpts, AsyncRuntime
|
||||
from clan_lib.errors import ClanError
|
||||
from clan_lib.machines.machines import Machine
|
||||
from clan_lib.machines.suggestions import validate_machine_names
|
||||
from clan_lib.machines.update import deploy_machine
|
||||
from clan_lib.nix import nix_config
|
||||
from clan_lib.ssh.remote import Remote
|
||||
@@ -45,6 +46,9 @@ def update_command(args: argparse.Namespace) -> None:
|
||||
msg = f"No machines found with tags: {', '.join(args.tags)}"
|
||||
raise ClanError(msg)
|
||||
|
||||
if args.machines:
|
||||
validate_machine_names(args.machines, args.flake)
|
||||
|
||||
for machine_name in selected_machines:
|
||||
machine = Machine(name=machine_name, flake=args.flake)
|
||||
machines.append(machine)
|
||||
|
||||
@@ -90,6 +90,57 @@ def test_machines_update_with_tags(
|
||||
assert args.tags == ["vm"]
|
||||
|
||||
|
||||
@pytest.mark.impure
|
||||
def test_machines_update_nonexistent_machine(
|
||||
test_flake_with_core: fixtures_flakes.FlakeForTest,
|
||||
) -> None:
|
||||
"""Test that update command gives helpful error messages for non-existent machines."""
|
||||
from clan_lib.errors import ClanError
|
||||
|
||||
with pytest.raises(ClanError) as exc_info:
|
||||
cli.run(
|
||||
[
|
||||
"machines",
|
||||
"update",
|
||||
"--flake",
|
||||
str(test_flake_with_core.path),
|
||||
"nonexistent-machine",
|
||||
]
|
||||
)
|
||||
|
||||
error_message = str(exc_info.value)
|
||||
assert "nonexistent-machine" in error_message
|
||||
assert "not found." in error_message
|
||||
# Should suggest similar machines (vm1, vm2 exist in test flake)
|
||||
assert "Did you mean:" in error_message or "Available machines:" in error_message
|
||||
|
||||
|
||||
@pytest.mark.impure
|
||||
def test_machines_update_typo_in_machine_name(
|
||||
test_flake_with_core: fixtures_flakes.FlakeForTest,
|
||||
) -> None:
|
||||
"""Test that update command suggests similar machine names for typos."""
|
||||
from clan_lib.errors import ClanError
|
||||
|
||||
with pytest.raises(ClanError) as exc_info:
|
||||
cli.run(
|
||||
[
|
||||
"machines",
|
||||
"update",
|
||||
"--flake",
|
||||
str(test_flake_with_core.path),
|
||||
"v1", # typo of "vm1"
|
||||
]
|
||||
)
|
||||
|
||||
error_message = str(exc_info.value)
|
||||
assert "v1" in error_message
|
||||
assert "not found." in error_message
|
||||
assert "Did you mean:" in error_message
|
||||
# Should suggest vm1 as it's the closest match
|
||||
assert "vm1" in error_message
|
||||
|
||||
|
||||
@pytest.mark.with_core
|
||||
def test_machine_delete(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
|
||||
Reference in New Issue
Block a user