Skip to content

Commit

Permalink
Fix exec_command issue
Browse files Browse the repository at this point in the history
Fixes ansible#57
Fixes ansible#56

*  Use channel created with Channel class
   instead of creating a new channel with
   exec_command()
  • Loading branch information
ganeshrn committed Jul 13, 2020
1 parent c83d151 commit c79c2ca
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 23 deletions.
28 changes: 11 additions & 17 deletions src/pylibsshext/channel.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ cdef class Channel:
raise LibsshChannelException("Failed to open_session: [%d]" % rc)

def __dealloc__(self):
libssh.ssh_channel_free(self._libssh_channel)
self._libssh_channel = NULL
if self._libssh_channel is not NULL:
libssh.ssh_channel_free(self._libssh_channel)
self._libssh_channel = NULL

def request_shell(self):
self.request_pty()
Expand Down Expand Up @@ -133,17 +134,10 @@ cdef class Channel:
return response

def exec_command(self, command):
cdef libssh.ssh_channel channel = libssh.ssh_channel_new(self._libssh_session)
if channel is NULL:
raise MemoryError
rc = libssh.ssh_channel_open_session(channel)
if rc != libssh.SSH_OK:
libssh.ssh_channel_free(channel)
raise CalledProcessError()
rc = libssh.ssh_channel_request_exec(self._libssh_channel, command.encode("utf-8"))

rc = libssh.ssh_channel_request_exec(channel, command.encode("utf-8"))
if rc != libssh.SSH_OK:
libssh.ssh_channel_free(channel)
libssh.ssh_channel_free(self._libssh_channel)
raise CalledProcessError()

cdef callbacks.ssh_channel_callbacks_struct cb
Expand All @@ -152,18 +146,18 @@ cdef class Channel:
result = CompletedProcess(args=command, returncode=-1, stdout=b'', stderr=b'')
cb.userdata = <void *>result
callbacks.ssh_callbacks_init(&cb)
callbacks.ssh_set_channel_callbacks(channel, &cb)
callbacks.ssh_set_channel_callbacks(self._libssh_channel, &cb)

libssh.ssh_channel_send_eof(channel)
result.returncode = libssh.ssh_channel_get_exit_status(channel)
libssh.ssh_channel_send_eof(self._libssh_channel)

libssh.ssh_channel_free(channel)
result.returncode = self.get_channel_exit_status()

return result

def get_channel_exit_status(self):
return libssh.ssh_channel_get_exit_status(self._libssh_channel)

def close(self):
libssh.ssh_channel_free(self._libssh_channel)
self._libssh_channel = NULL
if self._libssh_channel is not NULL:
libssh.ssh_channel_free(self._libssh_channel)
self._libssh_channel = NULL
6 changes: 0 additions & 6 deletions tests/unit/channel_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,6 @@ def ssh_channel(ssh_client_session):
chan.close()


@pytest.mark.xfail(
reason='This test causes SEGFAULT, flakily. '
'Ref: https://github.com/ansible/pylibssh/issues/57', # noqa: WPS326
run=False,
strict=False,
)
@pytest.mark.forked
def test_exec_command(ssh_channel):
"""Test getting the output of a remotely executed command."""
Expand Down

0 comments on commit c79c2ca

Please sign in to comment.