Skip to content

Commit

Permalink
Forward compatibility for ssh2-python
Browse files Browse the repository at this point in the history
  • Loading branch information
pkittenis committed Mar 21, 2018
1 parent 78f1bb3 commit 9aa0701
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 15 deletions.
8 changes: 8 additions & 0 deletions Changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Change Log
============

1.5.3
++++++

Changes
--------

* Compatibility with ``ssh2-python`` >= ``0.11.0``.

1.5.2
++++++

Expand Down
50 changes: 35 additions & 15 deletions pssh/ssh2_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,13 @@ def open_session(self):
"""Open new channel from session"""
chan = self.session.open_session()
errno = self.session.last_errno()
while chan is None and errno == LIBSSH2_ERROR_EAGAIN:
while (chan is None and errno == LIBSSH2_ERROR_EAGAIN) \
or chan == LIBSSH2_ERROR_EAGAIN:
wait_select(self.session)
chan = self.session.open_session()
try:
chan = self.session.open_session()
except Exception as ex:
raise SessionError(ex)
errno = self.session.last_errno()
if chan is None and errno != LIBSSH2_ERROR_EAGAIN:
raise SessionError(errno)
Expand Down Expand Up @@ -269,6 +273,14 @@ def read_output(self, channel, timeout=None):
"""
return _read_output(self.session, channel.read, timeout=timeout)

def _select_timeout(self, func, timeout):
ret = func()
while ret == LIBSSH2_ERROR_EAGAIN:
wait_select(self.session, timeout=timeout)
ret = func()
if ret == LIBSSH2_ERROR_EAGAIN and timeout is not None:
raise Timeout

def wait_finished(self, channel, timeout=None):
"""Wait for EOF from channel, close channel and wait for
close acknowledgement.
Expand All @@ -284,19 +296,13 @@ def wait_finished(self, channel, timeout=None):
# If .eof() returns EAGAIN after a select with a timeout, it means
# it reached timeout without EOF and the channel should not be
# closed as the command is still running.
ret = channel.wait_eof()
while ret == LIBSSH2_ERROR_EAGAIN:
wait_select(self.session, timeout=timeout)
ret = channel.wait_eof()
if ret == LIBSSH2_ERROR_EAGAIN and timeout is not None:
raise Timeout
self._select_timeout(channel.wait_eof, timeout)
# Close channel to indicate no more commands will be sent over it
self.close_channel(channel)

def close_channel(self, channel):
logger.debug("Closing channel")
self._eagain(channel.close)
self._eagain(channel.wait_closed)

def _eagain(self, func, *args, **kwargs):
ret = func(*args, **kwargs)
Expand Down Expand Up @@ -373,11 +379,18 @@ def run_command(self, command, sudo=False, user=None,

def _make_sftp(self):
"""Make SFTP client from open transport"""
sftp = self.session.sftp_init()
try:
sftp = self.session.sftp_init()
except Exception as ex:
raise SFTPError(ex)
errno = self.session.last_errno()
while sftp is None and errno == LIBSSH2_ERROR_EAGAIN:
while (sftp is None and errno == LIBSSH2_ERROR_EAGAIN) \
or sftp == LIBSSH2_ERROR_EAGAIN:
wait_select(self.session)
sftp = self.session.sftp_init()
try:
sftp = self.session.sftp_init()
except Exception as ex:
raise SFTPError(ex)
errno = self.session.last_errno()
if sftp is None and errno != LIBSSH2_ERROR_EAGAIN:
raise SFTPError("Error initialising SFTP - error code %s",
Expand Down Expand Up @@ -572,11 +585,18 @@ def _sftp_readdir(self, dir_h):
yield line

def _sftp_openfh(self, open_func, remote_file, *args):
fh = open_func(remote_file, *args)
try:
fh = open_func(remote_file, *args)
except Exception as ex:
raise SFTPError(ex)
errno = self.session.last_errno()
while fh is None and errno == LIBSSH2_ERROR_EAGAIN:
while (fh is None and errno == LIBSSH2_ERROR_EAGAIN) \
or fh == LIBSSH2_ERROR_EAGAIN:
wait_select(self.session, timeout=0.1)
fh = open_func(remote_file, *args)
try:
fh = open_func(remote_file, *args)
except Exception as ex:
raise SFTPError(ex)
errno = self.session.last_errno()
if fh is None and errno != LIBSSH2_ERROR_EAGAIN:
msg = "Error opening file handle for file %s - error no: %s"
Expand Down

0 comments on commit 9aa0701

Please sign in to comment.