Fix uploading ssh binaries when ssh cds (#22744)

Conrad Irwin created

The code we have assumes that when you run commands over ssh they run
in your home directory. This was not true in some cases, and broke SSH
remoting if you had `upload_binary_over_ssh` set.

To reproduce this use Coder and set the `dir` parameter.

Release Notes:

- Fixed SSH remoting in the case that ssh defaults to a non-$HOME
directory.

Change summary

crates/remote/src/ssh_session.rs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

Detailed changes

crates/remote/src/ssh_session.rs 🔗

@@ -253,7 +253,9 @@ impl SshSocket {
     // :WARNING: ssh unquotes arguments when executing on the remote :WARNING:
     // e.g. $ ssh host sh -c 'ls -l' is equivalent to $ ssh host sh -c ls -l
     // and passes -l as an argument to sh, not to ls.
-    // You need to do it like this: $ ssh host "sh -c 'ls -l /tmp'"
+    // Furthermore, some setups (e.g. Coder) will change directory when SSH'ing
+    // into a machine. You must use `cd` to get back to $HOME.
+    // You need to do it like this: $ ssh host "cd; sh -c 'ls -l /tmp'"
     fn ssh_command(&self, program: &str, args: &[&str]) -> process::Command {
         let mut command = util::command::new_smol_command("ssh");
         let to_run = iter::once(&program)
@@ -267,6 +269,7 @@ impl SshSocket {
                 shlex::try_quote(token).unwrap()
             })
             .join(" ");
+        let to_run = format!("cd; {to_run}");
         log::debug!("ssh {} {:?}", self.connection_options.ssh_url(), to_run);
         self.ssh_options(&mut command)
             .arg(self.connection_options.ssh_url())