You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2013/12/29 00:53:00 UTC
[1/2] git commit: Document some choices in the ssh client.
Updated Branches:
refs/heads/trunk 6c1b9de65 -> a053cde54
Document some choices in the ssh client.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/6e53bfff
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/6e53bfff
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/6e53bfff
Branch: refs/heads/trunk
Commit: 6e53bfff2edaee590cb1d70ba333e7a9a82c203a
Parents: 6c1b9de
Author: Tomaz Muraus <to...@apache.org>
Authored: Sat Dec 28 23:54:26 2013 +0100
Committer: Tomaz Muraus <to...@apache.org>
Committed: Sun Dec 29 00:16:47 2013 +0100
----------------------------------------------------------------------
libcloud/compute/ssh.py | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/6e53bfff/libcloud/compute/ssh.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/ssh.py b/libcloud/compute/ssh.py
index d476e87..7cbcee6 100644
--- a/libcloud/compute/ssh.py
+++ b/libcloud/compute/ssh.py
@@ -239,20 +239,32 @@ class ParamikoSSHClient(BaseSSHClient):
return True
def run(self, cmd):
+ """
+ Note: This function is based on paramiko's exec_command()
+ method.
+ """
extra = {'_cmd': cmd}
self.logger.debug('Executing command', extra=extra)
- # based on exec_command()
+ # Use the system default buffer size
bufsize = -1
- t = self.client.get_transport()
- chan = t.open_session()
+
+ transport = self.client.get_transport()
+ chan = transport.open_session()
+
chan.exec_command(cmd)
+
stdin = chan.makefile('wb', bufsize)
stdout = chan.makefile('rb', bufsize)
stderr = chan.makefile_stderr('rb', bufsize)
- #stdin, stdout, stderr = self.client.exec_command(cmd)
+
stdin.close()
+
+ # Receive the exit status code of the command we ran.
+ # Note: If the command hasn't finished yet, this method will block
+ # until it does
status = chan.recv_exit_status()
+
so = stdout.read()
se = stderr.read()
[2/2] git commit: Fix a deployment buffering issue spotted by
@pquerna which could happen if the the executed command produced a lot of
output.
Posted by to...@apache.org.
Fix a deployment buffering issue spotted by @pquerna which could happen if the
the executed command produced a lot of output.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/a053cde5
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/a053cde5
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/a053cde5
Branch: refs/heads/trunk
Commit: a053cde54fb6fffe8666aa01de46a354115f4f40
Parents: 6e53bff
Author: Tomaz Muraus <to...@apache.org>
Authored: Sun Dec 29 00:31:20 2013 +0100
Committer: Tomaz Muraus <to...@apache.org>
Committed: Sun Dec 29 00:43:12 2013 +0100
----------------------------------------------------------------------
libcloud/compute/ssh.py | 52 ++++++++++++++++++++++++++++++++++++--------
1 file changed, 43 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/a053cde5/libcloud/compute/ssh.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/ssh.py b/libcloud/compute/ssh.py
index 7cbcee6..88094a5 100644
--- a/libcloud/compute/ssh.py
+++ b/libcloud/compute/ssh.py
@@ -36,6 +36,11 @@ from os.path import split as psplit
from os.path import join as pjoin
from libcloud.utils.logging import ExtraLogFormatter
+from libcloud.utils.py3 import StringIO
+
+
+# Maximum number of bytes to read at once from a socket
+CHUNK_SIZE = 1024
class BaseSSHClient(object):
@@ -254,24 +259,53 @@ class ParamikoSSHClient(BaseSSHClient):
chan.exec_command(cmd)
- stdin = chan.makefile('wb', bufsize)
- stdout = chan.makefile('rb', bufsize)
- stderr = chan.makefile_stderr('rb', bufsize)
+ stdout = StringIO()
+ stderr = StringIO()
+ # Create a stdin file and immediately close it to prevent any
+ # interactive script from hanging the process.
+ stdin = chan.makefile('wb', bufsize)
stdin.close()
+ # Receive all the output
+ # Note: This is used instead of chan.makefile approach to prevent
+ # buffering issues and hanging if the executed command produces a lot
+ # of output.
+ while not chan.exit_status_ready():
+ if chan.recv_ready():
+ data = chan.recv(CHUNK_SIZE)
+
+ while data:
+ stdout.write(data)
+ ready = chan.recv_ready()
+
+ if not ready:
+ break
+
+ data = chan.recv(CHUNK_SIZE)
+
+ if chan.recv_stderr_ready():
+ data = chan.recv_stderr(CHUNK_SIZE)
+
+ while data:
+ stderr.write(data)
+ ready = chan.recv_stderr_ready()
+
+ if not ready:
+ break
+
+ data = chan.recv_stderr(CHUNK_SIZE)
+
# Receive the exit status code of the command we ran.
- # Note: If the command hasn't finished yet, this method will block
- # until it does
status = chan.recv_exit_status()
- so = stdout.read()
- se = stderr.read()
+ stdout = stdout.getvalue()
+ stderr = stderr.getvalue()
- extra = {'_status': status, '_stdout': so, '_stderr': se}
+ extra = {'_status': status, '_stdout': stdout, '_stderr': stderr}
self.logger.debug('Command finished', extra=extra)
- return [so, se, status]
+ return [stdout, stderr, status]
def close(self):
self.logger.debug('Closing server connection')