ssh kitten: Add an option to change the cwd at login
This commit is contained in:
parent
b0ea960159
commit
c9071a66ca
@ -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
|
env['KITTY_SSH_KITTEN_DATA_DIR'] = ssh_opts.remote_dir
|
||||||
if ssh_opts.login_shell:
|
if ssh_opts.login_shell:
|
||||||
env['KITTY_LOGIN_SHELL'] = 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)
|
env_script = serialize_env(env, base_env)
|
||||||
buf = io.BytesIO()
|
buf = io.BytesIO()
|
||||||
with tarfile.open(mode='w:bz2', fileobj=buf, encoding='utf-8') as tf:
|
with tarfile.open(mode='w:bz2', fileobj=buf, encoding='utf-8') as tf:
|
||||||
|
|||||||
@ -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.
|
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='''
|
opt('interpreter', 'sh', long_text='''
|
||||||
The interpreter to use on the remote host. Must be either a POSIX complaint shell
|
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
|
or a python executable. If the default sh is not available for broken, using
|
||||||
|
|||||||
@ -11,6 +11,9 @@ class Parser:
|
|||||||
for k, v in copy(val, ans["copy"]):
|
for k, v in copy(val, ans["copy"]):
|
||||||
ans["copy"][k] = v
|
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:
|
def env(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||||
for k, v in env(val, ans["env"]):
|
for k, v in env(val, ans["env"]):
|
||||||
ans["env"][k] = v
|
ans["env"][k] = v
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import kittens.ssh.copy
|
|||||||
|
|
||||||
option_names = ( # {{{
|
option_names = ( # {{{
|
||||||
'copy',
|
'copy',
|
||||||
|
'cwd',
|
||||||
'env',
|
'env',
|
||||||
'hostname',
|
'hostname',
|
||||||
'interpreter',
|
'interpreter',
|
||||||
@ -15,6 +16,7 @@ option_names = ( # {{{
|
|||||||
|
|
||||||
|
|
||||||
class Options:
|
class Options:
|
||||||
|
cwd: str = ''
|
||||||
hostname: str = '*'
|
hostname: str = '*'
|
||||||
interpreter: str = 'sh'
|
interpreter: str = 'sh'
|
||||||
login_shell: str = ''
|
login_shell: str = ''
|
||||||
|
|||||||
@ -142,9 +142,10 @@ copy --exclude */w.* d1
|
|||||||
tset = '$A-$(echo no)-`echo no2` "something"'
|
tset = '$A-$(echo no)-`echo no2` "something"'
|
||||||
for sh in self.all_possible_sh:
|
for sh in self.all_possible_sh:
|
||||||
with self.subTest(sh=sh), tempfile.TemporaryDirectory() as tdir:
|
with self.subTest(sh=sh), tempfile.TemporaryDirectory() as tdir:
|
||||||
|
os.mkdir(os.path.join(tdir, 'cwd'))
|
||||||
pty = self.check_bootstrap(
|
pty = self.check_bootstrap(
|
||||||
sh, tdir, test_script='env; exit 0', SHELL_INTEGRATION_VALUE='',
|
sh, tdir, test_script='env; pwd; exit 0', SHELL_INTEGRATION_VALUE='',
|
||||||
ssh_opts={'env': {
|
ssh_opts={'cwd': '$HOME/cwd', 'env': {
|
||||||
'A': 'AAA',
|
'A': 'AAA',
|
||||||
'TSET': tset,
|
'TSET': tset,
|
||||||
'COLORTERM': DELETE_ENV_VAR,
|
'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())
|
pty.wait_till(lambda: 'TSET={}'.format(tset.replace('$A', 'AAA')) in pty.screen_contents())
|
||||||
self.assertNotIn('COLORTERM', pty.screen_contents())
|
self.assertNotIn('COLORTERM', pty.screen_contents())
|
||||||
|
pty.wait_till(lambda: '/cwd' in pty.screen_contents())
|
||||||
|
|
||||||
def test_ssh_leading_data(self):
|
def test_ssh_leading_data(self):
|
||||||
script = 'echo "ld:$leading_data"; exit 0'
|
script = 'echo "ld:$leading_data"; exit 0'
|
||||||
|
|||||||
@ -230,6 +230,9 @@ def main():
|
|||||||
get_data()
|
get_data()
|
||||||
finally:
|
finally:
|
||||||
cleanup()
|
cleanup()
|
||||||
|
cwd = os.environ.pop('KITTY_LOGIN_CWD', '')
|
||||||
|
if cwd:
|
||||||
|
os.chdir(cwd)
|
||||||
ksi = frozenset(filter(None, os.environ.get('KITTY_SHELL_INTEGRATION', '').split()))
|
ksi = frozenset(filter(None, os.environ.get('KITTY_SHELL_INTEGRATION', '').split()))
|
||||||
exec_cmd = b'EXEC_CMD'
|
exec_cmd = b'EXEC_CMD'
|
||||||
if exec_cmd:
|
if exec_cmd:
|
||||||
|
|||||||
@ -86,8 +86,8 @@ hostname="$HOSTNAME"
|
|||||||
# ensure $USER is set
|
# ensure $USER is set
|
||||||
[ -z "$USER" ] && USER="$(command whoami 2> /dev/null)"
|
[ -z "$USER" ] && USER="$(command whoami 2> /dev/null)"
|
||||||
|
|
||||||
# ask for the SSH data
|
|
||||||
leading_data=""
|
leading_data=""
|
||||||
|
login_cwd=""
|
||||||
|
|
||||||
init_tty && trap "cleanup_on_bootstrap_exit" EXIT
|
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""
|
[ "$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"
|
read_n_bytes_from_tty "$1" | command base64 -d | command tar xpjf - -C "$tdir"
|
||||||
data_file="$tdir/data.sh"
|
data_file="$tdir/data.sh"
|
||||||
[ -f "$data_file" ] && . "$data_file"
|
[ -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"
|
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"
|
compile_terminfo "$tdir/home"
|
||||||
mv_files_and_dirs "$tdir/home" "$HOME"
|
mv_files_and_dirs "$tdir/home" "$HOME"
|
||||||
[ -e "$tdir/root" ] && mv_files_and_dirs "$tdir/root" ""
|
[ -e "$tdir/root" ] && mv_files_and_dirs "$tdir/root" ""
|
||||||
command rm -rf "$tdir"
|
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() {
|
read_record() {
|
||||||
@ -160,6 +162,7 @@ get_data() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if [ "$tty_ok" = "y" ]; then
|
if [ "$tty_ok" = "y" ]; then
|
||||||
|
# ask for the SSH data
|
||||||
get_data
|
get_data
|
||||||
cleanup_on_bootstrap_exit
|
cleanup_on_bootstrap_exit
|
||||||
if [ -n "$leading_data" ]; then
|
if [ -n "$leading_data" ]; then
|
||||||
@ -252,6 +255,7 @@ else
|
|||||||
using_getent || using_id || using_python || using_passwd || die "Could not detect login shell"
|
using_getent || using_id || using_python || using_passwd || die "Could not detect login shell"
|
||||||
fi
|
fi
|
||||||
shell_name=$(command basename $login_shell)
|
shell_name=$(command basename $login_shell)
|
||||||
|
[ -n "$login_cwd" ] && cd "$login_cwd"
|
||||||
|
|
||||||
# If a command was passed to SSH execute it here
|
# If a command was passed to SSH execute it here
|
||||||
EXEC_CMD
|
EXEC_CMD
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user