Merge pull request 'refactor: move clan_cli.error to clan_lib.error' (#3677) from hsjobeki/clan-core:chores-1 into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3677
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
@@ -207,7 +207,8 @@ def complete_secrets(
|
||||
"""
|
||||
Provides completion functionality for clan secrets
|
||||
"""
|
||||
from . import Flake
|
||||
from clan_lib.flake.flake import Flake
|
||||
|
||||
from .secrets.secrets import list_secrets
|
||||
|
||||
flake = clan_dir_result if (clan_dir_result := clan_dir(None)) is not None else "."
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from enum import Enum
|
||||
|
||||
from clan_cli.errors import ClanError
|
||||
from clan_lib.errors import ClanError
|
||||
|
||||
|
||||
class HostKeyCheck(Enum):
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user