@@ -62,16 +62,17 @@ def cli(self):
6262 help = "Run SSH command with arguments" ,
6363 )
6464 @click .option ("--direct" , is_flag = True , help = "Use direct TCP address" )
65+ @click .option ("-u" , "--user" , help = "Username to use for SSH connection" )
6566 @click .argument ("args" , nargs = - 1 )
66- def ssh (direct , args ):
67+ def ssh (direct , user , args ):
6768 options = SSHCommandRunOptions (
6869 direct = direct ,
6970 # For the CLI, we never capture output so that interactive shells
7071 # and long-running commands stream their output directly.
7172 capture_output = False ,
7273 )
7374
74- result = self .run (options , args )
75+ result = self .run (options , args , user = user )
7576 self .logger .debug ("SSH exit code: %s" , result .return_code )
7677
7778 if result .stdout :
@@ -118,7 +119,7 @@ def username(self) -> str:
118119 """Get the default SSH username"""
119120 return self .call ("get_default_username" )
120121
121- def run (self , options : SSHCommandRunOptions , args ) -> SSHCommandRunResult :
122+ def run (self , options : SSHCommandRunOptions , args , user : str | None = None ) -> SSHCommandRunResult :
122123 """Run SSH command with the given parameters and arguments"""
123124 # Get SSH command and default username from driver
124125 if options .direct :
@@ -131,7 +132,7 @@ def run(self, options: SSHCommandRunOptions, args) -> SSHCommandRunResult:
131132 if not host or not port :
132133 raise ValueError (f"Invalid address format: { address } " )
133134 self .logger .debug ("Using direct TCP connection for SSH - host: %s, port: %s" , host , port )
134- return self ._run_ssh_local (host , port , options , args )
135+ return self ._run_ssh_local (host , port , options , args , user )
135136 except (DriverMethodNotImplemented , ValueError ) as e :
136137 self .logger .error ("Direct address connection failed (%s), falling back to SSH port forwarding" , e )
137138 return self .run (SSHCommandRunOptions (
@@ -147,9 +148,9 @@ def run(self, options: SSHCommandRunOptions, args) -> SSHCommandRunResult:
147148 ) as addr :
148149 host , port = addr
149150 self .logger .debug ("SSH port forward established - host: %s, port: %s" , host , port )
150- return self ._run_ssh_local (host , port , options , args )
151+ return self ._run_ssh_local (host , port , options , args , user )
151152
152- def _run_ssh_local (self , host , port , options , args ):
153+ def _run_ssh_local (self , host , port , options , args , user : str | None = None ):
153154 """Run SSH command with the given host, port, and arguments"""
154155 # Create temporary identity file if needed
155156 ssh_identity = self .identity
@@ -175,7 +176,7 @@ def _run_ssh_local(self, host, port, options, args):
175176
176177 try :
177178 # Build SSH command arguments
178- ssh_args = self ._build_ssh_command_args (port , identity_file , args )
179+ ssh_args = self ._build_ssh_command_args (port , identity_file , args , user )
179180
180181 # Separate SSH options from command arguments
181182 ssh_options , command_args = self ._separate_ssh_options_and_command_args (args )
@@ -194,11 +195,11 @@ def _run_ssh_local(self, host, port, options, args):
194195 except Exception as e :
195196 self .logger .warning ("Failed to clean up temporary identity file %s: %s" , identity_file , str (e ))
196197
197- def _build_ssh_command_args (self , port , identity_file , args ):
198+ def _build_ssh_command_args (self , port , identity_file , args , user : str | None = None ):
198199 """Build initial SSH command arguments"""
199200 # Split the SSH command into individual arguments
200201 ssh_args = shlex .split (self .command )
201- default_username = self .username
202+ default_username = user or self .username
202203
203204 # Add identity file if provided
204205 if identity_file :
0 commit comments