From 164e37e41d48bb92a994eb3778d36d9285a6a465 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 20 Jan 2026 12:26:40 +0100 Subject: [PATCH] remote: Bring back docker exit status mapping (#47206) cc https://github.com/zed-industries/zed/pull/45584, was removed in #47200 fully due to breaking ssh Also makes ZED_BUILD_REMOTE_SERVER a bit easier to use Release Notes: - N/A *or* Added/Fixed/Improved ... --- crates/remote/src/transport.rs | 8 ++++- crates/remote/src/transport/docker.rs | 52 +++++++++++++++++---------- crates/remote/src/transport/ssh.rs | 33 +++++++++-------- crates/remote/src/transport/wsl.rs | 20 +++++++---- 4 files changed, 72 insertions(+), 41 deletions(-) diff --git a/crates/remote/src/transport.rs b/crates/remote/src/transport.rs index 6eafefbbf281f388fe2d14ea68efaa9d9e038379..7dfac0a5bb1675954df68016509a6ed4594ae3a2 100644 --- a/crates/remote/src/transport.rs +++ b/crates/remote/src/transport.rs @@ -178,6 +178,7 @@ fn handle_rpc_messages_over_child_process_stdio( async fn build_remote_server_from_source( platform: &crate::RemotePlatform, delegate: &dyn crate::RemoteClientDelegate, + binary_exists_on_server: bool, cx: &mut AsyncApp, ) -> Result> { use smol::process::{Command, Stdio}; @@ -202,8 +203,13 @@ async fn build_remote_server_from_source( let build_remote_server = std::env::var("ZED_BUILD_REMOTE_SERVER").unwrap_or("nocompress".into()); - if let "false" | "no" | "off" | "0" = &*build_remote_server { + if let "never" = &*build_remote_server { return Ok(None); + } else if let "false" | "no" | "off" | "0" = &*build_remote_server { + if binary_exists_on_server { + return Ok(None); + } + log::warn!("ZED_BUILD_REMOTE_SERVER is disabled, but no server binary exists on the server") } async fn run_cmd(command: &mut Command) -> Result<()> { diff --git a/crates/remote/src/transport/docker.rs b/crates/remote/src/transport/docker.rs index 1610c264e9ffdb337c31920d49be02abfe4bcd6a..d2c7dc74bff20abf875a413c3ad4e81b955ab119 100644 --- a/crates/remote/src/transport/docker.rs +++ b/crates/remote/src/transport/docker.rs @@ -165,9 +165,23 @@ impl DockerExecConnection { let dst_path = paths::remote_server_dir_relative().join(RelPath::unix(&binary_name).unwrap()); + let binary_exists_on_server = self + .run_docker_exec( + &dst_path.display(self.path_style()), + Some(&remote_dir_for_server), + &Default::default(), + &["version"], + ) + .await + .is_ok(); #[cfg(any(debug_assertions, feature = "build-remote-server-binary"))] - if let Some(remote_server_path) = - super::build_remote_server_from_source(&remote_platform, delegate.as_ref(), cx).await? + if let Some(remote_server_path) = super::build_remote_server_from_source( + &remote_platform, + delegate.as_ref(), + binary_exists_on_server, + cx, + ) + .await? { let tmp_path = paths::remote_server_dir_relative().join( RelPath::unix(&format!( @@ -190,16 +204,7 @@ impl DockerExecConnection { return Ok(dst_path); } - if self - .run_docker_exec( - &dst_path.display(self.path_style()), - Some(&remote_dir_for_server), - &Default::default(), - &["version"], - ) - .await - .is_ok() - { + if binary_exists_on_server { return Ok(dst_path); } @@ -611,13 +616,22 @@ impl RemoteConnection for DockerExecConnection { let mut proxy_process = self.proxy_process.lock(); *proxy_process = Some(child.id()); - super::handle_rpc_messages_over_child_process_stdio( - child, - incoming_tx, - outgoing_rx, - connection_activity_tx, - cx, - ) + cx.spawn(async move |cx| { + super::handle_rpc_messages_over_child_process_stdio( + child, + incoming_tx, + outgoing_rx, + connection_activity_tx, + cx, + ) + .await + .and_then(|status| { + if status != 0 { + anyhow::bail!("Remote server exited with status {status}"); + } + Ok(0) + }) + }) } fn upload_directory( diff --git a/crates/remote/src/transport/ssh.rs b/crates/remote/src/transport/ssh.rs index 4504019cccaeef6a3a804c50b5390620c42efe8d..4332945b11d5036817845623eeeabcd3e714485d 100644 --- a/crates/remote/src/transport/ssh.rs +++ b/crates/remote/src/transport/ssh.rs @@ -628,10 +628,25 @@ impl SshRemoteConnection { let dst_path = paths::remote_server_dir_relative().join(RelPath::unix(&binary_name).unwrap()); + let binary_exists_on_server = self + .socket + .run_command( + self.ssh_shell_kind, + &dst_path.display(self.path_style()), + &["version"], + true, + ) + .await + .is_ok(); + #[cfg(any(debug_assertions, feature = "build-remote-server-binary"))] - if let Some(remote_server_path) = - super::build_remote_server_from_source(&self.ssh_platform, delegate.as_ref(), cx) - .await? + if let Some(remote_server_path) = super::build_remote_server_from_source( + &self.ssh_platform, + delegate.as_ref(), + binary_exists_on_server, + cx, + ) + .await? { let tmp_path = paths::remote_server_dir_relative().join( RelPath::unix(&format!( @@ -648,17 +663,7 @@ impl SshRemoteConnection { return Ok(dst_path); } - if self - .socket - .run_command( - self.ssh_shell_kind, - &dst_path.display(self.path_style()), - &["version"], - true, - ) - .await - .is_ok() - { + if binary_exists_on_server { return Ok(dst_path); } diff --git a/crates/remote/src/transport/wsl.rs b/crates/remote/src/transport/wsl.rs index e32aba068ad70049b2d7abc955e0ae34db7da242..f3ff273f2045ba01b9b41b8ba966e17dd77ed055 100644 --- a/crates/remote/src/transport/wsl.rs +++ b/crates/remote/src/transport/wsl.rs @@ -186,9 +186,19 @@ impl WslRemoteConnection { .map_err(|e| anyhow!("Failed to create directory: {}", e))?; } + let binary_exists_on_server = self + .run_wsl_command(&dst_path.display(PathStyle::Posix), &["version"]) + .await + .is_ok(); + #[cfg(any(debug_assertions, feature = "build-remote-server-binary"))] - if let Some(remote_server_path) = - super::build_remote_server_from_source(&self.platform, delegate.as_ref(), cx).await? + if let Some(remote_server_path) = super::build_remote_server_from_source( + &self.platform, + delegate.as_ref(), + binary_exists_on_server, + cx, + ) + .await? { let tmp_path = paths::remote_wsl_server_dir_relative().join( &RelPath::unix(&format!( @@ -205,11 +215,7 @@ impl WslRemoteConnection { return Ok(dst_path); } - if self - .run_wsl_command(&dst_path.display(PathStyle::Posix), &["version"]) - .await - .is_ok() - { + if binary_exists_on_server { return Ok(dst_path); }