mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-20 23:44:59 +02:00
Implement setting of env vars
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
import atexit
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
@@ -17,15 +18,36 @@ from typing import (
|
||||
)
|
||||
|
||||
from kitty.constants import cache_dir, shell_integration_dir, terminfo_dir
|
||||
from kitty.fast_data_types import get_options
|
||||
from kitty.short_uuid import uuid4
|
||||
from kitty.types import run_once
|
||||
from kitty.utils import SSHConnectionData
|
||||
|
||||
from .completion import complete, ssh_options
|
||||
from .options.types import Options as SSHOptions
|
||||
from .options.utils import DELETE_ENV_VAR
|
||||
|
||||
|
||||
def make_tarfile(ssh_opts: SSHOptions) -> bytes:
|
||||
def serialize_env(env: Dict[str, str], base_env: Dict[str, str]) -> bytes:
|
||||
lines = []
|
||||
|
||||
def a(k: str, val: str) -> None:
|
||||
lines.append(f'export {k}={shlex.quote(val)}')
|
||||
|
||||
for k in sorted(env):
|
||||
v = env[k]
|
||||
if v is DELETE_ENV_VAR:
|
||||
lines.append(f'unset {shlex.quote(k)}')
|
||||
elif v == '_kitty_copy_env_var_':
|
||||
q = base_env.get(k)
|
||||
if q is not None:
|
||||
a(k, q)
|
||||
else:
|
||||
a(k, v)
|
||||
return '\n'.join(lines).encode('utf-8')
|
||||
|
||||
|
||||
def make_tarfile(ssh_opts: SSHOptions, base_env: Dict[str, str]) -> bytes:
|
||||
|
||||
def normalize_tarinfo(tarinfo: tarfile.TarInfo) -> tarfile.TarInfo:
|
||||
tarinfo.uname = tarinfo.gname = 'kitty'
|
||||
@@ -48,19 +70,31 @@ def make_tarfile(ssh_opts: SSHOptions) -> bytes:
|
||||
return None
|
||||
return normalize_tarinfo(tarinfo)
|
||||
|
||||
from kitty.shell_integration import get_effective_ksi_env_var
|
||||
if ssh_opts.shell_integration == 'inherit':
|
||||
ksi = get_effective_ksi_env_var()
|
||||
else:
|
||||
from kitty.options.types import Options
|
||||
from kitty.options.utils import shell_integration
|
||||
ksi = get_effective_ksi_env_var(Options({'shell_integration': shell_integration(ssh_opts.shell_integration)}))
|
||||
|
||||
env = {
|
||||
'TERM': get_options().term,
|
||||
'COLORTERM': 'truecolor',
|
||||
}
|
||||
for q in ('KITTY_WINDOW_ID', 'WINDOWID'):
|
||||
val = os.environ.get(q)
|
||||
if val is not None:
|
||||
env[q] = val
|
||||
env.update(ssh_opts.env)
|
||||
env['KITTY_SHELL_INTEGRATION'] = ksi or DELETE_ENV_VAR
|
||||
env_script = serialize_env(env, base_env)
|
||||
buf = io.BytesIO()
|
||||
with tarfile.open(mode='w:bz2', fileobj=buf, encoding='utf-8') as tf:
|
||||
rd = ssh_opts.remote_dir.rstrip('/')
|
||||
from kitty.shell_integration import get_effective_ksi_env_var
|
||||
if ssh_opts.shell_integration == 'inherit':
|
||||
ksi = get_effective_ksi_env_var()
|
||||
else:
|
||||
from kitty.options.types import Options
|
||||
from kitty.options.utils import shell_integration
|
||||
ksi = get_effective_ksi_env_var(Options({'shell_integration': shell_integration(ssh_opts.shell_integration)}))
|
||||
add_data_as_file(tf, rd + '/settings/env-vars.sh', env_script)
|
||||
if ksi:
|
||||
tf.add(shell_integration_dir, arcname=rd + '/shell-integration', filter=filter_files)
|
||||
add_data_as_file(tf, rd + '/settings/ksi_env_var', ksi)
|
||||
tf.add(terminfo_dir, arcname='.terminfo', filter=filter_files)
|
||||
return buf.getvalue()
|
||||
|
||||
@@ -92,16 +126,19 @@ def get_ssh_data(msg: str, ssh_opts: Optional[Dict[str, SSHOptions]] = None) ->
|
||||
yield fmt_prefix('!invalid ssh data request message')
|
||||
else:
|
||||
try:
|
||||
with open(os.path.join(cache_dir(), pwfilename)) as f:
|
||||
with open(os.path.join(cache_dir(), pwfilename), 'rb') as f:
|
||||
os.unlink(f.name)
|
||||
if pw != f.read():
|
||||
env_data = json.load(f)
|
||||
if pw != env_data['pw']:
|
||||
raise ValueError('Incorrect password')
|
||||
except Exception:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
yield fmt_prefix('!incorrect ssh data password')
|
||||
else:
|
||||
resolved_ssh_opts = options_for_host(hostname, ssh_opts)
|
||||
try:
|
||||
data = make_tarfile(resolved_ssh_opts)
|
||||
data = make_tarfile(resolved_ssh_opts, env_data['env'])
|
||||
except Exception:
|
||||
yield fmt_prefix('!error while gathering ssh data')
|
||||
else:
|
||||
@@ -119,8 +156,9 @@ def safe_remove(x: str) -> None:
|
||||
|
||||
def prepare_script(ans: str, replacements: Dict[str, str]) -> str:
|
||||
pw = uuid4()
|
||||
with tempfile.NamedTemporaryFile(prefix='ssh-kitten-pw-', dir=cache_dir(), delete=False) as tf:
|
||||
tf.write(pw.encode('utf-8'))
|
||||
with tempfile.NamedTemporaryFile(prefix='ssh-kitten-pw-', suffix='.json', dir=cache_dir(), delete=False) as tf:
|
||||
data = {'pw': pw, 'env': dict(os.environ)}
|
||||
tf.write(json.dumps(data).encode('utf-8'))
|
||||
atexit.register(safe_remove, tf.name)
|
||||
replacements['DATA_PASSWORD'] = pw
|
||||
replacements['PASSWORD_FILENAME'] = os.path.basename(tf.name)
|
||||
|
||||
@@ -28,13 +28,13 @@ to SSH to connect to it.
|
||||
|
||||
opt('remote_dir', '.local/share/kitty-ssh-kitten', long_text='''
|
||||
The location on the remote computer where the files needed for this kitten
|
||||
are installed. The location is relative to the HOME directory.
|
||||
are installed. The location is relative to the HOME directory for relative paths.
|
||||
''')
|
||||
|
||||
opt('shell_integration', 'inherit', long_text='''
|
||||
Control the shell integration on the remote host. See ref:`shell_integration`
|
||||
for details on how this setting works. The special value :code:`inherit` means
|
||||
use the setting from kitty.conf. This setting is mainly useful for overriding
|
||||
use the setting from kitty.conf. This setting is useful for overriding
|
||||
integration on a per-host basis.''')
|
||||
|
||||
opt('+env', '', option_type='env', add_to_default=False, long_text='''
|
||||
@@ -47,6 +47,7 @@ environment variables can refer to each other, so if you use::
|
||||
The value of MYVAR2 will be :code:`a/<path to home directory>/b`. Using
|
||||
:code:`VAR=` will set it to the empty string and using just :code:`VAR`
|
||||
will delete the variable from the child process' environment. The definitions
|
||||
are processed alphabetically.
|
||||
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.
|
||||
''')
|
||||
egr() # }}}
|
||||
|
||||
Reference in New Issue
Block a user