diff --git a/pkgs/clan-cli/clan_cli/machines/machines.py b/pkgs/clan-cli/clan_cli/machines/machines.py index 6118beb5a..e681d07d6 100644 --- a/pkgs/clan-cli/clan_cli/machines/machines.py +++ b/pkgs/clan-cli/clan_cli/machines/machines.py @@ -149,13 +149,14 @@ class Machine: @contextmanager def target_host(self) -> Iterator[Host]: - yield parse_deployment_address( + with parse_deployment_address( self.name, self.target_host_address, self.host_key_check, private_key=self.private_key, meta={"machine": self}, - ) + ) as target_host: + yield target_host @contextmanager def build_host(self) -> Iterator[Host | None]: @@ -168,14 +169,15 @@ class Machine: yield None return # enable ssh agent forwarding to allow the build host to access the target host - yield parse_deployment_address( + with parse_deployment_address( self.name, build_host, self.host_key_check, forward_agent=True, private_key=self.private_key, meta={"machine": self}, - ) + ) as build_host: + yield build_host @cached_property def deploy_as_root(self) -> bool: diff --git a/pkgs/clan-cli/clan_cli/machines/update.py b/pkgs/clan-cli/clan_cli/machines/update.py index abba56b43..609b6e367 100644 --- a/pkgs/clan-cli/clan_cli/machines/update.py +++ b/pkgs/clan-cli/clan_cli/machines/update.py @@ -179,11 +179,11 @@ def deploy_machine(machine: Machine) -> None: switch_cmd = [f"{machine._class_}-rebuild", "switch", *nix_options] test_cmd = [f"{machine._class_}-rebuild", "test", *nix_options] - env = host.nix_ssh_env(None) + remote_env = host.nix_ssh_env(None, local_ssh=False) ret = host.run( switch_cmd, RunOpts(check=False, msg_color=MsgColor(stderr=AnsiColor.DEFAULT)), - extra_env=env, + extra_env=remote_env, become_root=become_root, ) @@ -209,7 +209,7 @@ def deploy_machine(machine: Machine) -> None: msg_color=MsgColor(stderr=AnsiColor.DEFAULT), needs_user_terminal=True, ), - extra_env=env, + extra_env=remote_env, become_root=become_root, ) diff --git a/pkgs/clan-cli/clan_cli/ssh/host.py b/pkgs/clan-cli/clan_cli/ssh/host.py index 0b8d617e9..108b0025a 100644 --- a/pkgs/clan-cli/clan_cli/ssh/host.py +++ b/pkgs/clan-cli/clan_cli/ssh/host.py @@ -42,14 +42,9 @@ class Host: _temp_dir: TemporaryDirectory | None = None - def setup_control_master(self, control_path: Path) -> None: - self.ssh_options["ControlMaster"] = "auto" - self.ssh_options["ControlPath"] = str(control_path / "clan-%h-%p-%r") - self.ssh_options["ControlPersist"] = "30m" - - def __enter__(self) -> None: + def __enter__(self) -> "Host": self._temp_dir = TemporaryDirectory(prefix="clan-ssh-") - self.setup_control_master(Path(self._temp_dir.name)) + return self def __exit__( self, @@ -187,15 +182,17 @@ class Host: # Run the ssh command return run(ssh_cmd, opts) - def nix_ssh_env(self, env: dict[str, str] | None) -> dict[str, str]: + def nix_ssh_env( + self, env: dict[str, str] | None, local_ssh: bool = True + ) -> dict[str, str]: if env is None: env = {} - env["NIX_SSHOPTS"] = " ".join(self.ssh_cmd_opts) + env["NIX_SSHOPTS"] = " ".join(self.ssh_cmd_opts(local_ssh=local_ssh)) return env - @property def ssh_cmd_opts( self, + local_ssh: bool = True, ) -> list[str]: ssh_opts = ["-A"] if self.forward_agent else [] if self.port: @@ -209,6 +206,16 @@ class Host: if self.private_key: ssh_opts.extend(["-i", str(self.private_key)]) + if local_ssh and self._temp_dir: + ssh_opts.extend(["-o", "ControlPersist=30m"]) + ssh_opts.extend( + [ + "-o", + f"ControlPath={Path(self._temp_dir.name) / 'clan-%h-%p-%r'}", + ] + ) + ssh_opts.extend(["-o", "ControlMaster=auto"]) + return ssh_opts def ssh_cmd( @@ -226,7 +233,7 @@ class Host: self.password, ] - ssh_opts = self.ssh_cmd_opts + ssh_opts = self.ssh_cmd_opts() if verbose_ssh or self.verbose_ssh: ssh_opts.extend(["-v"]) if tty: