Skip to content

Commit

Permalink
New native client tunneling implementation - resolves #123.
Browse files Browse the repository at this point in the history
Added greenlet timeout setting to native clients.
Native clients raise specific exceptions on errors.
Fixed timeout setting not being applied to native client sockets.
Fixed native client raising incorrect exception on timeouts connecting to host.
Updated documentation.
Increased test coverage.
  • Loading branch information
pkittenis committed Jun 14, 2018
1 parent b7f5a55 commit 1515270
Show file tree
Hide file tree
Showing 22 changed files with 992 additions and 508 deletions.
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ script:
- export LD_LIBRARY_PATH=/usr/local/lib/x86_64-linux-gnu
# For testing SSH agent related functionality
- eval `ssh-agent -s`
- nosetests --with-coverage --cover-package=pssh
- nosetests --with-coverage --cover-package=pssh tests/test_native_tunnel.py
- nosetests --with-coverage --cover-package=pssh tests/test_native_*_client.py
- nosetests --with-coverage --cover-package=pssh tests/test_paramiko*.py
- flake8 pssh
- cd doc; make html; cd ..
# Test building from source distribution
Expand Down
18 changes: 18 additions & 0 deletions Changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
Change Log
============

1.7.0
++++++

Changes
--------

* Better tunneling implementation for native clients that supports multiple tunnels over single SSH connection for connecting multiple hosts through single proxy.
* Added ``greenlet_timeout`` setting to native client ``run_command`` to pass on to getting greenlet result to allow for greenlets to timeout.
* Native client raises specific exceptions on non-authentication errors connecting to host instead of generic ``SessionError``.


Fixes
------

* Native client tunneling would not work correctly - #123.
* ``timeout`` setting was not applied to native client sockets.
* Native client would have ``SessionError`` instead of ``Timeout`` exceptions on timeout errors connecting to hosts.

1.6.3
++++++

Expand Down
2 changes: 1 addition & 1 deletion doc/advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ To make use of this new client, ``ParallelSSHClient`` can be imported from ``pss

`Feature comparison <ssh2.html>`_ for how the client features compare.

API documentation for `parallel <pssh2_client.html>`_ and `single <ssh2_client.html>`_ native clients.
API documentation for `parallel <native_parallel.html>`_ and `single <native_single.html>`_ native clients.

Tunneling
**********
Expand Down
1 change: 1 addition & 0 deletions doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ API Documentation
base_pssh
output
agent
tunnel
utils
exceptions
32 changes: 7 additions & 25 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,19 @@ It uses non-blocking asynchronous SSH sessions and is to date the only publicly
quickstart
ssh2
advanced
Changelog
api
Changelog

In a nutshell
**************

Client will attempt to use all available keys under ``~/.ssh`` as well as any keys in an SSH agent, if one is available.

.. code-block:: python
from __future__ import print_function
from pssh.pssh_client import ParallelSSHClient
from pssh.clients import ParallelSSHClient
client = ParallelSSHClient(['localhost'])
output = client.run_command('whoami')
Expand All @@ -54,31 +56,11 @@ In a nutshell
<your username here>
`ssh2-python` (`libssh2`) based clients
******************************************

As of version ``1.2.0``, new single host and parallel clients are available based on the ``libssh2`` C library via its ``ssh2-python`` wrapper.

They offer significantly enhanced performance and stability, at much less overhead, with a native non-blocking mode meaning *no monkey patching of the Python standard library* when using them.

To use them, import from ``pssh2_client`` or ``ssh2_client`` for the parallel and single clients respectively.

.. code-block:: python
from __future__ import print_function
from pssh.pssh2_client import ParallelSSHClient
client = ParallelSSHClient(['localhost'])
output = client.run_command('whoami')
for line in output['localhost'].stdout:
print(line)
The API is mostly identical to the current clients, though some features are not yet supported. See `client feature comparison <ssh2.html>`_ section for how feature support differs between the two clients.

.. note::

From version ``2.x.x`` onwards, the ``ssh2-python`` based clients will *become the default*, replacing the current ``pssh_client.ParallelSSHClient``, with the current clients renamed.
There is also a now deprecated paramiko based client available under ``pssh.clients.miko`` that has much the same API. It supports some features not currently supported by the native client - see `feature comparison <ssh2.html>`_.

From version ``2.x.x`` onwards, the clients under ``pssh.clients.miko`` will be an optional ``extras`` install.


Indices and tables
Expand Down
6 changes: 3 additions & 3 deletions doc/ssh2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Below is a comparison of feature support for the two client types.
=============================== ============== ======================
Feature paramiko ssh2-python (libssh2)
=============================== ============== ======================
Agent forwarding Yes Not supported (*PR Pending*)
Agent forwarding Yes Yes (binary wheels or from source builds only)
Proxying/tunnelling Yes Yes
Kerberos (GSS) authentication Yes Not supported
Private key file authentication Yes Yes
Expand All @@ -20,8 +20,8 @@ Session timeout setting Yes Yes
Per-channel timeout setting Yes Yes
Programmatic SSH agent Yes Not supported
OpenSSH config parsing Yes Not yet implemented
ECSA keys support Yes Not supported (*PR Pending*)
SCP functionality Not supported Not yet implemented
ECSA keys support Yes Yes
SCP functionality Not supported Yes
=============================== ============== ======================

If any of missing features are required for a use case, then the paramiko based clients should be used instead.
Expand Down
5 changes: 5 additions & 0 deletions doc/tunnel.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Native Tunnel
==============

.. automodule:: pssh.clients.native.tunnel
:member-order: groupwise
7 changes: 4 additions & 3 deletions pssh/clients/base_pssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ def run_command(self, command, user=None, stop_on_errors=True,
host_args=None, use_pty=False, shell=None,
encoding='utf-8',
*args, **kwargs):
greenlet_timeout = kwargs.pop('greenlet_timeout', None)
output = {}
if host_args:
try:
Expand All @@ -88,7 +89,7 @@ def run_command(self, command, user=None, stop_on_errors=True,
for host in self.hosts]
for cmd in cmds:
try:
self.get_output(cmd, output)
self.get_output(cmd, output, timeout=greenlet_timeout)
except Exception:
if stop_on_errors:
raise
Expand Down Expand Up @@ -122,7 +123,7 @@ def _get_host_config_values(self, host):
def _run_command(self, host, command, *args, **kwargs):
raise NotImplementedError

def get_output(self, cmd, output):
def get_output(self, cmd, output, timeout=None):
"""Get output from command.
:param cmd: Command to get output from
Expand All @@ -133,7 +134,7 @@ def get_output(self, cmd, output):
:type output: dict
:rtype: None"""
try:
(channel, host, stdout, stderr, stdin) = cmd.get()
(channel, host, stdout, stderr, stdin) = cmd.get(timeout=timeout)
except Exception as ex:
host = ex.host
self._update_host_output(
Expand Down
5 changes: 2 additions & 3 deletions pssh/clients/miko/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,5 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

# flake8: noqa: F401
from .parallel import ParallelSSHClient
from .single import SSHClient, logger
from .parallel import ParallelSSHClient # noqa: F401
from .single import SSHClient, logger # noqa: F401
Loading

0 comments on commit 1515270

Please sign in to comment.