Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def open(self):
"""Open ThreadedTerminal connection & start thread pulling data from it."""
ret = super(ThreadedTerminal, self).open()
if not self._terminal:
self._terminal = PtyProcessUnicode.spawn(self._cmd, dimensions=self.dimensions)
# need to not replace not unicode data instead of raise exception
self._terminal.decoder = codecs.getincrementaldecoder('utf-8')(errors='replace')
done = Event()
self.pulling_thread = TillDoneThread(target=self.pull_data,
done_event=done,
kwargs={'pulling_done': done})
self.pulling_thread.start()
retry = 0
is_operable = False
while (retry < 3) and (not is_operable):
is_operable = self._shell_operable.wait(timeout=1)
if not is_operable:
self.logger.warning("Terminal open but not fully operable yet")
self._terminal.write('\n')
Use excellent ptyprocess package to run a pty with a shell
and denot the process to a chosen user.
"""
self.slave_io, self.slave = pty.openpty()
self.slave_io = os.fdopen(self.slave_io, 'rb+wb', 0) # open file in an unbuffered mode
self._make_non_blocking(self.slave_io)
pw_record = pwd.getpwnam(self.user)
uid = pw_record.pw_uid
gid = pw_record.pw_gid
if pw_record.pw_shell is None:
pw_shell = '/bin/bash'
else:
pw_shell = pw_record.pw_shell
#self.slave_process = ptyprocess.PtyProcessUnicode.spawn(['/bin/bash','-i'],
self.slave_process = ptyprocess.PtyProcessUnicode.spawn([pw_shell,'-i'],
preexec_fn=prepare_subprocess(uid, gid),
dimensions=(self.size_y, self.size_x),
cwd=pw_record.pw_dir,
env=dict(TERM="linux",
HOME=pw_record.pw_dir,
LOGNAME=pw_record.pw_name,
PWD=pw_record.pw_dir,
USER=pw_record.pw_name
))
def kill_spawned_process(self):
"""
Kill spawned process inside container.
If process of `docker exec` was killed, the spawned process inside container is
still running. So we should kill spawned process before kill `docker exec`.
"""
p = PtyProcessUnicode.spawn(['docker', 'exec', self.container_id, '/bin/sh', '-c',
'kill -1 $(cat /tmp/sh.pid.{})'.format(self.uuid)])
# wait till complete execution of command
while p.isalive():
sleep(1)
p.close()
def start_pty(self, *args):
if not self.container_id:
self.send_error_and_close("Error: container not found.")
return
try:
# create a pseudo terminal of container by command:
# `docker exec -ti /bin/sh -c '[ -x /bin/bash ] && /bin/bash || /bin/sh'`
# and then set the stream to non-blocking mode.
pty = PtyProcessUnicode.spawn(
['docker', 'exec', '-ti', self.container_id, '/bin/sh', '-c',
'echo $$ > /tmp/sh.pid.{} && [ -x /bin/bash ] && /bin/bash || /bin/sh'.format(self.uuid)])
flags = fcntl(pty.fileobj, F_GETFL)
fcntl(pty.fileobj, F_SETFL, flags | O_NONBLOCK)
setattr(self, "pty", pty)
TerminalSocketHandler.clients.update({self: pty})
logger.info('Connect to console of container {}'.format(self.container_id))
except Exception as e:
self.send_error_and_close("Error: cannot start console: {}".format(e))