Remote file transfer: Fix transfer not working is custom ssh port or identity is specified on the SSH command line
Fixes #4067
This commit is contained in:
parent
b70064d1be
commit
3bc7b5bad9
@ -55,6 +55,8 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
|||||||
- Linux: Fix IME with fcitx5 not working after fcitx5 is restarted
|
- Linux: Fix IME with fcitx5 not working after fcitx5 is restarted
|
||||||
(:pull:`4059`)
|
(:pull:`4059`)
|
||||||
|
|
||||||
|
- Remote file transfer: Fix transfer not working is custom ssh port or identity
|
||||||
|
is specified on the command line (:iss:`4067`)
|
||||||
|
|
||||||
|
|
||||||
0.23.1 [2021-08-17]
|
0.23.1 [2021-08-17]
|
||||||
|
|||||||
@ -118,7 +118,9 @@ class ControlMaster:
|
|||||||
'-o', 'TCPKeepAlive=yes', '-o', 'ControlPersist=yes'
|
'-o', 'TCPKeepAlive=yes', '-o', 'ControlPersist=yes'
|
||||||
]
|
]
|
||||||
if conn_data.port:
|
if conn_data.port:
|
||||||
cmd += ['-p', str(conn_data.port)]
|
cmd.extend(['-p', str(conn_data.port)])
|
||||||
|
if conn_data.identity_file:
|
||||||
|
cmd.extend(['-i', conn_data.identity_file])
|
||||||
self.batch_cmd_prefix = cmd + ['-o', 'BatchMode=yes']
|
self.batch_cmd_prefix = cmd + ['-o', 'BatchMode=yes']
|
||||||
|
|
||||||
def __enter__(self) -> 'ControlMaster':
|
def __enter__(self) -> 'ControlMaster':
|
||||||
|
|||||||
@ -140,13 +140,13 @@ def get_ssh_cli() -> Tuple[Set[str], Set[str]]:
|
|||||||
return boolean_ssh_args, other_ssh_args
|
return boolean_ssh_args, other_ssh_args
|
||||||
|
|
||||||
|
|
||||||
def get_connection_data(args: List[str]) -> Optional[SSHConnectionData]:
|
def get_connection_data(args: List[str], cwd: str = '') -> Optional[SSHConnectionData]:
|
||||||
boolean_ssh_args, other_ssh_args = get_ssh_cli()
|
boolean_ssh_args, other_ssh_args = get_ssh_cli()
|
||||||
found_ssh = ''
|
|
||||||
port: Optional[int] = None
|
port: Optional[int] = None
|
||||||
expecting_port = False
|
expecting_port = expecting_identity = False
|
||||||
expecting_option_val = False
|
expecting_option_val = False
|
||||||
expecting_hostname = False
|
expecting_hostname = False
|
||||||
|
host_name = identity_file = found_ssh = ''
|
||||||
|
|
||||||
for i, arg in enumerate(args):
|
for i, arg in enumerate(args):
|
||||||
if not found_ssh:
|
if not found_ssh:
|
||||||
@ -154,7 +154,8 @@ def get_connection_data(args: List[str]) -> Optional[SSHConnectionData]:
|
|||||||
found_ssh = arg
|
found_ssh = arg
|
||||||
continue
|
continue
|
||||||
if expecting_hostname:
|
if expecting_hostname:
|
||||||
return SSHConnectionData(found_ssh, arg, port)
|
host_name = arg
|
||||||
|
continue
|
||||||
if arg.startswith('-') and not expecting_option_val:
|
if arg.startswith('-') and not expecting_option_val:
|
||||||
if arg in boolean_ssh_args:
|
if arg in boolean_ssh_args:
|
||||||
continue
|
continue
|
||||||
@ -164,8 +165,15 @@ def get_connection_data(args: List[str]) -> Optional[SSHConnectionData]:
|
|||||||
if arg[2:].isdigit():
|
if arg[2:].isdigit():
|
||||||
with suppress(Exception):
|
with suppress(Exception):
|
||||||
port = int(arg[2:])
|
port = int(arg[2:])
|
||||||
|
continue
|
||||||
elif arg == '-p':
|
elif arg == '-p':
|
||||||
expecting_port = True
|
expecting_port = True
|
||||||
|
elif arg.startswith('-i'):
|
||||||
|
if arg == '-i':
|
||||||
|
expecting_identity = True
|
||||||
|
else:
|
||||||
|
identity_file = arg[2:]
|
||||||
|
continue
|
||||||
expecting_option_val = True
|
expecting_option_val = True
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -174,10 +182,22 @@ def get_connection_data(args: List[str]) -> Optional[SSHConnectionData]:
|
|||||||
with suppress(Exception):
|
with suppress(Exception):
|
||||||
port = int(arg)
|
port = int(arg)
|
||||||
expecting_port = False
|
expecting_port = False
|
||||||
|
elif expecting_identity:
|
||||||
|
identity_file = arg
|
||||||
expecting_option_val = False
|
expecting_option_val = False
|
||||||
continue
|
continue
|
||||||
|
|
||||||
return SSHConnectionData(found_ssh, arg, port)
|
if not host_name:
|
||||||
|
host_name = arg
|
||||||
|
if not host_name:
|
||||||
|
return None
|
||||||
|
if identity_file:
|
||||||
|
if not os.path.isabs(identity_file):
|
||||||
|
identity_file = os.path.expanduser(identity_file)
|
||||||
|
if not os.path.isabs(identity_file):
|
||||||
|
identity_file = os.path.normpath(os.path.join(cwd or os.getcwd(), identity_file))
|
||||||
|
|
||||||
|
return SSHConnectionData(found_ssh, host_name, port, identity_file)
|
||||||
|
|
||||||
|
|
||||||
class InvalidSSHArgs(ValueError):
|
class InvalidSSHArgs(ValueError):
|
||||||
|
|||||||
@ -705,6 +705,7 @@ class SSHConnectionData(NamedTuple):
|
|||||||
binary: str
|
binary: str
|
||||||
hostname: str
|
hostname: str
|
||||||
port: Optional[int] = None
|
port: Optional[int] = None
|
||||||
|
identity_file: str = ''
|
||||||
|
|
||||||
|
|
||||||
def get_new_os_window_size(
|
def get_new_os_window_size(
|
||||||
|
|||||||
@ -649,7 +649,7 @@ class Window:
|
|||||||
def handle_remote_file(self, netloc: str, remote_path: str) -> None:
|
def handle_remote_file(self, netloc: str, remote_path: str) -> None:
|
||||||
from kittens.ssh.main import get_connection_data
|
from kittens.ssh.main import get_connection_data
|
||||||
args = self.child.foreground_cmdline
|
args = self.child.foreground_cmdline
|
||||||
conn_data = get_connection_data(args)
|
conn_data = get_connection_data(args, self.child.foreground_cwd or self.child.current_cwd or '')
|
||||||
if conn_data is None:
|
if conn_data is None:
|
||||||
get_boss().show_error('Could not handle remote file', 'No SSH connection data found in: {args}')
|
get_boss().show_error('Could not handle remote file', 'No SSH connection data found in: {args}')
|
||||||
return
|
return
|
||||||
|
|||||||
25
kitty_tests/ssh.py
Normal file
25
kitty_tests/ssh.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=utf-8
|
||||||
|
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
from . import BaseTest
|
||||||
|
|
||||||
|
from kittens.ssh.main import get_connection_data
|
||||||
|
from kitty.utils import SSHConnectionData
|
||||||
|
|
||||||
|
|
||||||
|
class SSHTest(BaseTest):
|
||||||
|
|
||||||
|
def test_ssh_connection_data(self):
|
||||||
|
def t(cmdline, binary='ssh', host='main', port=None, identity_file=''):
|
||||||
|
if identity_file:
|
||||||
|
identity_file = os.path.abspath(identity_file)
|
||||||
|
q = get_connection_data(cmdline.split())
|
||||||
|
self.ae(q, SSHConnectionData(binary, host, port, identity_file))
|
||||||
|
|
||||||
|
t('ssh main')
|
||||||
|
t('ssh un@ip -i ident -p34', host='un@ip', port=34, identity_file='ident')
|
||||||
|
t('ssh un@ip -iident -p34', host='un@ip', port=34, identity_file='ident')
|
||||||
|
t('ssh -p 33 main', port=33)
|
||||||
Loading…
x
Reference in New Issue
Block a user