Skip to content

Commit 08c7891

Browse files
author
Dan
committed
Updated readme, docstrings. Changes for readability
1 parent 7aaccd8 commit 08c7891

File tree

3 files changed

+76
-45
lines changed

3 files changed

+76
-45
lines changed

README.rst

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,23 +46,38 @@ Run ``ls`` on two remote hosts in parallel with ``sudo``.
4646

4747
::
4848

49-
from __future__ import print_function
50-
49+
from pprint import pprint
5150
from pssh import ParallelSSHClient
51+
5252
hosts = ['myhost1', 'myhost2']
5353
client = ParallelSSHClient(hosts)
5454
output = client.run_command('ls -ltrh /tmp/', sudo=True)
55-
print(output)
56-
{'myhost1': {'exit_code': None, 'stdout': <generator>, 'stderr': <generator>, 'channel': <channel>, 'cmd' : <greenlet>, 'exception' : None},
57-
'myhost2': {'exit_code': None, 'stdout': <generator>, 'stderr': <generator>, 'channel': <channel>, 'cmd' : <greenlet>, 'exception' : None}}
55+
pprint(output)
56+
{'myhost1':
57+
host=myhost1
58+
cmd=<Greenlet>
59+
channel=<channel>
60+
stdout=<generator>
61+
stderr=<generator>
62+
stdin=<channel>
63+
exception=None
64+
'myhost2':
65+
host=myhost2
66+
cmd=<Greenlet>
67+
channel=<channel>
68+
stdout=<generator>
69+
stderr=<generator>
70+
stdin=<channel>
71+
exception=None
72+
}
5873

5974
Stdout and stderr buffers are available in output. Iterating on them can be used to get output as it becomes available. Iteration ends *only when command has finished*, though it may be interrupted and resumed at any point.
6075

6176
::
6277

6378
for host in output:
64-
for line in output[host]['stdout']:
65-
print("Host %s - output: %s" % (host, line))
79+
for line in output[host].stdout:
80+
pprint("Host %s - output: %s" % (host, line))
6681
Host myhost1 - output: drwxr-xr-x 6 xxx xxx 4.0K Jan 1 00:00 xxx
6782
Host myhost1 - output: <..>
6883
Host myhost2 - output: drwxr-xr-x 6 xxx xxx 4.0K Jan 1 00:00 xxx
@@ -73,7 +88,7 @@ Exit codes become available once stdout/stderr is iterated on or ``client.join(o
7388
::
7489

7590
for host in output:
76-
print(output[host]['exit_code'])
91+
print(output[host].exit_code)
7792
0
7893
0
7994

@@ -84,9 +99,9 @@ The client's ``join`` function can be used to block and wait for all parallel co
8499
Similarly, exit codes are available after ``client.join`` is called::
85100

86101
output = client.run_command('exit 0')
87-
# Block and gather exit codes. Output variable is updated in-place
102+
# Block and gather exit codes. Output is updated in-place
88103
client.join(output)
89-
print(output[client.hosts[0]]['exit_code'])
104+
pprint(output[client.hosts[0]].exit_code)
90105
0
91106

92107
.. note::

pssh/output.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from os import linesep
2+
13
class HostOutput(dict):
24
__slots__ = ('host', 'cmd', 'channel', 'stdout', 'stderr', 'stdin', 'exit_code', 'exception')
35

@@ -25,6 +27,9 @@ def update(self, update_dict):
2527
object.__setattr__(self, key, update_dict[key])
2628

2729
def __repr__(self):
28-
return "host=%s, cmd=%s, channel=%s, stdout=%s, stderr=%s, stdin=%s, \
29-
exception=%s" % (self.host, self.cmd, self.channel, self.stdout, self.stdin,
30-
self.stderr, self.exception,)
30+
return "{linesep}\thost={host}{linesep}" \
31+
"\tcmd={cmd}{linesep}\tchannel={channel}{linesep}" \
32+
"\tstdout={stdout}{linesep}\tstderr={stderr}{linesep}\tstdin={stdin}{linesep}\
33+
\texception={exception}{linesep}".format(
34+
host=self.host, cmd=self.cmd, channel=self.channel, stdout=self.stdout,
35+
stdin=self.stdin, stderr=self.stderr, exception=self.exception, linesep=linesep,)

pssh/pssh_client.py

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ def __init__(self, hosts,
210210
211211
For individual commands the status of channel can be checked ::
212212
213-
output[host]['channel'].closed
213+
output[host].channel.closed
214214
False
215215
216216
which returns ``True`` if command has finished.
@@ -234,7 +234,7 @@ def __init__(self, hosts,
234234
235235
client.get_exit_codes(output)
236236
for host in output:
237-
print(output[host]['exit_code'])
237+
print(output[host].exit_code)
238238
0
239239
0
240240
@@ -243,7 +243,7 @@ def __init__(self, hosts,
243243
.. code-block:: python
244244
245245
for host in output:
246-
for line in output[host]['stdout']:
246+
for line in output[host].stdout:
247247
print(line)
248248
[myhost1] ls: cannot access /tmp/aasdfasdf: No such file or directory
249249
[myhost2] ls: cannot access /tmp/aasdfasdf: No such file or directory
@@ -406,18 +406,22 @@ def run_command(self, *args, **kwargs):
406406
**Print stdout for each command**
407407
408408
.. code-block:: python
409-
409+
410+
from __future__ import print_function
411+
410412
for host in output:
411-
for line in output[host]['stdout']:
413+
for line in output[host].stdout:
412414
print(line)
413415
414416
**Get exit codes after command has finished**
415417
416418
.. code-block:: python
417-
419+
420+
from __future__ import print_function
421+
418422
client.get_exit_codes(output)
419423
for host in output:
420-
print(output[host]['exit_code'])
424+
print(output[host].exit_code)
421425
0
422426
0
423427
@@ -426,9 +430,9 @@ def run_command(self, *args, **kwargs):
426430
.. code-block:: python
427431
428432
client.join(output)
429-
print(output[host]['exit_code'])
433+
print(output[host].exit_code)
430434
0
431-
for line in output[host]['stdout']:
435+
for line in output[host].stdout:
432436
print(line)
433437
434438
**Run with sudo**
@@ -448,9 +452,11 @@ def run_command(self, *args, **kwargs):
448452
`Enabling Host Logger` above.
449453
450454
.. code-block:: python
451-
455+
456+
from __future__ import print_function
457+
452458
for host in output:
453-
stdout = list(output[host]['stdout'])
459+
stdout = list(output[host]stdout)
454460
print("Complete stdout for host %s is %s" % (host, stdout,))
455461
456462
**Command with per-host arguments**
@@ -544,7 +550,7 @@ def run_command(self, *args, **kwargs):
544550
print("Started %s commands in %s" % (len(cmds), end-start,))
545551
start = datetime.datetime.now()
546552
for _output in output:
547-
for line in _output[host]['stdout']:
553+
for line in _output[host].stdout:
548554
print(line)
549555
end = datetime.datetime.now()
550556
print("All commands finished in %s" % (end-start,))
@@ -560,12 +566,15 @@ def run_command(self, *args, **kwargs):
560566
561567
::
562568
563-
{'myhost1': {'exit_code': exit code if ready else None,
564-
'channel' : SSH channel of command,
565-
'stdout' : <iterable>,
566-
'stderr' : <iterable>,
567-
'cmd' : <greenlet>},
568-
'exception' : None}
569+
{'myhost1':
570+
host=myhost1
571+
exit_code=exit code if ready else None
572+
channel=SSH channel of command
573+
stdout=<iterable>
574+
stderr=<iterable>
575+
stdin=<file-like writable channel>
576+
cmd=<greenlet>
577+
exception=None}
569578
570579
**Do not stop on errors, return per-host exceptions in output**
571580
@@ -577,24 +586,26 @@ def run_command(self, *args, **kwargs):
577586
578587
.. code-block:: python
579588
580-
{'myhost1': {'exit_code': None,
581-
'channel' : None,
582-
'stdout' : None,
583-
'stderr' : None,
584-
'cmd' : None,
585-
'exception' : ConnectionErrorException(
586-
"Error connecting to host '%s:%s' - %s - retry %s/%s",
587-
host, port, 'Connection refused', 3, 3)}}
589+
{'myhost1':
590+
host=myhost1
591+
exit_code=None
592+
channel=None
593+
stdout=None
594+
stderr=None
595+
cmd=None
596+
exception=ConnectionErrorException(
597+
"Error connecting to host '%s:%s' - %s - retry %s/%s",
598+
host, port, 'Connection refused', 3, 3)}
588599
589600
**Using stdin**
590601
591602
.. code-block:: python
592603
593604
output = client.run_command('read')
594-
stdin = output['localhost']['stdin']
605+
stdin = output['localhost'].stdin
595606
stdin.write("writing to stdin\\n")
596607
stdin.flush()
597-
for line in output['localhost']['stdout']:
608+
for line in output['localhost'].stdout:
598609
print(line)
599610
600611
writing to stdin
@@ -682,7 +693,7 @@ def get_output(self, cmd, output):
682693
683694
output = client.get_output()
684695
for host in output:
685-
for line in output[host]['stdout']:
696+
for line in output[host].stdout:
686697
print(line)
687698
<stdout>
688699
# Get exit code after command has finished
@@ -731,7 +742,7 @@ def join(self, output):
731742
and retrieve exit codes"""
732743
for host in output:
733744
output[host].cmd.join()
734-
if output[host].channel:
745+
if output[host].channel is not None:
735746
output[host].channel.recv_exit_status()
736747
self.get_exit_codes(output)
737748

@@ -743,7 +754,7 @@ def finished(self, output):
743754
"""
744755
for host in output:
745756
chan = output[host]['channel']
746-
if chan and not chan.closed:
757+
if chan is not None and not chan.closed:
747758
return False
748759
return True
749760

@@ -883,7 +894,7 @@ def _copy_remote_file(self, host, remote_file, local_file, recurse,
883894
remote_file, file_w_suffix, recurse=recurse)
884895

885896
def _make_ssh_client(self, host):
886-
if not host in self.host_clients or not self.host_clients[host]:
897+
if not host in self.host_clients or self.host_clients[host] is None:
887898
_user, _port, _password, _pkey = self._get_host_config_values(host)
888899
self.host_clients[host] = SSHClient(
889900
host, user=_user, password=_password, port=_port, pkey=_pkey,

0 commit comments

Comments
 (0)