CLI: machine create use patch inventory for partial updates
This commit is contained in:
committed by
hsjobeki
parent
718e553211
commit
dee284d669
@@ -10,11 +10,14 @@ from clan_cli.dirs import get_clan_flake_toplevel_or_env
|
|||||||
from clan_cli.errors import ClanError
|
from clan_cli.errors import ClanError
|
||||||
from clan_cli.flake import Flake
|
from clan_cli.flake import Flake
|
||||||
from clan_cli.git import commit_file
|
from clan_cli.git import commit_file
|
||||||
from clan_cli.inventory import Machine as InventoryMachine
|
from clan_cli.inventory import (
|
||||||
|
Machine as InventoryMachine,
|
||||||
|
patch_inventory_with,
|
||||||
|
dataclass_to_dict,
|
||||||
|
)
|
||||||
from clan_cli.inventory import (
|
from clan_cli.inventory import (
|
||||||
MachineDeploy,
|
MachineDeploy,
|
||||||
get_inventory,
|
get_inventory,
|
||||||
set_inventory,
|
|
||||||
)
|
)
|
||||||
from clan_cli.machines.list import list_nixos_machines
|
from clan_cli.machines.list import list_nixos_machines
|
||||||
from clan_cli.templates import (
|
from clan_cli.templates import (
|
||||||
@@ -100,20 +103,18 @@ def create_machine(opts: CreateOptions) -> None:
|
|||||||
|
|
||||||
copy_from_nixstore(src, dst)
|
copy_from_nixstore(src, dst)
|
||||||
|
|
||||||
inventory = get_inventory(clan_dir)
|
|
||||||
|
|
||||||
target_host = opts.target_host
|
target_host = opts.target_host
|
||||||
# TODO: We should allow the template to specify machine metadata if not defined by user
|
|
||||||
new_machine = opts.machine
|
new_machine = opts.machine
|
||||||
if target_host:
|
if target_host:
|
||||||
new_machine["deploy"] = {"targetHost": target_host}
|
new_machine["deploy"] = {"targetHost": target_host}
|
||||||
|
|
||||||
inventory["machines"] = inventory.get("machines", {})
|
patch_inventory_with(
|
||||||
inventory["machines"][machine_name] = new_machine
|
clan_dir, f"machines.{machine_name}", dataclass_to_dict(new_machine)
|
||||||
|
)
|
||||||
|
|
||||||
# Commit at the end in that order to avoid committing halve-baked machines
|
# Commit at the end in that order to avoid committing halve-baked machines
|
||||||
# TODO: automatic rollbacks if something goes wrong
|
# TODO: automatic rollbacks if something goes wrong
|
||||||
set_inventory(inventory, clan_dir, "Imported machine from template")
|
|
||||||
|
|
||||||
commit_file(
|
commit_file(
|
||||||
clan_dir / "machines" / machine_name,
|
clan_dir / "machines" / machine_name,
|
||||||
|
|||||||
@@ -307,9 +307,7 @@ def test_update_list() -> None:
|
|||||||
assert writeables == {"writeable": {"foo"}, "non_writeable": set()}
|
assert writeables == {"writeable": {"foo"}, "non_writeable": set()}
|
||||||
|
|
||||||
# Add "C" to the list
|
# Add "C" to the list
|
||||||
update = {
|
update = {"foo": ["A", "B", "C"]} # User wants to add "C"
|
||||||
"foo": ["A", "B", "C"] # User wants to add "C"
|
|
||||||
}
|
|
||||||
|
|
||||||
patchset, _ = calc_patches(
|
patchset, _ = calc_patches(
|
||||||
data_disk, update, all_values=data_eval, writeables=writeables
|
data_disk, update, all_values=data_eval, writeables=writeables
|
||||||
@@ -320,9 +318,7 @@ def test_update_list() -> None:
|
|||||||
# "foo": ["A", "B"]
|
# "foo": ["A", "B"]
|
||||||
# Remove "B" from the list
|
# Remove "B" from the list
|
||||||
# Expected is [ ] because ["A"] is defined in nix
|
# Expected is [ ] because ["A"] is defined in nix
|
||||||
update = {
|
update = {"foo": ["A"]} # User wants to remove "B"
|
||||||
"foo": ["A"] # User wants to remove "B"
|
|
||||||
}
|
|
||||||
|
|
||||||
patchset, _ = calc_patches(
|
patchset, _ = calc_patches(
|
||||||
data_disk, update, all_values=data_eval, writeables=writeables
|
data_disk, update, all_values=data_eval, writeables=writeables
|
||||||
@@ -350,9 +346,7 @@ def test_update_list_duplicates() -> None:
|
|||||||
assert writeables == {"writeable": {"foo"}, "non_writeable": set()}
|
assert writeables == {"writeable": {"foo"}, "non_writeable": set()}
|
||||||
|
|
||||||
# Add "A" to the list
|
# Add "A" to the list
|
||||||
update = {
|
update = {"foo": ["A", "B", "A"]} # User wants to add duplicate "A"
|
||||||
"foo": ["A", "B", "A"] # User wants to add duplicate "A"
|
|
||||||
}
|
|
||||||
|
|
||||||
with pytest.raises(ClanError) as error:
|
with pytest.raises(ClanError) as error:
|
||||||
calc_patches(data_disk, update, all_values=data_eval, writeables=writeables)
|
calc_patches(data_disk, update, all_values=data_eval, writeables=writeables)
|
||||||
@@ -363,6 +357,31 @@ def test_update_list_duplicates() -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_dont_persist_defaults() -> None:
|
||||||
|
"""
|
||||||
|
Default values should not be persisted to disk if not explicitly requested by the user.
|
||||||
|
"""
|
||||||
|
|
||||||
|
prios = {
|
||||||
|
"enabled": {"__prio": 1500},
|
||||||
|
"config": {"__prio": 100},
|
||||||
|
}
|
||||||
|
data_eval = {
|
||||||
|
"enabled": True,
|
||||||
|
"config": {"foo": "bar"},
|
||||||
|
}
|
||||||
|
data_disk = {}
|
||||||
|
writeables = determine_writeability(prios, data_eval, data_disk)
|
||||||
|
assert writeables == {"writeable": {"config", "enabled"}, "non_writeable": set()}
|
||||||
|
|
||||||
|
update = {"config": {"foo": "foo"}}
|
||||||
|
patchset, delete_set = calc_patches(
|
||||||
|
data_disk, update, all_values=data_eval, writeables=writeables
|
||||||
|
)
|
||||||
|
assert patchset == {"config.foo": "foo"}
|
||||||
|
assert delete_set == set()
|
||||||
|
|
||||||
|
|
||||||
def test_update_mismatching_update_type() -> None:
|
def test_update_mismatching_update_type() -> None:
|
||||||
prios = {
|
prios = {
|
||||||
"foo": {
|
"foo": {
|
||||||
|
|||||||
Reference in New Issue
Block a user