refactor: move clan_cli.error to clan_lib.error

This commit is contained in:
Johannes Kirschbauer
2025-05-16 14:10:59 +02:00
parent 9a642e465f
commit f210b2f9a6
87 changed files with 149 additions and 109 deletions

View File

@@ -14,6 +14,7 @@ from .clan import show, update
# API endpoints that are not used in the cli.
__all__ = ["directory", "disk", "mdns_discovery", "modules", "update"]
from clan_lib.errors import ClanError
from clan_lib.flake.flake import Flake
from . import (
@@ -26,7 +27,6 @@ from . import (
)
from .custom_logger import setup_logging
from .dirs import get_clan_flake_toplevel_or_env
from .errors import ClanError
from .facts import cli as facts
from .flash import cli as flash_cli
from .hyperlink import help_hyperlink

View File

@@ -7,7 +7,7 @@ from collections.abc import Callable
from dataclasses import dataclass, field
from typing import IO, Any, Generic, ParamSpec, TypeVar
from clan_cli.errors import ClanError
from clan_lib.errors import ClanError
log = logging.getLogger(__name__)

View File

@@ -1,12 +1,13 @@
import argparse
import logging
from clan_lib.errors import ClanError
from clan_cli.completions import (
add_dynamic_completer,
complete_backup_providers_for_machine,
complete_machines,
)
from clan_cli.errors import ClanError
from clan_cli.machines.machines import Machine
log = logging.getLogger(__name__)

View File

@@ -2,13 +2,14 @@ import argparse
import json
from dataclasses import dataclass
from clan_lib.errors import ClanError
from clan_cli.cmd import Log, RunOpts
from clan_cli.completions import (
add_dynamic_completer,
complete_backup_providers_for_machine,
complete_machines,
)
from clan_cli.errors import ClanError
from clan_cli.machines.machines import Machine
from clan_cli.ssh.host import Host

View File

@@ -1,12 +1,13 @@
import argparse
from clan_lib.errors import ClanError
from clan_cli.cmd import Log, RunOpts
from clan_cli.completions import (
add_dynamic_completer,
complete_backup_providers_for_machine,
complete_machines,
)
from clan_cli.errors import ClanError
from clan_cli.machines.machines import Machine
from clan_cli.ssh.host import Host

View File

@@ -5,12 +5,12 @@ from dataclasses import dataclass
from pathlib import Path
from clan_lib.api import API
from clan_lib.errors import ClanError
from clan_lib.flake.flake import Flake
from clan_lib.nix_models.inventory import Inventory
from clan_lib.persist.inventory_store import InventoryStore
from clan_cli.cmd import CmdOut, RunOpts, run
from clan_cli.errors import ClanError
from clan_cli.nix import nix_command, nix_metadata, nix_shell
from clan_cli.templates import (
InputPrio,

View File

@@ -3,11 +3,11 @@ from dataclasses import dataclass
from pathlib import Path
from typing import Any
from clan_lib.errors import ClanError
from clan_lib.flake.flake import Flake
from clan_cli.cmd import run
from clan_cli.dirs import machine_gcroot
from clan_cli.errors import ClanError
from clan_cli.machines.list import list_machines
from clan_cli.machines.machines import Machine
from clan_cli.nix import (

View File

@@ -5,11 +5,11 @@ from pathlib import Path
from urllib.parse import urlparse
from clan_lib.api import API
from clan_lib.errors import ClanCmdError, ClanError
from clan_lib.flake.flake import Flake
from clan_lib.nix_models.inventory import Meta
from clan_cli.cmd import run
from clan_cli.errors import ClanCmdError, ClanError
from clan_cli.nix import nix_eval
log = logging.getLogger(__name__)

View File

@@ -18,10 +18,11 @@ from enum import Enum
from pathlib import Path
from typing import IO, Any
from clan_lib.errors import ClanCmdError, ClanError, CmdOut, indent_command
from clan_cli.async_run import get_async_ctx, is_async_cancelled
from clan_cli.colors import Color
from clan_cli.custom_logger import print_trace
from clan_cli.errors import ClanCmdError, ClanError, CmdOut, indent_command
cmdlog = logging.getLogger(__name__)

View File

@@ -6,7 +6,7 @@ from enum import Enum
from pathlib import Path
from typing import TYPE_CHECKING
from .errors import ClanError
from clan_lib.errors import ClanError
if TYPE_CHECKING:
from clan_lib.flake.flake import Flake

View File

@@ -1,201 +0,0 @@
import contextlib
import json
import os
import shlex
import shutil
from dataclasses import dataclass
from math import floor
from pathlib import Path
from typing import cast
def get_term_filler(name: str) -> tuple[int, int]:
width, _ = shutil.get_terminal_size()
filler = floor((width - len(name)) / 2)
return (filler - 1, width)
def text_heading(heading: str) -> str:
filler, total = get_term_filler(heading)
msg = f"{'=' * filler} {heading} {'=' * filler}"
if len(msg) < total:
msg += "="
return msg
def optional_text(heading: str, text: str | None) -> str:
if text is None or text.strip() == "":
return ""
with contextlib.suppress(json.JSONDecodeError):
text = json.dumps(json.loads(text), indent=4)
return f"{text_heading(heading)}\n{text}"
@dataclass
class DictDiff:
added: dict[str, str]
removed: dict[str, str]
changed: dict[str, dict[str, str]]
def diff_dicts(dict1: dict[str, str], dict2: dict[str, str]) -> DictDiff:
"""
Compare two dictionaries and report additions, deletions, and changes.
:param dict1: The first dictionary (baseline).
:param dict2: The second dictionary (to compare).
:return: A dictionary with keys 'added', 'removed', and 'changed', each containing
the respective differences. 'changed' is a nested dictionary with keys 'old' and 'new'.
"""
added = {k: dict2[k] for k in dict2 if k not in dict1}
removed = {k: dict1[k] for k in dict1 if k not in dict2}
changed = {
k: {"old": dict1[k], "new": dict2[k]}
for k in dict1
if k in dict2 and dict1[k] != dict2[k]
}
return DictDiff(added=added, removed=removed, changed=changed)
def indent_command(command_list: list[str]) -> str:
formatted_command = []
i = 0
while i < len(command_list):
arg = command_list[i]
formatted_command.append(shlex.quote(arg))
if i < len(command_list) - 1:
# Check if the current argument is an option
if arg.startswith("-"):
# Indent after the next argument
formatted_command.append(" ")
i += 1
formatted_command.append(shlex.quote(command_list[i]))
if i < len(command_list) - 1:
# Add line continuation only if it's not the last argument
formatted_command.append(" \\\n ")
i += 1
# Join the list into a single string
final_command = "".join(formatted_command)
# Remove the trailing continuation if it exists
if final_command.endswith(" \\ \n "):
final_command = final_command.rsplit(" \\ \n ", 1)[0]
return final_command
DEBUG_COMMANDS = os.environ.get("CLAN_DEBUG_COMMANDS", False)
@dataclass
class CmdOut:
stdout: str
stderr: str
env: dict[str, str] | None
cwd: Path
command_list: list[str]
returncode: int
msg: str | None
@property
def command(self) -> str:
return indent_command(self.command_list)
def __str__(self) -> str:
# Set a common indentation level, assuming a reasonable spacing
label_width = max(len("Return Code"), len("Work Dir"), len("Error Msg"))
error_msg = [
f"""
{optional_text("Command", self.command)}
{optional_text("Stdout", self.stdout)}
{optional_text("Stderr", self.stderr)}
{"Return Code:":<{label_width}} {self.returncode}
"""
]
if self.msg:
error_msg += [f"{'Error Msg:':<{label_width}} {self.msg.capitalize()}"]
if DEBUG_COMMANDS:
diffed_dict = (
diff_dicts(cast(dict[str, str], os.environ), self.env)
if self.env
else None
)
diffed_dict_str = (
json.dumps(diffed_dict.__dict__, indent=4) if diffed_dict else None
)
error_msg += [
f"""
{optional_text("Environment", diffed_dict_str)}
{text_heading(heading="Metadata")}
{"Work Dir:":<{label_width}} '{self.cwd}'
"""
]
return "\n".join(error_msg)
class ClanError(Exception):
"""Base class for exceptions in this module."""
description: str | None
location: str
def __init__(
self,
msg: str | None = None,
*,
description: str | None = None,
location: str | None = None,
) -> None:
self.description = description
self.location = location or "Unknown location"
self.msg = msg or ""
exception_msg = ""
if location:
exception_msg += f"{location}: \n"
exception_msg += self.msg
if self.description:
exception_msg += f" - {self.description}"
super().__init__(exception_msg)
class ClanHttpError(ClanError):
status_code: int
msg: str
def __init__(self, status_code: int, msg: str) -> None:
self.status_code = status_code
self.msg = msg
super().__init__(msg)
class ClanCmdError(ClanError):
cmd: CmdOut
def __init__(self, cmd: CmdOut) -> None:
self.cmd = cmd
super().__init__()
def __str__(self) -> str:
return str(self.cmd)
def __repr__(self) -> str:
return f"ClanCmdError({self.cmd})"
class TorSocksError(ClanError):
def __init__(self, msg: str) -> None:
super().__init__(msg)
class TorConnectionError(ClanError):
def __init__(self, msg: str) -> None:
super().__init__(msg)

View File

@@ -7,13 +7,14 @@ from collections.abc import Callable
from pathlib import Path
from tempfile import TemporaryDirectory
from clan_lib.errors import ClanError
from clan_cli.cmd import RunOpts, run
from clan_cli.completions import (
add_dynamic_completer,
complete_machines,
complete_services_for_machine,
)
from clan_cli.errors import ClanError
from clan_cli.git import commit_files
from clan_cli.machines.list import list_machines
from clan_cli.machines.machines import Machine

View File

@@ -1,6 +1,7 @@
from pathlib import Path
from clan_cli.errors import ClanError
from clan_lib.errors import ClanError
from clan_cli.machines.machines import Machine
from . import FactStoreBase

View File

@@ -1,8 +1,9 @@
import logging
from pathlib import Path
from clan_lib.errors import ClanError
from clan_cli.dirs import vm_state_dir
from clan_cli.errors import ClanError
from clan_cli.machines.machines import Machine
from . import FactStoreBase

View File

@@ -4,8 +4,9 @@ from collections.abc import Generator
from contextlib import contextmanager
from pathlib import Path
from clan_lib.errors import ClanError
from clan_cli.cmd import Log, RunOpts, run
from clan_cli.errors import ClanError
from clan_cli.machines.machines import Machine
log = logging.getLogger(__name__)

View File

@@ -7,9 +7,9 @@ from tempfile import TemporaryDirectory
from typing import Any
from clan_lib.api import API
from clan_lib.errors import ClanError
from clan_cli.cmd import Log, RunOpts, cmd_with_root, run
from clan_cli.errors import ClanError
from clan_cli.facts.generate import generate_facts
from clan_cli.machines.machines import Machine
from clan_cli.nix import nix_shell

View File

@@ -4,9 +4,9 @@ import os
from pathlib import Path
from clan_lib.api import API
from clan_lib.errors import ClanError
from clan_cli.cmd import Log, RunOpts, run
from clan_cli.errors import ClanError
from clan_cli.nix import nix_build
log = logging.getLogger(__name__)

View File

@@ -1,8 +1,9 @@
import os
from pathlib import Path
from clan_lib.errors import ClanError
from .cmd import Log, RunOpts, run
from .errors import ClanError
from .locked_open import locked_open
from .nix import nix_shell

View File

@@ -16,6 +16,7 @@ from pathlib import Path
from typing import Any
from clan_lib.api import API
from clan_lib.errors import ClanError
from clan_lib.flake.flake import Flake
from clan_lib.nix_models.inventory import Inventory
from clan_lib.persist.inventory_store import WriteInfo
@@ -26,7 +27,6 @@ from clan_lib.persist.util import (
determine_writeability,
)
from clan_cli.errors import ClanError
from clan_cli.git import commit_file

View File

@@ -5,6 +5,7 @@ from dataclasses import dataclass
from pathlib import Path
from clan_lib.api import API
from clan_lib.errors import ClanError
from clan_lib.flake.flake import Flake
from clan_lib.nix_models.inventory import (
Machine as InventoryMachine,
@@ -17,7 +18,6 @@ from clan_lib.persist.util import apply_patch
from clan_cli.completions import add_dynamic_completer, complete_tags
from clan_cli.dirs import get_clan_flake_toplevel_or_env
from clan_cli.errors import ClanError
from clan_cli.git import commit_file
from clan_cli.machines.list import list_machines
from clan_cli.templates import (

View File

@@ -6,11 +6,11 @@ from enum import Enum
from pathlib import Path
from clan_lib.api import API
from clan_lib.errors import ClanCmdError, ClanError
from clan_cli.cmd import RunOpts, run
from clan_cli.completions import add_dynamic_completer, complete_machines
from clan_cli.dirs import specific_machine_dir
from clan_cli.errors import ClanCmdError, ClanError
from clan_cli.git import commit_file
from clan_cli.machines.machines import Machine
from clan_cli.nix import nix_config, nix_eval

View File

@@ -8,6 +8,7 @@ from pathlib import Path
from tempfile import TemporaryDirectory
from clan_lib.api import API
from clan_lib.errors import ClanError
from clan_cli.cmd import Log, RunOpts, run
from clan_cli.completions import (
@@ -15,7 +16,6 @@ from clan_cli.completions import (
complete_machines,
complete_target_host,
)
from clan_cli.errors import ClanError
from clan_cli.facts.generate import generate_facts
from clan_cli.machines.hardware import HardwareConfig
from clan_cli.machines.machines import Machine

View File

@@ -1,11 +1,11 @@
from clan_lib.api import API
from clan_lib.errors import ClanError
from clan_lib.nix_models.inventory import (
Machine as InventoryMachine,
)
from clan_lib.persist.inventory_store import InventoryStore
from clan_lib.persist.util import apply_patch
from clan_cli.errors import ClanError
from clan_cli.machines.machines import Machine

View File

@@ -9,10 +9,10 @@ from functools import cached_property
from pathlib import Path
from typing import TYPE_CHECKING, Any
from clan_lib.errors import ClanCmdError, ClanError
from clan_lib.flake.flake import Flake
from clan_cli.cmd import Log, RunOpts, run
from clan_cli.errors import ClanCmdError, ClanError
from clan_cli.facts import public_modules as facts_public_modules
from clan_cli.facts import secret_modules as facts_secret_modules
from clan_cli.nix import nix_config, nix_eval, nix_test_store

View File

@@ -7,12 +7,12 @@ import re
from pathlib import Path
from tempfile import TemporaryDirectory
from clan_lib.errors import ClanError
from clan_lib.flake.flake import Flake
from clan_lib.nix_models.inventory import Machine as InventoryMachine
from clan_cli.cmd import Log, RunOpts, run
from clan_cli.dirs import get_clan_flake_toplevel_or_env
from clan_cli.errors import ClanError
from clan_cli.machines.create import CreateOptions, create_machine
from clan_cli.machines.machines import Machine
from clan_cli.nix import nix_build, nix_command

View File

@@ -8,6 +8,7 @@ import sys
from contextlib import ExitStack
from clan_lib.api import API
from clan_lib.errors import ClanError
from clan_cli.async_run import AsyncContext, AsyncOpts, AsyncRuntime, is_async_cancelled
from clan_cli.cmd import Log, MsgColor, RunOpts, run
@@ -16,7 +17,6 @@ from clan_cli.completions import (
add_dynamic_completer,
complete_machines,
)
from clan_cli.errors import ClanError
from clan_cli.facts.generate import generate_facts
from clan_cli.facts.upload import upload_secrets
from clan_cli.machines.list import list_machines

View File

@@ -7,9 +7,10 @@ from functools import cache
from pathlib import Path
from typing import Any
from clan_lib.errors import ClanError
from clan_cli.cmd import run
from clan_cli.dirs import nixpkgs_flake, nixpkgs_source
from clan_cli.errors import ClanError
from clan_cli.locked_open import locked_open
log = logging.getLogger(__name__)

View File

@@ -3,7 +3,8 @@ import time
import types
from dataclasses import dataclass
from clan_cli.errors import ClanError
from clan_lib.errors import ClanError
from clan_cli.qemu.qmp import QEMUMonitorProtocol

View File

@@ -16,7 +16,7 @@ import socket
import types
from typing import Any
from clan_cli.errors import ClanError
from clan_lib.errors import ClanError
class QMPError(Exception):

View File

@@ -2,7 +2,7 @@ import shutil
from collections.abc import Callable
from pathlib import Path
from clan_cli.errors import ClanError
from clan_lib.errors import ClanError
def get_sops_folder(flake_dir: Path) -> Path:

View File

@@ -3,6 +3,8 @@ import os
from collections.abc import Callable
from pathlib import Path
from clan_lib.errors import ClanError
from clan_cli.completions import (
add_dynamic_completer,
complete_groups,
@@ -10,7 +12,6 @@ from clan_cli.completions import (
complete_secrets,
complete_users,
)
from clan_cli.errors import ClanError
from clan_cli.git import commit_files
from clan_cli.machines.types import machine_name_type, validate_hostname

View File

@@ -3,6 +3,8 @@ import json
import sys
from pathlib import Path
from clan_lib.errors import ClanError
from clan_cli.cmd import RunOpts, run
from clan_cli.completions import (
add_dynamic_completer,
@@ -10,7 +12,6 @@ from clan_cli.completions import (
complete_machines,
complete_users,
)
from clan_cli.errors import ClanError
from clan_cli.nix import nix_shell
from .secrets import encrypt_secret, sops_secrets_folder

View File

@@ -3,7 +3,8 @@ import json
import logging
import sys
from clan_cli.errors import ClanError
from clan_lib.errors import ClanError
from clan_cli.git import commit_files
from . import sops

View File

@@ -1,12 +1,13 @@
import argparse
from pathlib import Path
from clan_lib.errors import ClanError
from clan_cli.completions import (
add_dynamic_completer,
complete_machines,
complete_secrets,
)
from clan_cli.errors import ClanError
from clan_cli.git import commit_files
from clan_cli.machines.types import machine_name_type, validate_hostname

View File

@@ -9,6 +9,8 @@ from collections.abc import Callable
from pathlib import Path
from typing import IO
from clan_lib.errors import ClanError
from clan_cli.completions import (
add_dynamic_completer,
complete_groups,
@@ -16,7 +18,6 @@ from clan_cli.completions import (
complete_secrets,
complete_users,
)
from clan_cli.errors import ClanError
from clan_cli.git import commit_files
from . import sops

View File

@@ -14,11 +14,11 @@ from tempfile import NamedTemporaryFile
from typing import IO, Any
from clan_lib.api import API
from clan_lib.errors import ClanError
from clan_lib.flake.flake import Flake
from clan_cli.cmd import Log, RunOpts, run
from clan_cli.dirs import user_config_dir
from clan_cli.errors import ClanError
from clan_cli.nix import nix_shell
from .folders import sops_users_folder

View File

@@ -3,7 +3,7 @@ import re
from collections.abc import Callable
from pathlib import Path
from clan_cli.errors import ClanError
from clan_lib.errors import ClanError
from .sops import get_public_age_keys

View File

@@ -5,8 +5,9 @@ import sys
from collections.abc import Iterable
from pathlib import Path
from clan_lib.errors import ClanError
from clan_cli.completions import add_dynamic_completer, complete_secrets, complete_users
from clan_cli.errors import ClanError
from clan_cli.git import commit_files
from . import groups, secrets, sops

View File

@@ -6,13 +6,14 @@ from dataclasses import dataclass
from pathlib import Path
from typing import Any
from clan_lib.errors import ClanError
from clan_cli.async_run import AsyncRuntime
from clan_cli.cmd import run
from clan_cli.completions import (
add_dynamic_completer,
complete_machines,
)
from clan_cli.errors import ClanError
from clan_cli.machines.machines import Machine
from clan_cli.nix import nix_shell
from clan_cli.ssh.host import Host, is_ssh_reachable

View File

@@ -13,9 +13,10 @@ from shlex import quote
from tempfile import TemporaryDirectory
from typing import Any
from clan_lib.errors import ClanError
from clan_cli.cmd import CmdOut, RunOpts, run
from clan_cli.colors import AnsiColor
from clan_cli.errors import ClanError
from clan_cli.nix import nix_shell
from clan_cli.ssh.host_key import HostKeyCheck

View File

@@ -2,7 +2,7 @@
from enum import Enum
from clan_cli.errors import ClanError
from clan_lib.errors import ClanError
class HostKeyCheck(Enum):

View File

@@ -3,7 +3,8 @@ import urllib.parse
from pathlib import Path
from typing import Any
from clan_cli.errors import ClanError
from clan_lib.errors import ClanError
from clan_cli.ssh.host import Host
from clan_cli.ssh.host_key import HostKeyCheck

View File

@@ -1,7 +1,8 @@
from dataclasses import dataclass
from typing import Generic
from clan_cli.errors import CmdOut
from clan_lib.errors import CmdOut
from clan_cli.ssh import T
from clan_cli.ssh.host import Host

View File

@@ -7,9 +7,10 @@ import struct
import time
from dataclasses import dataclass
from clan_lib.errors import TorConnectionError, TorSocksError
from clan_cli.async_run import AsyncRuntime
from clan_cli.cmd import Log, RunOpts, run
from clan_cli.errors import TorConnectionError, TorSocksError
from clan_cli.nix import nix_shell
log = logging.getLogger(__name__)

View File

@@ -3,9 +3,10 @@ from pathlib import Path
from shlex import quote
from tempfile import TemporaryDirectory
from clan_lib.errors import ClanError
from clan_cli.cmd import Log, RunOpts
from clan_cli.cmd import run as run_local
from clan_cli.errors import ClanError
from clan_cli.ssh.host import Host

View File

@@ -3,6 +3,8 @@ import json
import logging
from pathlib import Path
from clan_lib.errors import ClanCmdError, ClanError
from clan_cli.cmd import RunOpts, run
from clan_cli.completions import (
add_dynamic_completer,
@@ -10,7 +12,6 @@ from clan_cli.completions import (
complete_state_services_for_machine,
)
from clan_cli.dirs import get_clan_flake_toplevel_or_env
from clan_cli.errors import ClanCmdError, ClanError
from clan_cli.machines.machines import Machine
from clan_cli.nix import nix_eval

View File

@@ -3,11 +3,11 @@ from dataclasses import dataclass, field
from pathlib import Path
from typing import Any, Literal, NewType, TypedDict, cast
from clan_lib.errors import ClanCmdError, ClanError
from clan_lib.flake.flake import Flake
from clan_cli.cmd import run
from clan_cli.dirs import clan_templates
from clan_cli.errors import ClanCmdError, ClanError
log = logging.getLogger(__name__)

View File

@@ -5,9 +5,9 @@ import sys
from dataclasses import is_dataclass
from pathlib import Path
from clan_cli.errors import ClanError
from clan_lib.api import API
from clan_lib.api.util import JSchemaTypeError, type_to_dict
from clan_lib.errors import ClanError
def should_skip(file_path: Path, excludes: list[Path]) -> bool:

View File

@@ -3,11 +3,11 @@ from pathlib import Path
from typing import Any, Literal
import pytest
from clan_cli.errors import ClanError
from clan_cli.machines import machines
# Functions to test
from clan_lib.api import dataclass_to_dict, from_dict
from clan_lib.errors import ClanError
def test_simple() -> None:

View File

@@ -4,7 +4,7 @@ from pathlib import Path
import pytest
from clan_cli import git
from clan_cli.errors import ClanError
from clan_lib.errors import ClanError
def test_commit_file(git_repo: Path) -> None:

View File

@@ -9,12 +9,12 @@ from contextlib import contextmanager
from typing import TYPE_CHECKING
import pytest
from clan_cli.errors import ClanError
from clan_cli.tests.age_keys import assert_secrets_file_recipients
from clan_cli.tests.fixtures_flakes import FlakeForTest
from clan_cli.tests.gpg_keys import GpgKey
from clan_cli.tests.helpers import cli
from clan_cli.tests.stdout import CaptureOutput
from clan_lib.errors import ClanError
if TYPE_CHECKING:
from .age_keys import KeyPair

View File

@@ -6,10 +6,10 @@ from typing import Any, NamedTuple
import pytest
from clan_cli.async_run import AsyncRuntime
from clan_cli.cmd import ClanCmdTimeoutError, Log, RunOpts
from clan_cli.errors import ClanError, CmdOut
from clan_cli.ssh.host import Host
from clan_cli.ssh.host_key import HostKeyCheck
from clan_cli.ssh.parse import parse_deployment_address
from clan_lib.errors import ClanError, CmdOut
if sys.platform == "darwin":
pytest.skip("preload doesn't work on darwin", allow_module_level=True)

View File

@@ -4,7 +4,6 @@ import shutil
from pathlib import Path
import pytest
from clan_cli.errors import ClanError
from clan_cli.machines.machines import Machine
from clan_cli.nix import nix_eval, run
from clan_cli.tests.age_keys import SopsSetup
@@ -23,6 +22,7 @@ from clan_cli.vars.list import stringify_all_vars
from clan_cli.vars.public_modules import in_repo
from clan_cli.vars.secret_modules import password_store, sops
from clan_cli.vars.set import set_var
from clan_lib.errors import ClanError
from clan_lib.flake.flake import Flake

View File

@@ -5,9 +5,9 @@ from dataclasses import dataclass
from pathlib import Path
from typing import TYPE_CHECKING
from clan_cli.errors import ClanError
from clan_cli.machines import machines
from clan_cli.ssh.host import Host
from clan_lib.errors import ClanError
if TYPE_CHECKING:
from .generate import Generator, Var

View File

@@ -2,8 +2,8 @@ import argparse
import logging
from clan_cli.completions import add_dynamic_completer, complete_machines
from clan_cli.errors import ClanError
from clan_cli.machines.machines import Machine
from clan_lib.errors import ClanError
log = logging.getLogger(__name__)

View File

@@ -2,8 +2,8 @@ import argparse
import logging
from clan_cli.completions import add_dynamic_completer, complete_machines
from clan_cli.errors import ClanError
from clan_cli.machines.machines import Machine
from clan_lib.errors import ClanError
log = logging.getLogger(__name__)

View File

@@ -15,13 +15,13 @@ from clan_cli.completions import (
complete_machines,
complete_services_for_machine,
)
from clan_cli.errors import ClanError
from clan_cli.git import commit_files
from clan_cli.machines.list import list_machines
from clan_cli.nix import nix_config, nix_shell, nix_test_store
from clan_cli.vars._types import StoreBase
from clan_cli.vars.migration import check_can_migrate, migrate_files
from clan_lib.api import API
from clan_lib.errors import ClanError
from clan_lib.flake.flake import Flake
from .check import check_vars

View File

@@ -3,8 +3,8 @@ import logging
import sys
from clan_cli.completions import add_dynamic_completer, complete_machines
from clan_cli.errors import ClanError
from clan_lib.api import API
from clan_lib.errors import ClanError
from clan_lib.flake.flake import Flake
from .generate import Var

View File

@@ -4,7 +4,7 @@ from collections.abc import Iterable
from graphlib import TopologicalSorter
from typing import TYPE_CHECKING
from clan_cli.errors import ClanError
from clan_lib.errors import ClanError
if TYPE_CHECKING:
from .generate import Generator

View File

@@ -3,11 +3,11 @@ import logging
import os
from pathlib import Path
from clan_cli.errors import ClanError
from clan_cli.secrets.key import generate_key
from clan_cli.secrets.sops import maybe_get_admin_public_key
from clan_cli.secrets.users import add_user
from clan_lib.api import API
from clan_lib.errors import ClanError
log = logging.getLogger(__name__)

View File

@@ -2,9 +2,9 @@ import argparse
import logging
from clan_cli.completions import add_dynamic_completer, complete_machines
from clan_cli.errors import ClanError
from clan_cli.machines.machines import Machine
from clan_lib.api import API
from clan_lib.errors import ClanError
from clan_lib.flake.flake import Flake
from ._types import GeneratorUpdate

View File

@@ -2,8 +2,8 @@ import logging
from pathlib import Path
from typing import TYPE_CHECKING
from clan_cli.errors import ClanError
from clan_cli.git import commit_files
from clan_lib.errors import ClanError
log = logging.getLogger(__name__)

View File

@@ -7,7 +7,7 @@ from dataclasses import dataclass
from getpass import getpass
from typing import Any
from clan_cli.errors import ClanError
from clan_lib.errors import ClanError
log = logging.getLogger(__name__)

View File

@@ -2,11 +2,11 @@ import shutil
from collections.abc import Iterable
from pathlib import Path
from clan_cli.errors import ClanError
from clan_cli.machines.machines import Machine
from clan_cli.ssh.host import Host
from clan_cli.vars._types import StoreBase
from clan_cli.vars.generate import Generator, Var
from clan_lib.errors import ClanError
class FactStore(StoreBase):

View File

@@ -4,11 +4,11 @@ from collections.abc import Iterable
from pathlib import Path
from clan_cli.dirs import vm_state_dir
from clan_cli.errors import ClanError
from clan_cli.machines.machines import Machine
from clan_cli.ssh.host import Host
from clan_cli.vars._types import StoreBase
from clan_cli.vars.generate import Generator, Var
from clan_lib.errors import ClanError
log = logging.getLogger(__name__)

View File

@@ -5,7 +5,6 @@ from pathlib import Path
from tempfile import TemporaryDirectory
from typing import override
from clan_cli.errors import ClanError
from clan_cli.machines.machines import Machine
from clan_cli.secrets import sops
from clan_cli.secrets.folders import (
@@ -28,6 +27,7 @@ from clan_cli.ssh.upload import upload
from clan_cli.vars._types import StoreBase
from clan_cli.vars.generate import Generator
from clan_cli.vars.var import Var
from clan_lib.errors import ClanError
@dataclass

View File

@@ -4,7 +4,8 @@ from contextlib import contextmanager
from dataclasses import dataclass
from pathlib import Path
from clan_cli.errors import ClanError
from clan_lib.errors import ClanError
from clan_cli.qemu.qmp import QEMUMonitorProtocol
from .inspect import VmConfig
@@ -74,7 +75,7 @@ def graphics_options(vm: VmConfig) -> GraphicOptions:
"-device", "usb-ccid",
"-chardev", "spicevmc,id=ccid,name=smartcard",
], None)
# fmt: on
# fmt: on
@dataclass
@@ -140,19 +141,31 @@ def qemu_command(
"-device", "virtserialport,chardev=qga0,name=org.qemu.guest_agent.0",
] # fmt: on
if interactive:
command.extend([
"-serial", "null",
"-chardev", "stdio,mux=on,id=char0,signal=off",
"-mon", "chardev=char0,mode=readline",
"-device", "virtconsole,chardev=char0,nr=0",
])
command.extend(
[
"-serial",
"null",
"-chardev",
"stdio,mux=on,id=char0,signal=off",
"-mon",
"chardev=char0,mode=readline",
"-device",
"virtconsole,chardev=char0,nr=0",
]
)
else:
command.extend([
"-serial", "null",
"-chardev", "file,id=char0,path=/dev/stdout",
"-device", "virtconsole,chardev=char0,nr=0",
"-monitor", "none",
])
command.extend(
[
"-serial",
"null",
"-chardev",
"file,id=char0,path=/dev/stdout",
"-device",
"virtconsole,chardev=char0,nr=0",
"-monitor",
"none",
]
)
vsock_cid = None
if vm.graphics:

View File

@@ -12,10 +12,11 @@ from dataclasses import dataclass
from pathlib import Path
from tempfile import TemporaryDirectory
from clan_lib.errors import ClanCmdError, ClanError
from clan_cli.cmd import CmdOut, Log, RunOpts, handle_io, run
from clan_cli.completions import add_dynamic_completer, complete_machines
from clan_cli.dirs import module_root, user_cache_dir, vm_state_dir
from clan_cli.errors import ClanCmdError, ClanError
from clan_cli.facts.generate import generate_facts
from clan_cli.machines.machines import Machine
from clan_cli.nix import nix_shell

View File

@@ -5,7 +5,8 @@ import time
from collections.abc import Iterator
from pathlib import Path
from clan_cli.errors import ClanError
from clan_lib.errors import ClanError
from clan_cli.nix import nix_shell

View File

@@ -5,7 +5,8 @@ import subprocess
import time
from collections.abc import Iterator
from clan_cli.errors import ClanError
from clan_lib.errors import ClanError
from clan_cli.nix import nix_shell
VMADDR_CID_HYPERVISOR = 2