Exemple #1
0
 def new_terminal(self, ip_address="", **kwargs):
     """Make a new terminal, return a :class:`PtyWithClients` instance."""
     options = self.term_settings.copy()
     options['shell_command'] = self.shell_command
     options.update(kwargs)
     env = self.make_term_env(**options)
     if ip_address == "":
         argv = options['shell_command']
         pty = PtyProcessUnicode.spawn(argv,
                                       env=env,
                                       cwd=options.get('cwd', None))
     else:
         argv = 'ssh admin@%s' % (ip_address)
         pty = pexpect.spawn(argv, env=env, cwd=options.get('cwd', None))
         ssh_newkey = 'Are you sure you want to continue connecting'
         i = pty.expect([pexpect.TIMEOUT, ssh_newkey, 'password: '******'yes')
             pty.expect('password: '******'password: '******'Connect to server timeout')
                 return None
         pty.sendline('admin')
     return PtyWithClients(pty)
Exemple #2
0
    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 < 10) 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.\nREAD_BUFFER: '{}'"
                        .format(self.read_buffer.encode("UTF-8", "replace")))
                    self._terminal.write('\n')
                    retry += 1

        return ret
 def new_terminal(self, **kwargs):
     options = self.term_settings.copy()
     options['shell_command'] = self.shell_command
     options.update(kwargs)
     argv = options['shell_command']
     env = self.make_term_env(**options)
     pty = PtyProcessUnicode.spawn(argv, env=env, cwd=options.get('cwd', None))
     return PtyWithClients(pty)
 def new_terminal(self, **kwargs):
     """Make a new terminal, return a :class:`PtyWithClients` instance."""
     options = self.term_settings.copy()
     options['shell_command'] = self.shell_command
     options.update(kwargs)
     argv = options['shell_command']
     env = self.make_term_env(**options)
     pty = PtyProcessUnicode.spawn(argv, env=env, cwd=options.get('cwd', None))
     return PtyWithClients(pty)
Exemple #5
0
 def open(self):
     """Open ThreadedTerminal connection & start thread pulling data from it."""
     if not self._terminal:
         self._terminal = PtyProcessUnicode.spawn(
             self._cmd, dimensions=self.dimensions)
         done = Event()
         self.pulling_thread = TillDoneThread(target=self.pull_data,
                                              done_event=done,
                                              kwargs={'pulling_done': done})
         self.pulling_thread.start()
         self._shell_operable.wait(timeout=2)
 def __init__(self, argv, env=[], cwd=None):
     self.clients = []
     # If you start the process and then construct this object from it,
     #  output generated by the process prior to the object's creation
     #  is lost.  Hence the change from 0.8.3.
     # Buffer output until a client connects; then let the client
     #  drain the buffer.
     # We keep the same read_buffer as before
     self.read_buffer = deque([], maxlen=10)
     self.preopen_buffer = deque([])
     self.ptyproc = PtyProcessUnicode.spawn(argv, env=env, cwd=cwd)
Exemple #7
0
def _import_torrent(torrent):
    proc = PtyProcessUnicode.spawn([
        "beet",
        "import",
        "--noresume",
        _calculate_import_path(torrent),
    ])
    PROCESSES[torrent.id] = proc
    _read_and_send_pty_out(proc, torrent)
    exit_status = _right_exit_status(proc.exitstatus)
    return exit_status
Exemple #8
0
 def __init__(self, argv, env=[], cwd=None):
     self.clients = []
     # Use read_buffer to store historical messages for reconnection
     self.read_buffer = deque([], maxlen=1000)
     kwargs = dict(argv=argv, env=env, cwd=cwd)
     if preexec_fn is not None:
         kwargs["preexec_fn"] = preexec_fn
     self.ptyproc = PtyProcessUnicode.spawn(**kwargs)
     # The output might not be strictly UTF-8 encoded, so
     # we replace the inner decoder of PtyProcessUnicode
     # to allow non-strict decode.
     self.ptyproc.decoder = codecs.getincrementaldecoder('utf-8')(errors='replace')
Exemple #9
0
    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()
Exemple #10
0
    def new_one(self, **kwargs):
        """Make a new terminal, return a :class:`PtyWithClients` instance."""

        options = {}
        options['shell_command'] = self.shell_command
        options.update(kwargs)
        argv = options['shell_command']
        env = self.make_term_env(**options)

        self.proc = PtyProcessUnicode.spawn(argv,
                                            env=env,
                                            cwd=options.get('cwd', None))

        return self
Exemple #11
0
    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()
Exemple #12
0
 def test_spawn_unicode_sh(self):
     env = os.environ.copy()
     env['FOO'] = 'rebar'
     p = PtyProcessUnicode.spawn(['sh'], env=env)
     p.read()
     p.write(u'echo $FOO\n')
     time.sleep(0.1)
     response = p.read()
     assert u'rebar' in response
     
     p.sendeof()
     p.read()
     
     with self.assertRaises(EOFError):
         p.read()
    def test_spawn_unicode_sh(self):
        env = os.environ.copy()
        env['FOO'] = 'rebar'
        p = PtyProcessUnicode.spawn(['sh'], env=env)
        p.read()
        p.write(u'echo $FOO\n')
        time.sleep(0.1)
        response = p.read()
        assert u'rebar' in response

        p.sendeof()
        p.readline()

        with self.assertRaises(EOFError):
            p.read()
Exemple #14
0
    def _interactive_repl_unicode(self, echo):
        """Test Call and response with echo ON/OFF."""
        # given,
        bc = PtyProcessUnicode.spawn(['bc'], echo=echo)
        given_input = u'2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2\n'
        expected_output = u'40'

        # gnu-bc will display a long FSF banner on startup,
        # whereas bsd-bc (on FreeBSD, Solaris) display no
        # banner at all.  To ensure we've read up to our
        # current prompt, read until the response of '2^16' is found.
        time.sleep(1)

        bc.write(u'2^16\n')
        outp = u''
        while self._canread(bc.fd):
            outp += bc.read()
        assert u'65536' in outp

        # exercise,
        bc.write(given_input)

        while self._canread(bc.fd, timeout=2):
            outp += bc.read()

        # with echo ON, we should see our input.
        #
        # note: we cannot assert the reverse: on Solaris, FreeBSD,
        # and OSX, our input is echoed to output even with echo=False,
        # something to do with the non-gnu version of bc(1), perhaps.
        if echo:
            assert given_input.strip() in outp

        # we should most certainly see the result output.
        assert expected_output in outp

        # exercise sending EOF
        bc.sendeof()

        # validate EOF on read
        while True:
            try:
                bc.read()
            except EOFError:
                break

        # validate exit status,
        assert bc.wait() == 0
Exemple #15
0
    def _interactive_repl_unicode(self, echo):
        """Test Call and response with echo ON/OFF."""
        # given,
        bc = PtyProcessUnicode.spawn(['bc'], echo=echo)
        given_input = u'2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2\n'
        expected_output = u'40'

        # gnu-bc will display a long FSF banner on startup,
        # whereas bsd-bc (on FreeBSD, Solaris) display no
        # banner at all.  To ensure we've read up to our
        # current prompt, read until the response of '2^16' is found.
        time.sleep(1)

        bc.write(u'2^16\n')
        outp = u''
        while self._canread(bc.fd):
            outp += bc.read()
        assert u'65536' in outp

        # exercise,
        bc.write(given_input)

        while self._canread(bc.fd, timeout=2):
            outp += bc.read()

        # with echo ON, we should see our input.
        #
        # note: we cannot assert the reverse: on Solaris, FreeBSD,
        # and OSX, our input is echoed to output even with echo=False,
        # something to do with the non-gnu version of bc(1), perhaps.
        if echo:
            assert given_input.strip() in outp

        # we should most certainly see the result output.
        assert expected_output in outp

        # exercise sending EOF
        bc.sendeof()

        # validate EOF on read
        while True:
            try:
                bc.read()
            except EOFError:
                break

        # validate exit status,
        assert bc.wait() == 0
Exemple #16
0
    def run(self) -> int:
        from codecs import getreader
        import subprocess as sp
        import sys
        from cleo.io.io import OutputType  # type: ignore[import]
        from ptyprocess import PtyProcessUnicode  # type: ignore[import]

        color = self._colors[
            0] if TestRunner._prev_color is None else self._colors[
                (self._colors.index(TestRunner._prev_color) + 1) %
                len(self._colors)]
        TestRunner._prev_color = color
        command = ['bash', '-c', self.config]
        prefix = f'{self.name}| '

        try:
            cols, rows = os.get_terminal_size()
        except OSError:
            sproc = sp.Popen(command,
                             cwd=self.cwd,
                             stdout=sp.PIPE,
                             stderr=sp.STDOUT)
            assert sproc.stdout
            stdout = getreader(sys.getdefaultencoding())(sproc.stdout)
            for line in iter(stdout.readline, ''):
                line = line.rstrip()
                if self.line_prefixing:
                    self.io.write(f'<fg={color}>{prefix}</fg>')
                self.io.write(line + '\n', type=OutputType.NORMAL)
            sproc.wait()
            assert sproc.returncode is not None
            return sproc.returncode
        else:
            proc = PtyProcessUnicode.spawn(command,
                                           dimensions=(rows,
                                                       cols - len(prefix)),
                                           cwd=self.cwd)
            while not proc.eof():
                try:
                    line = proc.readline().rstrip()
                except EOFError:
                    break
                if self.line_prefixing:
                    self.io.write(f'<fg={color}>{prefix}</fg>')
                self.io.write(line + '\n', type=OutputType.NORMAL)
            proc.wait()
            assert proc.exitstatus is not None
            return proc.exitstatus
Exemple #17
0
    def __init__(self,
                 argv,
                 cwd=None,
                 env=None,
                 name='tty',
                 dimensions=(24, 80)):
        ptyproc = PtyProcessUnicode.spawn(argv, env=env, cwd=cwd)
        self.ptyproc = ptyproc
        self.name = name
        self.read_watch = FdWatcher(self)
        # tracker for XtermSocketHandler connected to this terminal
        self.clients = []

        # Store the last few things read, so when a new client connects,
        # it can show e.g. the most recent prompt, rather than absolutely
        # nothing.
        self.read_buffer = deque([], maxlen=15)
Exemple #18
0
 def __init__(self, argv, env=[], cwd=None):
     self.clients = []
     # If you start the process and then construct this object from it,
     #  output generated by the process prior to the object's creation
     #  is lost.  Hence the change from 0.8.3.
     # Buffer output until a client connects; then let the client
     #  drain the buffer.
     # We keep the same read_buffer as before
     self.read_buffer = deque([], maxlen=10)
     self.preopen_buffer = deque([])
     kwargs = dict(argv=argv, env=env, cwd=cwd)
     if preexec_fn is not None:
         kwargs["preexec_fn"] = preexec_fn
     self.ptyproc = PtyProcessUnicode.spawn(**kwargs)
     # The output might not be strictly UTF-8 encoded, so
     # we replace the inner decoder of PtyProcessUnicode
     # to allow non-strict decode.
     self.ptyproc.decoder = codecs.getincrementaldecoder('utf-8')(errors='replace')
Exemple #19
0
async def run_in_terminal(msg, send, context):
    root = context.shared.project_root
    mode = msg['mode']
    path = Path(root, *msg.get('filePath', [])).resolve()
    args = shlex.split(msg.get('args', ''))

    await stop(msg, send, context)
    if mode == 'script':
        command = ['python', shlex.quote(str(path))] + args
    elif mode == 'module':
        module = '.'.join(path.relative_to(root).parts[:-1] + (path.stem, ))
        command = ['python', '-m', module] + args
    elif mode == 'shell':
        command = shlex.split(msg['command'])
    else:
        raise ValueError('unsupported mode')

    cwd = msg.get('cwd', None)
    if not cwd:
        cwd = str(root)
    cwd = shlex.quote(cwd)

    if IS_PTY:
        pty = PtyProcessUnicode.spawn(command,
                                      cwd=cwd,
                                      dimensions=(msg['rows'], msg['cols']))
        await send('Started', None)
        context.pty = pty
        loop = asyncio.get_event_loop()
        context.reader = asyncio.ensure_future(
            loop.run_in_executor(
                None, partial(reader, pty, context.main_thread_send, context)))
    else:
        pty = await asyncio.create_subprocess_shell(shlex.join(command),
                                                    stdin=PIPE,
                                                    stdout=PIPE,
                                                    stderr=STDOUT,
                                                    cwd=cwd,
                                                    bufsize=0)
        await send('Started', None)
        context.pty = pty
        context.reader = asyncio.create_task(async_reader(pty, send))
        context.reader = asyncio.create_task(wait_until_finish(pty, send))
Exemple #20
0
    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 <container_id> /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))
Exemple #21
0
def run_pty_subprocess(cmd: List[str],
                       capture: Capture = Capture.BOTH,
                       stdin: Optional[str] = None) -> Tuple[int, str]:
    """
    Run a command in a PTY subprocess.

    Arguments:
        cmd: The command to run.
        capture: The output to capture.
        stdin: String to use as standard input.

    Returns:
        The exit code and the command output.
    """
    process = PtyProcessUnicode.spawn(cmd)
    pty_output: List[str] = []

    if stdin is not None:
        process.setecho(False)
        process.waitnoecho()
        process.write(stdin)
        process.sendeof()
        # not sure why but sending only one eof is not always enough,
        # so we send a second one and ignore any IO error
        with contextlib.suppress(OSError):
            process.sendeof()

    while True:
        try:
            output_data = process.read()
        except EOFError:
            break
        if capture == Capture.NONE:
            print(output_data, end="", flush=True)  # noqa: WPS421 (print)
        else:
            pty_output.append(output_data)

    output = "".join(pty_output).replace("\r\n", "\n")
    return process.wait(), output
Exemple #22
0
    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 <container_id> /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))
Exemple #23
0
 def spawn(self, argv):
     self.set_quit_signal()
     self.pty = PtyProcessUnicode.spawn(argv)
     self._copy()
     self.pty.wait()
     return (self.pty.exitstatus, self.log)
Exemple #24
0
    script.write(appaware_command)

# spin up in a subprocesses

pid = os.fork()

if pid == 0:
    abort_oracle_j2 = Template("su - {{ orauser }} -c 'kill -9 -1'")
    abort_oracle = abort_oracle_j2.render(orauser=act_orauser)

    def unmountthemount(SignNum, frame):
        os.system(abort_oracle)
        appliance.unmount_image(image=mountedimage)

    # register for the signals
    signal.signal(signal.SIGINT, unmountthemount)
    signal.signal(signal.SIGTERM, unmountthemount)

    while True:
        time.sleep(60)
else:
    # ignore all the signals... let oracle deal with them
    for sig in signal.Signals:
        print(sig)
        if (sig != signal.SIGKILL): signal.signal(sig, signal.SIG_IGN)

    # run with a terminal
    script_proc = PtyProcessUnicode.spawn(["bash", "/script/run.sh"])
    while True:
        print(script_proc.readline())
Exemple #25
0
 def _process(self, argv):
     self.set_quit_signal()
     self.pty = PtyProcessUnicode.spawn(argv)
Exemple #26
0
from ptyprocess import PtyProcessUnicode
p = PtyProcessUnicode.spawn(['python3'])
x = p.read(20)
print("x=", x)
p.write('6+6\n')
y = p.read(20)
print("y=", y)