Merge pull request 'clan-cli: use automatic networking for vars upload and machines update' (#4792) from networking_4 into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/4792
This commit is contained in:
@@ -442,17 +442,31 @@ Examples:
|
||||
parser_network = subparsers.add_parser(
|
||||
"network",
|
||||
aliases=["net"],
|
||||
# TODO: Add help="Manage networks" when network code is ready
|
||||
# help="Manage networks",
|
||||
help="Manage networks",
|
||||
description="Manage networks",
|
||||
epilog=(
|
||||
"""
|
||||
show information about configured networks
|
||||
Manage and monitor network connections for machines.
|
||||
|
||||
Clan supports multiple network technologies (direct SSH, Tor, etc.) that can be
|
||||
configured with different priorities. When connecting to a machine, Clan will:
|
||||
1. Check for targetHost in inventory
|
||||
2. Try configured networks by priority
|
||||
3. Fall back to targetHost from machine config
|
||||
|
||||
Commands like 'ssh' and 'machines update' automatically use the best
|
||||
available network connection unless overridden with --target-host.
|
||||
|
||||
Examples:
|
||||
|
||||
$ clan network list
|
||||
Will list networks
|
||||
List all configured networks and their peers
|
||||
|
||||
$ clan network ping machine1
|
||||
Check connectivity to machine1 across all networks
|
||||
|
||||
$ clan network overview
|
||||
Show complete network status and connectivity
|
||||
"""
|
||||
),
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
@@ -495,7 +509,7 @@ For more detailed information, visit: {help_hyperlink("getting-started", "https:
|
||||
register_common_flags(parser)
|
||||
|
||||
if argcomplete:
|
||||
argcomplete.autocomplete(parser, exclude=["morph", "network", "net"])
|
||||
argcomplete.autocomplete(parser, exclude=["morph"])
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ from clan_lib.machines.list import instantiate_inventory_to_machines
|
||||
from clan_lib.machines.machines import Machine
|
||||
from clan_lib.machines.suggestions import validate_machine_names
|
||||
from clan_lib.machines.update import run_machine_update
|
||||
from clan_lib.network.network import get_best_remote
|
||||
from clan_lib.nix import nix_config
|
||||
from clan_lib.ssh.host import Host
|
||||
from clan_lib.ssh.host_key import HostKeyCheck
|
||||
@@ -27,6 +28,42 @@ from clan_cli.completions import (
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def run_update_with_network(
|
||||
machine: Machine,
|
||||
build_host: Remote | LocalHost | None,
|
||||
upload_inputs: bool,
|
||||
host_key_check: HostKeyCheck,
|
||||
target_host_override: str | None = None,
|
||||
) -> None:
|
||||
"""Run machine update with proper network context handling.
|
||||
|
||||
If target_host_override is provided, use it directly.
|
||||
Otherwise, use get_best_remote to establish network connection.
|
||||
"""
|
||||
if target_host_override:
|
||||
# Direct connection without network context
|
||||
target_host = Remote.from_ssh_uri(
|
||||
machine_name=machine.name,
|
||||
address=target_host_override,
|
||||
).override(host_key_check=host_key_check)
|
||||
run_machine_update(
|
||||
machine=machine,
|
||||
target_host=target_host,
|
||||
build_host=build_host,
|
||||
upload_inputs=upload_inputs,
|
||||
)
|
||||
else:
|
||||
# Use network context
|
||||
with get_best_remote(machine) as remote:
|
||||
target_host = remote.override(host_key_check=host_key_check)
|
||||
run_machine_update(
|
||||
machine=machine,
|
||||
target_host=target_host,
|
||||
build_host=build_host,
|
||||
upload_inputs=upload_inputs,
|
||||
)
|
||||
|
||||
|
||||
def requires_explicit_update(m: Machine) -> bool:
|
||||
try:
|
||||
if m.select("config.clan.deployment.requireExplicitUpdate"):
|
||||
@@ -144,27 +181,19 @@ def update_command(args: argparse.Namespace) -> None:
|
||||
).override(host_key_check=host_key_check)
|
||||
else:
|
||||
build_host = machine.build_host()
|
||||
# Figure out the target host
|
||||
if args.target_host:
|
||||
target_host = Remote.from_ssh_uri(
|
||||
machine_name=machine.name,
|
||||
address=args.target_host,
|
||||
).override(host_key_check=host_key_check)
|
||||
else:
|
||||
target_host = machine.target_host().override(
|
||||
host_key_check=host_key_check
|
||||
)
|
||||
# run the update
|
||||
|
||||
# Schedule the update with network handling
|
||||
runtime.async_run(
|
||||
AsyncOpts(
|
||||
tid=machine.name,
|
||||
async_ctx=AsyncContext(prefix=machine.name),
|
||||
),
|
||||
run_machine_update,
|
||||
run_update_with_network,
|
||||
machine=machine,
|
||||
target_host=target_host,
|
||||
build_host=build_host,
|
||||
upload_inputs=args.upload_inputs,
|
||||
host_key_check=host_key_check,
|
||||
target_host_override=args.target_host,
|
||||
)
|
||||
runtime.join_all()
|
||||
runtime.check_all()
|
||||
|
||||
@@ -5,6 +5,7 @@ from pathlib import Path
|
||||
from clan_cli.completions import add_dynamic_completer, complete_machines
|
||||
from clan_lib.flake import require_flake
|
||||
from clan_lib.machines.machines import Machine
|
||||
from clan_lib.network.network import get_best_remote
|
||||
from clan_lib.ssh.host import Host
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -32,7 +33,12 @@ def upload_command(args: argparse.Namespace) -> None:
|
||||
populate_secret_vars(machine, directory)
|
||||
return
|
||||
|
||||
with machine.target_host().host_connection() as host, host.become_root() as host:
|
||||
# Use get_best_remote to handle networking
|
||||
with (
|
||||
get_best_remote(machine) as remote,
|
||||
remote.host_connection() as host,
|
||||
host.become_root() as host,
|
||||
):
|
||||
upload_secret_vars(machine, host)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user