Implement an option to control the installation of the kitty bootstrap script
This commit is contained in:
parent
a2d1140229
commit
c07f164154
@ -156,6 +156,8 @@ def make_tarfile(ssh_opts: SSHOptions, base_env: Dict[str, str], compression: st
|
|||||||
env['KITTY_LOGIN_SHELL'] = ssh_opts.login_shell
|
env['KITTY_LOGIN_SHELL'] = ssh_opts.login_shell
|
||||||
if ssh_opts.cwd:
|
if ssh_opts.cwd:
|
||||||
env['KITTY_LOGIN_CWD'] = ssh_opts.cwd
|
env['KITTY_LOGIN_CWD'] = ssh_opts.cwd
|
||||||
|
if ssh_opts.remote_kitty != 'no':
|
||||||
|
env['KITTY_REMOTE'] = ssh_opts.remote_kitty
|
||||||
env_script = serialize_env(env, base_env)
|
env_script = serialize_env(env, base_env)
|
||||||
buf = io.BytesIO()
|
buf = io.BytesIO()
|
||||||
with tarfile.open(mode=f'w:{compression}', fileobj=buf, encoding='utf-8') as tf:
|
with tarfile.open(mode=f'w:{compression}', fileobj=buf, encoding='utf-8') as tf:
|
||||||
@ -171,9 +173,10 @@ def make_tarfile(ssh_opts: SSHOptions, base_env: Dict[str, str], compression: st
|
|||||||
f'{arcname}/ssh/*', # bootstrap files are sent as command line args
|
f'{arcname}/ssh/*', # bootstrap files are sent as command line args
|
||||||
f'{arcname}/zsh/kitty.zsh', # present for legacy compat not needed by ssh kitten
|
f'{arcname}/zsh/kitty.zsh', # present for legacy compat not needed by ssh kitten
|
||||||
))
|
))
|
||||||
arcname = 'home/' + rd + '/kitty'
|
if ssh_opts.remote_kitty != 'no':
|
||||||
add_data_as_file(tf, arcname + '/version', str_version.encode('ascii'))
|
arcname = 'home/' + rd + '/kitty'
|
||||||
tf.add(shell_integration_dir + '/ssh/kitty', arcname=arcname + '/bin/kitty', filter=normalize_tarinfo)
|
add_data_as_file(tf, arcname + '/version', str_version.encode('ascii'))
|
||||||
|
tf.add(shell_integration_dir + '/ssh/kitty', arcname=arcname + '/bin/kitty', filter=normalize_tarinfo)
|
||||||
tf.add(f'{terminfo_dir}/kitty.terminfo', arcname='home/.terminfo/kitty.terminfo', filter=normalize_tarinfo)
|
tf.add(f'{terminfo_dir}/kitty.terminfo', arcname='home/.terminfo/kitty.terminfo', filter=normalize_tarinfo)
|
||||||
tf.add(glob.glob(f'{terminfo_dir}/*/xterm-kitty')[0], arcname='home/.terminfo/x/xterm-kitty', filter=normalize_tarinfo)
|
tf.add(glob.glob(f'{terminfo_dir}/*/xterm-kitty')[0], arcname='home/.terminfo/x/xterm-kitty', filter=normalize_tarinfo)
|
||||||
return buf.getvalue()
|
return buf.getvalue()
|
||||||
|
|||||||
@ -102,6 +102,19 @@ 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
|
value are expanded. The default is empty so no changing is done, which
|
||||||
usually means the home directory is used.
|
usually means the home directory is used.
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
opt('remote_kitty', 'if-needed', choices=('if-needed', 'no', 'yes'), long_text='''
|
||||||
|
Make kitty available on the remote server. Useful to run kittens such as the
|
||||||
|
icat kitten to display images or the transfer file kitten to transfer files.
|
||||||
|
Only works if the remote server has an architecture for which pre-compiled
|
||||||
|
kitty binaries are available. Note that kitty is not actually copied to the
|
||||||
|
remote server, instead a small bootstrap script is copied which will download
|
||||||
|
and run kitty when kitty is first executed on the remote server. A value of
|
||||||
|
:code:`needed` means kitty is installed only if not already present in the
|
||||||
|
system-wide PATH. A value of :code:`yes` means that kitty is installed even if
|
||||||
|
already present, and the installed kitty takes precedence. Finally, :code:`no`
|
||||||
|
means no kitty is installed on the remote machine.
|
||||||
|
''')
|
||||||
egr() # }}}
|
egr() # }}}
|
||||||
|
|
||||||
agr('ssh', 'SSH configuration') # {{{
|
agr('ssh', 'SSH configuration') # {{{
|
||||||
|
|||||||
@ -38,6 +38,14 @@ class Parser:
|
|||||||
def remote_dir(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
def remote_dir(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||||
ans['remote_dir'] = relative_dir(val)
|
ans['remote_dir'] = relative_dir(val)
|
||||||
|
|
||||||
|
def remote_kitty(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||||
|
val = val.lower()
|
||||||
|
if val not in self.choices_for_remote_kitty:
|
||||||
|
raise ValueError(f"The value {val} is not a valid choice for remote_kitty")
|
||||||
|
ans["remote_kitty"] = val
|
||||||
|
|
||||||
|
choices_for_remote_kitty = frozenset(('if-needed', 'no', 'yes'))
|
||||||
|
|
||||||
def share_connections(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
def share_connections(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||||
ans['share_connections'] = to_bool(val)
|
ans['share_connections'] = to_bool(val)
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,10 @@ import kittens.ssh.copy
|
|||||||
|
|
||||||
if typing.TYPE_CHECKING:
|
if typing.TYPE_CHECKING:
|
||||||
choices_for_askpass = typing.Literal['unless-set', 'ssh', 'native']
|
choices_for_askpass = typing.Literal['unless-set', 'ssh', 'native']
|
||||||
|
choices_for_remote_kitty = typing.Literal['if-needed', 'no', 'yes']
|
||||||
else:
|
else:
|
||||||
choices_for_askpass = str
|
choices_for_askpass = str
|
||||||
|
choices_for_remote_kitty = str
|
||||||
|
|
||||||
option_names = ( # {{{
|
option_names = ( # {{{
|
||||||
'askpass',
|
'askpass',
|
||||||
@ -17,6 +19,7 @@ option_names = ( # {{{
|
|||||||
'interpreter',
|
'interpreter',
|
||||||
'login_shell',
|
'login_shell',
|
||||||
'remote_dir',
|
'remote_dir',
|
||||||
|
'remote_kitty',
|
||||||
'share_connections',
|
'share_connections',
|
||||||
'shell_integration') # }}}
|
'shell_integration') # }}}
|
||||||
|
|
||||||
@ -28,6 +31,7 @@ class Options:
|
|||||||
interpreter: str = 'sh'
|
interpreter: str = 'sh'
|
||||||
login_shell: str = ''
|
login_shell: str = ''
|
||||||
remote_dir: str = '.local/share/kitty-ssh-kitten'
|
remote_dir: str = '.local/share/kitty-ssh-kitten'
|
||||||
|
remote_kitty: choices_for_remote_kitty = 'if-needed'
|
||||||
share_connections: bool = True
|
share_connections: bool = True
|
||||||
shell_integration: str = 'inherited'
|
shell_integration: str = 'inherited'
|
||||||
copy: typing.Dict[str, kittens.ssh.copy.CopyInstruction] = {}
|
copy: typing.Dict[str, kittens.ssh.copy.CopyInstruction] = {}
|
||||||
|
|||||||
@ -169,6 +169,24 @@ fi' > "$sh_script"
|
|||||||
exec "$login_shell"
|
exec "$login_shell"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
install_kitty_bootstrap() {
|
||||||
|
case "$(command uname)" in
|
||||||
|
Linux) ;;
|
||||||
|
Darwin) ;;
|
||||||
|
*) return ;;
|
||||||
|
esac
|
||||||
|
kitty_exists="n"
|
||||||
|
command -v kitty 2> /dev/null > /dev/null && kitty_exists="y"
|
||||||
|
if [ "$kitty_remote" = "yes" -o "$kitty_remote-$kitty_exists" = "if-needed-n" ]; then
|
||||||
|
kitty_dir="$data_dir/kitty/bin"
|
||||||
|
if [ "$kitty_exists" = "y" ]; then
|
||||||
|
export PATH="$kitty_dir:$PATH"
|
||||||
|
else
|
||||||
|
export PATH="$PATH:$kitty_dir"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
prepare_for_exec() {
|
prepare_for_exec() {
|
||||||
if [ -n "$leading_data" ]; then
|
if [ -n "$leading_data" ]; then
|
||||||
# clear current line as it might have things echoed on it from leading_data
|
# clear current line as it might have things echoed on it from leading_data
|
||||||
@ -177,6 +195,7 @@ prepare_for_exec() {
|
|||||||
printf "\r\033[K" > /dev/tty
|
printf "\r\033[K" > /dev/tty
|
||||||
fi
|
fi
|
||||||
[ -f "$HOME/.terminfo/kitty.terminfo" ] || die "Incomplete extraction of ssh data"
|
[ -f "$HOME/.terminfo/kitty.terminfo" ] || die "Incomplete extraction of ssh data"
|
||||||
|
install_kitty_bootstrap
|
||||||
|
|
||||||
[ -n "$login_shell" ] || using_getent || using_id || using_python || using_perl || using_passwd || using_shell_env || login_shell="sh"
|
[ -n "$login_shell" ] || using_getent || using_id || using_python || using_perl || using_passwd || using_shell_env || login_shell="sh"
|
||||||
shell_name=$(command basename $login_shell)
|
shell_name=$(command basename $login_shell)
|
||||||
|
|||||||
@ -258,6 +258,19 @@ def exec_with_shell_integration():
|
|||||||
exec_bash_with_integration()
|
exec_bash_with_integration()
|
||||||
|
|
||||||
|
|
||||||
|
def install_kitty_bootstrap():
|
||||||
|
kitty_remote = os.environ.pop('KITTY_REMOTE', '')
|
||||||
|
if os.uname().sysname not in ('Linux', 'Darwin'):
|
||||||
|
return
|
||||||
|
kitty_exists = shutil.which('kitty')
|
||||||
|
if kitty_remote == 'yes' or (kitty_remote == 'if-needed' and not kitty_exists):
|
||||||
|
kitty_dir = os.path.join(data_dir, 'kitty', 'bin')
|
||||||
|
if kitty_exists:
|
||||||
|
os.environ['PATH'] = kitty_dir + os.pathsep + os.environ['PATH']
|
||||||
|
else:
|
||||||
|
os.environ['PATH'] = os.environ['PATH'] + os.pathsep + kitty_dir
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
global tty_file_obj, login_shell
|
global tty_file_obj, login_shell
|
||||||
# the value of O_CLOEXEC below is on macOS which is most likely to not have
|
# the value of O_CLOEXEC below is on macOS which is most likely to not have
|
||||||
@ -271,6 +284,7 @@ def main():
|
|||||||
finally:
|
finally:
|
||||||
cleanup()
|
cleanup()
|
||||||
cwd = os.environ.pop('KITTY_LOGIN_CWD', '')
|
cwd = os.environ.pop('KITTY_LOGIN_CWD', '')
|
||||||
|
install_kitty_bootstrap()
|
||||||
if cwd:
|
if cwd:
|
||||||
os.chdir(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()))
|
||||||
|
|||||||
@ -106,6 +106,8 @@ untar_and_read_env() {
|
|||||||
unset KITTY_LOGIN_SHELL
|
unset KITTY_LOGIN_SHELL
|
||||||
login_cwd="$KITTY_LOGIN_CWD"
|
login_cwd="$KITTY_LOGIN_CWD"
|
||||||
unset KITTY_LOGIN_CWD
|
unset KITTY_LOGIN_CWD
|
||||||
|
kitty_remote="$KITTY_REMOTE"
|
||||||
|
unset KITTY_REMOTE
|
||||||
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" ""
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user