From cb933787ff1087a087df740886ae4c15de075309 Mon Sep 17 00:00:00 2001 From: Qubasa Date: Sun, 31 Dec 2023 00:49:57 +0100 Subject: [PATCH] Added gcroot for clan Icon and VM --- pkgs/clan-cli/clan_cli/dirs.py | 18 ++++ pkgs/clan-cli/clan_cli/flakes/inspect.py | 93 ++++++++----------- pkgs/clan-cli/clan_cli/nix.py | 38 +++++--- pkgs/clan-cli/clan_cli/vms/run.py | 6 +- .../clan-vm-manager.code-workspace | 17 ++-- 5 files changed, 97 insertions(+), 75 deletions(-) diff --git a/pkgs/clan-cli/clan_cli/dirs.py b/pkgs/clan-cli/clan_cli/dirs.py index 98076db3a..72126bb12 100644 --- a/pkgs/clan-cli/clan_cli/dirs.py +++ b/pkgs/clan-cli/clan_cli/dirs.py @@ -1,3 +1,4 @@ +import base64 import logging import os import sys @@ -35,6 +36,23 @@ def user_config_dir() -> Path: return Path(os.getenv("XDG_CONFIG_HOME", os.path.expanduser("~/.config"))) +def user_gcroot_dir() -> Path: + p = user_config_dir() / "clan" / "gcroots" + p.mkdir(parents=True, exist_ok=True) + return p + + +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 = base64.urlsafe_b64encode(flake_url.encode()).decode() + # Create the directory if it already exists append a number to it till it doesn't exist and then create it + clan_gcroot = gcroot_dir / f"{clan_name}-{burl}" + + clan_gcroot.mkdir(parents=True, exist_ok=True) + return clan_gcroot + + def user_history_file() -> Path: return user_config_dir() / "clan" / "history" diff --git a/pkgs/clan-cli/clan_cli/flakes/inspect.py b/pkgs/clan-cli/clan_cli/flakes/inspect.py index a2c5f4e6c..fe0444f15 100644 --- a/pkgs/clan-cli/clan_cli/flakes/inspect.py +++ b/pkgs/clan-cli/clan_cli/flakes/inspect.py @@ -4,6 +4,7 @@ import subprocess from dataclasses import dataclass from pathlib import Path +from ..dirs import specific_groot_dir from ..errors import ClanError from ..machines.list import list_machines from ..nix import nix_build, nix_config, nix_eval, nix_metadata @@ -22,22 +23,7 @@ class FlakeConfig: revision: str | None -def inspect_flake(flake_url: str | Path, flake_attr: str) -> FlakeConfig: - config = nix_config() - system = config["system"] - - machines = list_machines(flake_url) - if flake_attr not in machines: - raise ClanError( - f"Machine {flake_attr} not found in {flake_url}. Available machines: {', '.join(machines)}" - ) - - cmd = nix_eval( - [ - f'{flake_url}#clanInternals.machines."{system}"."{flake_attr}".config.clanCore.clanIcon' - ] - ) - +def run_cmd(cmd: list[str]) -> str: proc = subprocess.run(cmd, text=True, stdout=subprocess.PIPE) assert proc.stdout is not None if proc.returncode != 0: @@ -49,53 +35,54 @@ stdout: {proc.stdout} """ ) - res = proc.stdout.strip() - if res == "null": - icon_path = None - else: - icon_path = res.strip('"') - if not Path(icon_path).exists(): - cmd = nix_build( - [ - f'{flake_url}#clanInternals.machines."{system}"."{flake_attr}".config.clanCore.clanIcon' - ] - ) - proc = subprocess.run(cmd, text=True, capture_output=True) - assert proc.stdout is not None - if proc.returncode != 0: - raise ClanError( - f""" -command: {shlex.join(cmd)} -exit code: {proc.returncode} -stdout: -{proc.stdout} -stderr: -{proc.stderr} -""" - ) + return proc.stdout.strip() + +def inspect_flake(flake_url: str | Path, flake_attr: str) -> FlakeConfig: + config = nix_config() + system = config["system"] + + # Check if the machine exists + machines = list_machines(flake_url) + if flake_attr not in machines: + raise ClanError( + f"Machine {flake_attr} not found in {flake_url}. Available machines: {', '.join(machines)}" + ) + + # Get the cLAN name cmd = nix_eval( [ f'{flake_url}#clanInternals.machines."{system}"."{flake_attr}".config.clanCore.clanName' ] ) + res = run_cmd(cmd) + clan_name = res.strip('"') - proc = subprocess.run(cmd, text=True, capture_output=True) - assert proc.stdout is not None - if proc.returncode != 0: - raise ClanError( - f""" -command: {shlex.join(cmd)} -exit code: {proc.returncode} -stdout: -{proc.stdout} -stderr: -{proc.stderr} -""" + # Get the clan icon path + cmd = nix_eval( + [ + f'{flake_url}#clanInternals.machines."{system}"."{flake_attr}".config.clanCore.clanIcon' + ] + ) + res = run_cmd(cmd) + + # If the icon is null, no icon is set for this cLAN + if res == "null": + icon_path = None + else: + icon_path = res.strip('"') + + cmd = nix_build( + [ + f'{flake_url}#clanInternals.machines."{system}"."{flake_attr}".config.clanCore.clanIcon' + ], + specific_groot_dir(clan_name=clan_name, flake_url=str(flake_url)) + / "clanIcon", ) - clan_name = proc.stdout.strip().strip('"') + run_cmd(cmd) + # Get the flake metadata meta = nix_metadata(flake_url) return FlakeConfig( diff --git a/pkgs/clan-cli/clan_cli/nix.py b/pkgs/clan-cli/clan_cli/nix.py index 34cc5a29f..b9b0acaaf 100644 --- a/pkgs/clan-cli/clan_cli/nix.py +++ b/pkgs/clan-cli/clan_cli/nix.py @@ -25,20 +25,32 @@ def nix_flake_show(flake_url: str | Path) -> list[str]: ) -def nix_build( - flags: list[str], -) -> list[str]: - return ( - nix_command( - [ - "build", - "--no-link", - "--print-out-paths", - "--no-write-lock-file", - ] +def nix_build(flags: list[str], gcroot: Path | None = None) -> list[str]: + if gcroot is not None: + return ( + nix_command( + [ + "build", + "--out-link", + str(gcroot), + "--print-out-paths", + "--no-write-lock-file", + ] + ) + + flags + ) + else: + return ( + nix_command( + [ + "build", + "--no-link", + "--print-out-paths", + "--no-write-lock-file", + ] + ) + + flags ) - + flags - ) def nix_config() -> dict[str, Any]: diff --git a/pkgs/clan-cli/clan_cli/vms/run.py b/pkgs/clan-cli/clan_cli/vms/run.py index 338268d2a..9273f8e5b 100644 --- a/pkgs/clan-cli/clan_cli/vms/run.py +++ b/pkgs/clan-cli/clan_cli/vms/run.py @@ -10,7 +10,7 @@ from dataclasses import dataclass, field from pathlib import Path from typing import IO -from ..dirs import module_root +from ..dirs import module_root, specific_groot_dir from ..errors import ClanError from ..nix import nix_build, nix_config, nix_shell from .inspect import VmConfig, inspect_vm @@ -131,7 +131,9 @@ def get_vm_create_info(vm: VmConfig, nix_options: list[str]) -> dict[str, str]: [ f'{clan_dir}#clanInternals.machines."{system}"."{machine}".config.system.clan.vm.create', *nix_options, - ] + ], + specific_groot_dir(clan_name=vm.clan_name, flake_url=str(vm.flake_url)) + / f"vm-{machine}", ) proc = subprocess.run( cmd, diff --git a/pkgs/clan-vm-manager/clan-vm-manager.code-workspace b/pkgs/clan-vm-manager/clan-vm-manager.code-workspace index e9cebdd9e..08aa93b58 100644 --- a/pkgs/clan-vm-manager/clan-vm-manager.code-workspace +++ b/pkgs/clan-vm-manager/clan-vm-manager.code-workspace @@ -19,15 +19,18 @@ "**/.mypy_cache": true, "**/.reports": true, "**/.ruff_cache": true, - "**/result": true + "**/result": true, + "/nix/store/**": true }, "search.exclude": { - "**/.direnv": true, - "**/.mypy_cache": true, - "**/.ruff_cache": true, - "**/.hypothesis": true, "**/__pycache__": true, - "**/.reports": true - } + "**/.direnv": true, + "**/.hypothesis": true, + "**/.mypy_cache": true, + "**/.reports": true, + "**/.ruff_cache": true, + "/nix/store/**": true + }, + "files.autoSave": "off" } }