ssh kitten: Add an option to change the cwd at login

This commit is contained in:
Kovid Goyal 2022-03-07 12:24:37 +05:30
parent b0ea960159
commit c9071a66ca
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
7 changed files with 29 additions and 5 deletions

View File

@ -113,6 +113,8 @@ def make_tarfile(ssh_opts: SSHOptions, base_env: Dict[str, str]) -> bytes:
env['KITTY_SSH_KITTEN_DATA_DIR'] = ssh_opts.remote_dir
if ssh_opts.login_shell:
env['KITTY_LOGIN_SHELL'] = ssh_opts.login_shell
if ssh_opts.cwd:
env['KITTY_LOGIN_CWD'] = ssh_opts.cwd
env_script = serialize_env(env, base_env)
buf = io.BytesIO()
with tarfile.open(mode='w:bz2', fileobj=buf, encoding='utf-8') as tf:

View File

@ -71,6 +71,14 @@ are processed alphabetically. The special value :code:`_kitty_copy_env_var_`
will cause the value of the variable to be copied from the local machine.
''')
opt('cwd', '', long_text='''
The working directory on the remote host to change to. Env vars in this
value are expanded. The default is empty so no changing is done, which
usually means the home directory is used.
''')
opt('interpreter', 'sh', long_text='''
The interpreter to use on the remote host. Must be either a POSIX complaint shell
or a python executable. If the default sh is not available for broken, using

View File

@ -11,6 +11,9 @@ class Parser:
for k, v in copy(val, ans["copy"]):
ans["copy"][k] = v
def cwd(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
ans['cwd'] = str(val)
def env(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
for k, v in env(val, ans["env"]):
ans["env"][k] = v

View File

@ -6,6 +6,7 @@ import kittens.ssh.copy
option_names = ( # {{{
'copy',
'cwd',
'env',
'hostname',
'interpreter',
@ -15,6 +16,7 @@ option_names = ( # {{{
class Options:
cwd: str = ''
hostname: str = '*'
interpreter: str = 'sh'
login_shell: str = ''

View File

@ -142,9 +142,10 @@ copy --exclude */w.* d1
tset = '$A-$(echo no)-`echo no2` "something"'
for sh in self.all_possible_sh:
with self.subTest(sh=sh), tempfile.TemporaryDirectory() as tdir:
os.mkdir(os.path.join(tdir, 'cwd'))
pty = self.check_bootstrap(
sh, tdir, test_script='env; exit 0', SHELL_INTEGRATION_VALUE='',
ssh_opts={'env': {
sh, tdir, test_script='env; pwd; exit 0', SHELL_INTEGRATION_VALUE='',
ssh_opts={'cwd': '$HOME/cwd', 'env': {
'A': 'AAA',
'TSET': tset,
'COLORTERM': DELETE_ENV_VAR,
@ -152,6 +153,7 @@ copy --exclude */w.* d1
)
pty.wait_till(lambda: 'TSET={}'.format(tset.replace('$A', 'AAA')) in pty.screen_contents())
self.assertNotIn('COLORTERM', pty.screen_contents())
pty.wait_till(lambda: '/cwd' in pty.screen_contents())
def test_ssh_leading_data(self):
script = 'echo "ld:$leading_data"; exit 0'

View File

@ -230,6 +230,9 @@ def main():
get_data()
finally:
cleanup()
cwd = os.environ.pop('KITTY_LOGIN_CWD', '')
if cwd:
os.chdir(cwd)
ksi = frozenset(filter(None, os.environ.get('KITTY_SHELL_INTEGRATION', '').split()))
exec_cmd = b'EXEC_CMD'
if exec_cmd:

View File

@ -86,8 +86,8 @@ hostname="$HOSTNAME"
# ensure $USER is set
[ -z "$USER" ] && USER="$(command whoami 2> /dev/null)"
# ask for the SSH data
leading_data=""
login_cwd=""
init_tty && trap "cleanup_on_bootstrap_exit" EXIT
[ "$tty_ok" = "y" ] && dcs_to_kitty "ssh" "id="REQUEST_ID":hostname="$hostname":pwfile="PASSWORD_FILENAME":user="$USER":pw="DATA_PASSWORD""
@ -129,13 +129,15 @@ untar_and_read_env() {
read_n_bytes_from_tty "$1" | command base64 -d | command tar xpjf - -C "$tdir"
data_file="$tdir/data.sh"
[ -f "$data_file" ] && . "$data_file"
[ -z "$KITTY_SSH_KITTEN_DATA_DIR" ] && die "Failed to read SSH data from tty"
data_dir="$HOME/$KITTY_SSH_KITTEN_DATA_DIR"
unset KITTY_SSH_KITTEN_DATA_DIR
login_cwd="$KITTY_LOGIN_CWD"
unset KITTY_LOGIN_CWD
compile_terminfo "$tdir/home"
mv_files_and_dirs "$tdir/home" "$HOME"
[ -e "$tdir/root" ] && mv_files_and_dirs "$tdir/root" ""
command rm -rf "$tdir"
[ -z "KITTY_SSH_KITTEN_DATA_DIR" ] && die "Failed to read SSH data from tty"
unset KITTY_SSH_KITTEN_DATA_DIR
}
read_record() {
@ -160,6 +162,7 @@ get_data() {
}
if [ "$tty_ok" = "y" ]; then
# ask for the SSH data
get_data
cleanup_on_bootstrap_exit
if [ -n "$leading_data" ]; then
@ -252,6 +255,7 @@ else
using_getent || using_id || using_python || using_passwd || die "Could not detect login shell"
fi
shell_name=$(command basename $login_shell)
[ -n "$login_cwd" ] && cd "$login_cwd"
# If a command was passed to SSH execute it here
EXEC_CMD