1
0
forked from clan/clan-core

VMs: ensure state dirs don't collide between clans

This commit is contained in:
DavHau 2024-01-09 16:53:52 +07:00
parent 2566fccfcf
commit 520ff0b334
4 changed files with 31 additions and 13 deletions

View File

@ -15,6 +15,11 @@ def find_git_repo_root() -> Path | None:
return find_toplevel([".git"])
def clan_key_safe(clan_name: str, flake_url: str) -> str:
quoted_url = urllib.parse.quote_plus(flake_url)
return f"{clan_name}-{quoted_url}"
def find_toplevel(top_level_files: list[str]) -> Path | None:
"""Returns the path to the toplevel of the clan flake"""
for project_file in top_level_files:
@ -45,9 +50,7 @@ def user_gcroot_dir() -> Path:
def specific_groot_dir(*, clan_name: str, flake_url: str) -> Path:
# Always build icon so that we can symlink it to the gcroot
gcroot_dir = user_gcroot_dir()
burl = urllib.parse.quote_plus(flake_url)
clan_gcroot = gcroot_dir / f"{clan_name}-{burl}"
clan_gcroot = gcroot_dir / clan_key_safe(clan_name, flake_url)
clan_gcroot.mkdir(parents=True, exist_ok=True)
return clan_gcroot
@ -56,8 +59,9 @@ def user_history_file() -> Path:
return user_config_dir() / "clan" / "history"
def vm_state_dir(clan_name: str, vm_name: str) -> Path:
return user_config_dir() / "clan" / "vmstate" / clan_name / vm_name
def vm_state_dir(clan_name: str, flake_url: str, vm_name: str) -> Path:
clan_key = clan_key_safe(clan_name, flake_url)
return user_config_dir() / "clan" / "vmstate" / clan_key / vm_name
def machines_dir(flake_dir: Path) -> Path:

View File

@ -255,7 +255,7 @@ def run_vm(
secrets_dir = generate_secrets(vm, nixos_config, tmpdir, log_fd)
disk_img = prepare_disk(tmpdir, log_fd)
state_dir = vm_state_dir(vm.clan_name, machine)
state_dir = vm_state_dir(vm.clan_name, str(vm.flake_url), machine)
state_dir.mkdir(parents=True, exist_ok=True)
qemu_cmd = qemu_command(

View File

@ -15,3 +15,21 @@
# monkeypatch.chdir(subdir)
# (subdir / ".clan-flake").touch()
# assert _get_clan_flake_toplevel() == subdir
from clan_cli.dirs import clan_key_safe, vm_state_dir
def test_clan_key_safe() -> None:
assert clan_key_safe("clan1", "/foo/bar") == "clan1-%2Ffoo%2Fbar"
def test_vm_state_dir_identity() -> None:
dir1 = vm_state_dir("clan1", "https://some.clan", "vm1")
dir2 = vm_state_dir("clan1", "https://some.clan", "vm1")
assert str(dir1) == str(dir2)
def test_vm_state_dir_no_collision() -> None:
dir1 = vm_state_dir("clan1", "/foo/bar", "vm1")
dir2 = vm_state_dir("clan1", "https://some.clan", "vm1")
assert str(dir1) != str(dir2)

View File

@ -7,6 +7,8 @@ from cli import Cli
from fixtures_flakes import FlakeForTest, generate_flake
from root import CLAN_CORE
from clan_cli.dirs import vm_state_dir
if TYPE_CHECKING:
from age_keys import KeyPair
@ -89,14 +91,8 @@ def test_vm_persistence(
)
monkeypatch.chdir(flake.path)
Cli().run(["vms", "run", "my_machine"])
test_file = (
temporary_home
/ ".config"
/ "clan"
/ "vmstate"
/ "_test_vm_persistence"
/ "my_machine"
vm_state_dir("_test_vm_persistence", str(flake.path), "my_machine")
/ "var"
/ "my-state"
/ "test"