def shell(self, username=None, cmd_args=[]):
""" Opens a new interactive shell in the container. """
# We run this in case our lxdock.yml config was modified since our last `lxdock up`.
self._setup_env()
# For now, it's much easier to call `lxc`, but eventually, we might want to contribute
# to pylxd so it supports `interactive = True` in `exec()`.
shellcfg = self.options.get('shell', {})
shelluser = username or shellcfg.get('user')
if shelluser:
# This part is the result of quite a bit of `su` args trial-and-error.
shellhome = shellcfg.get('home') if not username else None
homearg = '--env HOME={}'.format(shellhome) if shellhome else ''
cmd = 'lxc exec {} {} -- su -m {}'.format(self.lxd_name, homearg, shelluser)
else:
cmd = 'lxc exec {} -- su -m root'.format(self.lxd_name)
if cmd_args:
# Again, a bit of trial-and-error.
# 1. Using `su -s SCRIPT_FILE` instead of `su -c COMMAND` because `su -c` cannot
# receive SIGINT (Ctrl-C).
# Ref: //sethmiller.org/it/su-forking-and-the-incorrect-trapping-of-sigint-ctrl-c/
# See also: //github.com/lxdock/lxdock/pull/67#issuecomment-299755944
# 2. Applying shlex.quote to every argument to protect special characters.
# e.g.: lxdock shell container_name -c echo "he re\"s" '$PATH'
self._guest.run(['mkdir', '-p',
str(PurePosixPath(self._guest_shell_script_file).parent)])
self._container.files.put(self._guest_shell_script_file, textwrap.dedent(
"""\
#!/bin/sh
{}
""".format(' '.join(map(shlex.quote, cmd_args)))))
self._guest.run(['chmod', 'a+rx', self._guest_shell_script_file])
cmd += ' -s {}'.format(self._guest_shell_script_file)
subprocess.call(cmd, shell=True)
评论列表
文章目录