You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by "John Carr (JIRA)" <ji...@apache.org> on 2014/01/10 13:34:50 UTC

[jira] [Commented] (LIBCLOUD-491) ParamikoSSHClient don't show stdout/stderr when run fast commands

    [ https://issues.apache.org/jira/browse/LIBCLOUD-491?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13867763#comment-13867763 ] 

John Carr commented on LIBCLOUD-491:
------------------------------------

I've seen this in other projects. The method that has been working robustly for us isn't pretty and would need cleaning up a bit for libcloud:

{code}
        def recvr(ready, recv, cb, buffer):
            # ready is the callable to check if there is anything in the buffer like chan.recv_ready
            # recv actually reads from the buffer (chan.recv)
            # cb is called when there is data - for when we want to print "live" to our terminal as the command runs, rather than at end
            # buffer - something with an append() method to collect an ordered list of strings.
            while ready():
                data = recv(1024)
                if data:
                    if cb:
                        cb(data)
                    buffer.append(data)

        stdout_buffer = []
        stderr_buffer = []

        while not channel.exit_status_ready():
            rlist, wlist, xlist = select.select([channel], [], [], 1)
            if not rlist:
                continue

            recvr(channel.recv_ready, channel.recv, stdout, stdout_buffer)
            recvr(channel.recv_stderr_ready,
                  channel.recv_stderr, stderr, stderr_buffer)

        while not channel.eof_received:
            # FIXME: I don't know why this isn't part of the other while loop really.... Maybe it didn't work?
            recvr(channel.recv_ready, channel.recv, stdout, stdout_buffer)
            recvr(channel.recv_stderr_ready,
                  channel.recv_stderr, stderr, stderr_buffer)

        # When eof has been received there might still be stuff in the buffers so check one last time
        recvr(channel.recv_ready, channel.recv, stdout, stdout_buffer)
        recvr(channel.recv_stderr_ready,
              channel.recv_stderr, stderr, stderr_buffer)

        returncode = channel.recv_exit_status()
{code}

(I had a manual test case that was copying large files to a remote box using tee and stdin and then cat'ing them back down and checking for differences. A few iterations of this quickly broke most other things i tried).

> ParamikoSSHClient don't show stdout/stderr when run fast commands
> -----------------------------------------------------------------
>
>                 Key: LIBCLOUD-491
>                 URL: https://issues.apache.org/jira/browse/LIBCLOUD-491
>             Project: Libcloud
>          Issue Type: Bug
>            Reporter: Oleg Suharev
>            Priority: Critical
>
> Hello
> Commit a053cde create a big trouble in ParamikoSSHClien.run method. When I run 'fast' commands (for example uname -a) this method doesn't return stdout/stderr, because code
> {code}
> while not chan.exit_status_ready():
>             if chan.recv_ready():
> {code}
> doesn't run since chan.exit_status_ready() already return True (in first call)
> [~kami] please fix this trouble.
> {code}
> In [1]: from libcloud.compute.ssh import SSHClient
> In [2]: client = SSHClient('123.123.321.321', key='/Users/user/mykey.pem')
> In [3]: client.connect()
> Out[3]: True
> In [4]: client.run('uname -a')
> Out[4]: ['', '', 0]
> {code}



--
This message was sent by Atlassian JIRA
(v6.1.5#6160)