Skip to content

Commit 2e9fdb2

Browse files
authored
Fix read same host (#242)
* Added read output from multiple commands on same host test * Updated examples * Updated host output to hold output buffers - updated clients. * Updated documentation, readme, changelog * Removed travis cfg
1 parent 3b1d052 commit 2e9fdb2

17 files changed

+225
-205
lines changed

.travis.yml

-45
This file was deleted.

Changelog.rst

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
Change Log
22
============
33

4+
2.3.1
5+
+++++
6+
7+
Changes
8+
-------
9+
10+
* ``SSHClient.read_output`` and ``read_stderr`` now take buffer to read from as argument instead of channel.
11+
* ``SSHClient.wait_finished`` now takes ``HostOutput`` argument instead of channel.
12+
13+
Fixes
14+
-----
15+
16+
* Output for multiple commands on one host run at the same time would be lost.
17+
18+
419
2.3.0
520
+++++
621

@@ -34,7 +49,7 @@ As is this:
3449

3550
.. code-block:: python
3651
37-
client.run_command(<..>, timeout=1)
52+
client.run_command(<..>, read_timeout=1)
3853
client.join(output, timeout=1)
3954
for line in output[0].stdout:
4055
print(line)

README.rst

+29-13
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,14 @@ Run SSH commands over many - hundreds/hundreds of thousands - number of servers
88

99
Native code based client with extremely high performance - based on ``libssh2`` C library.
1010

11-
.. image:: https://img.shields.io/badge/License-LGPL%20v2-blue.svg
11+
.. image:: https://img.shields.io/badge/License-LGPL%20v2.1-blue.svg
1212
:target: https://pypi.python.org/pypi/parallel-ssh
1313
:alt: License
1414
.. image:: https://img.shields.io/pypi/v/parallel-ssh.svg
1515
:target: https://pypi.python.org/pypi/parallel-ssh
1616
:alt: Latest Version
1717
.. image:: https://circleci.com/gh/ParallelSSH/parallel-ssh/tree/master.svg?style=svg
1818
:target: https://circleci.com/gh/ParallelSSH/parallel-ssh
19-
.. image:: https://ci.appveyor.com/api/projects/status/github/parallelssh/parallel-ssh?svg=true&branch=master
20-
:target: https://ci.appveyor.com/project/pkittenis/parallel-ssh-4nme1
2119
.. image:: https://codecov.io/gh/ParallelSSH/parallel-ssh/branch/master/graph/badge.svg
2220
:target: https://codecov.io/gh/ParallelSSH/parallel-ssh
2321
.. image:: https://img.shields.io/pypi/wheel/parallel-ssh.svg
@@ -44,7 +42,7 @@ Usage Example
4442

4543
See documentation on `read the docs`_ for more complete examples.
4644

47-
Run ``uname`` on two remote hosts in parallel.
45+
Run ``uname`` on two hosts in parallel.
4846

4947
.. code-block:: python
5048
@@ -53,7 +51,7 @@ Run ``uname`` on two remote hosts in parallel.
5351
hosts = ['localhost', 'localhost']
5452
client = ParallelSSHClient(hosts)
5553
56-
output = client.run_command('uname', return_list=True)
54+
output = client.run_command('uname')
5755
for host_output in output:
5856
for line in host_output.stdout:
5957
print(line)
@@ -65,15 +63,34 @@ Run ``uname`` on two remote hosts in parallel.
6563
Linux
6664
Linux
6765
66+
67+
Single Host Client
68+
*******************
69+
70+
Single host client with similar API for users that do not need parallel functionality.
71+
72+
.. code-block:: python
73+
74+
from pssh.clients import SSHClient
75+
76+
host = 'localhost'
77+
cmd = 'uname'
78+
client = SSHClient(host)
79+
80+
host_out = client.run_command(cmd)
81+
for line in host_out.stdout:
82+
print(line)
83+
84+
6885
**************
6986
Native clients
7087
**************
7188

72-
Starting from version ``1.2.0``, the default client in ``parallel-ssh`` has changed to a native client based on ``ssh2-python`` - ``libssh2`` C library - which offers much greater performance and reduced overhead compared to other Python SSH libraries.
89+
The default client in ``parallel-ssh`` is a native client based on ``ssh2-python`` - ``libssh2`` C library - which offers much greater performance and reduced overhead compared to other Python SSH libraries.
7390

7491
See `this post <https://parallel-ssh.org/post/parallel-ssh-libssh2>`_ for a performance comparison of different Python SSH libraries.
7592

76-
An alternative client based on ``ssh-python`` (``libssh``) is also available. See `client documentation <http://parallel-ssh.readthedocs.io/en/latest/clients.html>`_ for a feature comparison of the available clients in the library.
93+
Alternative clients based on ``ssh-python`` (``libssh``) are also available under ``pssh.clients.ssh``. See `client documentation <http://parallel-ssh.readthedocs.io/en/latest/clients.html>`_ for a feature comparison of the available clients in the library.
7794

7895
``parallel-ssh`` makes use of clients and an event loop solely based on C libraries providing native code levels of performance and stability with an easy to use Python API.
7996

@@ -84,15 +101,15 @@ Native Code Client Features
84101

85102
* Highest performance and least overhead of any Python SSH library
86103
* Thread safe - makes use of native threads for CPU bound calls like authentication
87-
* Natively non-blocking utilising ``libssh2`` via ``ssh2-python``
104+
* Natively asynchronous utilising ``libssh2`` via ``ssh2-python``
88105
* Significantly reduced overhead in CPU and memory usage
89106

90107

91108
***********
92109
Exit codes
93110
***********
94111

95-
Once *either* standard output is iterated on *to completion*, or ``client.join(output, consume_output=True)`` is called, exit codes become available in host output.
112+
Once *either* standard output is iterated on *to completion*, or ``client.join()`` is called, exit codes become available in host output.
96113

97114
Iteration ends *only when remote command has completed*, though it may be interrupted and resumed at any point.
98115

@@ -126,23 +143,22 @@ After ``join`` returns, commands have finished and all output can be read withou
126143

127144
.. code-block:: python
128145
129-
client.join(output)
146+
client.join()
130147
131148
for host_out in output:
132149
for line in host_output.stdout:
133150
print(line)
134151
print(host_out.exit_code)
135152
136-
Similarly, exit codes are available after ``client.join(output, consume_output=True)``.
153+
Similarly, exit codes are available after ``client.join()`` without reading output.
137154

138-
``consume_output`` flag must be set to get exit codes when not reading from ``stdout``. Future releases aim to remove the need for `consume_output` to be set.
139155

140156
.. code-block:: python
141157
142158
output = client.run_command('uname')
143159
144160
# Wait for commands to complete and consume output so can get exit codes
145-
client.join(output, consume_output=True)
161+
client.join()
146162
147163
for host_output in output:
148164
print(host_out.exit_code)

doc/clients.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ SFTP copy to/from hosts Yes No
1818
OpenSSH config parsing Not yet implemented Not yet implemented
1919
ECDSA keys support Yes Yes
2020
ED25519 keys support Yes Yes
21-
Certificate authentication Not supported Not yet implemented
21+
Certificate authentication Not supported Yes
2222
SCP functionality Yes No
2323
Keep-alive functionality Yes No
2424
=============================== ====================== ======================

doc/conf.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060

6161
# General information about the project.
6262
project = u'Parallel-SSH'
63-
copyright = u'2014-2017, P Kittenis'
63+
copyright = u'2014-2020, P Kittenis'
6464

6565
# The version info for the project you're documenting, acts as replacement for
6666
# |version| and |release|, also used in various other places throughout the

doc/quickstart.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Examples all assume a valid key is available on a running SSH agent. See `Progra
1717
Complete Example
1818
-----------------
1919

20-
Host list can contain identical hosts. Commands are executed concurrently on every host given to the client regardless.
20+
Host list can contain identical hosts. Commands are executed concurrently on every host given to the client regardless, up to pool size.
2121

2222
.. code-block:: python
2323
@@ -45,7 +45,7 @@ Output:
4545
Single Host Client
4646
====================
4747

48-
``parallel-ssh`` has a fully featured, non-blocking single host client that it uses for all its parallel commands.
48+
``parallel-ssh`` has a fully featured, asynchronous single host client that it uses for all its parallel commands.
4949

5050
Users that do not need the parallel capabilities can use the single host client for a simpler way to run asynchronous non-blocking commands on a remote host.
5151

@@ -150,7 +150,7 @@ Complete Example
150150
151151
client = ParallelSSHClient(['localhost', 'localhost'])
152152
output = client.run_command('whoami')
153-
client.join(output)
153+
client.join()
154154
155155
for host_output in output:
156156
hostname = host_output.host

examples/pssh_local.py

-61
This file was deleted.

examples/quickstart.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from pssh.clients import ParallelSSHClient, SSHClient
2+
3+
4+
hosts = ['localhost']
5+
cmd = 'uname'
6+
7+
client = ParallelSSHClient(hosts)
8+
output = client.run_command(cmd)
9+
10+
for host_out in output:
11+
for line in host_out.stdout:
12+
print(line)
13+
print("Host %s: exit code %s" % (host_out.host, host_out.exit_code))

pssh/clients/base/parallel.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -268,11 +268,10 @@ def _join(self, host_out, consume_output=False, timeout=None,
268268
encoding="utf-8"):
269269
if host_out is None:
270270
return
271-
channel = host_out.channel
272271
client = host_out.client
273272
if client is None:
274273
return
275-
client.wait_finished(channel, timeout=timeout)
274+
client.wait_finished(host_out, timeout=timeout)
276275
if consume_output:
277276
self._consume_output(host_out.stdout, host_out.stderr)
278277
return host_out

0 commit comments

Comments
 (0)