@@ -62,16 +62,18 @@ 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 ):
68+ """Run SSH command with arguments."""
6769 options = SSHCommandRunOptions (
6870 direct = direct ,
6971 # For the CLI, we never capture output so that interactive shells
7072 # and long-running commands stream their output directly.
7173 capture_output = False ,
7274 )
7375
74- result = self .run (options , args )
76+ result = self .run (options , args , user = user )
7577 self .logger .debug ("SSH exit code: %s" , result .return_code )
7678
7779 if result .stdout :
@@ -118,8 +120,15 @@ def username(self) -> str:
118120 """Get the default SSH username"""
119121 return self .call ("get_default_username" )
120122
121- def run (self , options : SSHCommandRunOptions , args ) -> SSHCommandRunResult :
122- """Run SSH command with the given parameters and arguments"""
123+ def run (self , options : SSHCommandRunOptions , args , user : str | None = None ) -> SSHCommandRunResult :
124+ """
125+ Run SSH command with the given parameters and arguments
126+
127+ Args:
128+ options: SSH command run options.
129+ args: Command arguments.
130+ user: Optional username to override the default.
131+ """
123132 # Get SSH command and default username from driver
124133 if options .direct :
125134 # Use direct TCP address
@@ -131,14 +140,14 @@ def run(self, options: SSHCommandRunOptions, args) -> SSHCommandRunResult:
131140 if not host or not port :
132141 raise ValueError (f"Invalid address format: { address } " )
133142 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 )
143+ return self ._run_ssh_local (host , port , options , args , user )
135144 except (DriverMethodNotImplemented , ValueError ) as e :
136145 self .logger .error ("Direct address connection failed (%s), falling back to SSH port forwarding" , e )
137146 return self .run (SSHCommandRunOptions (
138147 direct = False ,
139148 capture_output = options .capture_output ,
140149 capture_as_text = options .capture_as_text ,
141- ), args )
150+ ), args , user = user )
142151 else :
143152 # Use SSH port forwarding (default behavior)
144153 self .logger .debug ("Using SSH port forwarding for SSH connection" )
@@ -147,9 +156,9 @@ def run(self, options: SSHCommandRunOptions, args) -> SSHCommandRunResult:
147156 ) as addr :
148157 host , port = addr
149158 self .logger .debug ("SSH port forward established - host: %s, port: %s" , host , port )
150- return self ._run_ssh_local (host , port , options , args )
159+ return self ._run_ssh_local (host , port , options , args , user )
151160
152- def _run_ssh_local (self , host , port , options , args ):
161+ def _run_ssh_local (self , host , port , options , args , user : str | None = None ):
153162 """Run SSH command with the given host, port, and arguments"""
154163 # Create temporary identity file if needed
155164 ssh_identity = self .identity
@@ -175,7 +184,7 @@ def _run_ssh_local(self, host, port, options, args):
175184
176185 try :
177186 # Build SSH command arguments
178- ssh_args = self ._build_ssh_command_args (port , identity_file , args )
187+ ssh_args = self ._build_ssh_command_args (port , identity_file , args , user )
179188
180189 # Separate SSH options from command arguments
181190 ssh_options , command_args = self ._separate_ssh_options_and_command_args (args )
@@ -194,11 +203,11 @@ def _run_ssh_local(self, host, port, options, args):
194203 except Exception as e :
195204 self .logger .warning ("Failed to clean up temporary identity file %s: %s" , identity_file , str (e ))
196205
197- def _build_ssh_command_args (self , port , identity_file , args ):
206+ def _build_ssh_command_args (self , port , identity_file , args , user : str | None = None ):
198207 """Build initial SSH command arguments"""
199208 # Split the SSH command into individual arguments
200209 ssh_args = shlex .split (self .command )
201- default_username = self .username
210+ default_username = user or self .username
202211
203212 # Add identity file if provided
204213 if identity_file :
0 commit comments