diff --git a/pkgs/clan-cli/clan_lib/api/network.py b/pkgs/clan-cli/clan_lib/api/network.py index c16f9b39d..13c21d8be 100644 --- a/pkgs/clan-cli/clan_lib/api/network.py +++ b/pkgs/clan-cli/clan_lib/api/network.py @@ -6,7 +6,7 @@ from typing import Literal from clan_lib.api import API from clan_lib.cmd import RunOpts from clan_lib.errors import ClanError -from clan_lib.machines.machines import Machine +from clan_lib.ssh.remote import Remote log = logging.getLogger(__name__) @@ -19,19 +19,12 @@ class ConnectionOptions: @API.register def check_machine_online( - machine: Machine, opts: ConnectionOptions | None = None + remote: Remote, opts: ConnectionOptions | None = None ) -> Literal["Online", "Offline"]: - hostname = machine.target_host().target - - if not hostname: - msg = f"Machine {machine.name} does not specify a targetHost" - raise ClanError(msg) - timeout = opts.timeout if opts and opts.timeout else 2 for _ in range(opts.retries if opts and opts.retries else 10): - host = machine.target_host() - with host.ssh_control_master() as ssh: + with remote.ssh_control_master() as ssh: res = ssh.run( ["true"], RunOpts(timeout=timeout, check=False, needs_user_terminal=True), @@ -39,6 +32,10 @@ def check_machine_online( if res.returncode == 0: return "Online" + + if "Host key verification failed." in res.stderr: + raise ClanError(res.stderr.strip()) + time.sleep(timeout) return "Offline" diff --git a/pkgs/clan-cli/clan_lib/machines/machines.py b/pkgs/clan-cli/clan_lib/machines/machines.py index b24defe22..7933cfd0c 100644 --- a/pkgs/clan-cli/clan_lib/machines/machines.py +++ b/pkgs/clan-cli/clan_lib/machines/machines.py @@ -167,7 +167,20 @@ class Machine: msg, description="See https://docs.clan.lol/guides/getting-started/deploy/#setting-the-target-host for more information.", ) - return remote.data + data = remote.data + return Remote( + address=data.address, + user=data.user, + command_prefix=data.command_prefix, + port=data.port, + private_key=self.private_key, + password=data.password, + forward_agent=data.forward_agent, + host_key_check=self.host_key_check, + verbose_ssh=data.verbose_ssh, + ssh_options=data.ssh_options, + tor_socks=data.tor_socks, + ) def build_host(self) -> Remote | None: """ @@ -183,9 +196,25 @@ class Machine: private_key=self.private_key, ) - remote = get_build_host(self) + remote = get_build_host(self.name, self.flake) - return remote.data if remote else None + if remote: + data = remote.data + return Remote( + address=data.address, + user=data.user, + command_prefix=data.command_prefix, + port=data.port, + private_key=self.private_key, + password=data.password, + forward_agent=data.forward_agent, + host_key_check=self.host_key_check, + verbose_ssh=data.verbose_ssh, + ssh_options=data.ssh_options, + tor_socks=data.tor_socks, + ) + + return None def nix( self, @@ -268,7 +297,7 @@ def get_target_host(name: str, flake: Flake) -> RemoteSource | None: machine = Machine(name=name, flake=flake) inv_machine = machine.get_inv_machine() - source = "inventory" + source: Literal["inventory", "nix_machine"] = "inventory" target_host_str = inv_machine.get("deploy", {}).get("targetHost") if target_host_str is None: @@ -300,7 +329,7 @@ def get_build_host(name: str, flake: Flake) -> RemoteSource | None: machine = Machine(name=name, flake=flake) inv_machine = machine.get_inv_machine() - source = "inventory" + source: Literal["inventory", "nix_machine"] = "inventory" target_host_str = inv_machine.get("deploy", {}).get("buildHost") if target_host_str is None: diff --git a/pkgs/clan-cli/clan_lib/tests/test_create.py b/pkgs/clan-cli/clan_lib/tests/test_create.py index 5cf754b86..b46bbb879 100644 --- a/pkgs/clan-cli/clan_lib/tests/test_create.py +++ b/pkgs/clan-cli/clan_lib/tests/test_create.py @@ -203,7 +203,7 @@ def test_clan_create_api( # Invalidate cache because of new machine creation clan_dir_flake.invalidate_cache() - result = check_machine_online(machine) + result = check_machine_online(machine.target_host()) assert result == "Online", f"Machine {machine.name} is not online" ssh_keys = [