First, make sure that
parallel-ssh is installed.
ParallelSSH uses gevent’s monkey patching to enable asynchronous use of the Python standard library’s network I/O.
Make sure that ParallelSSH imports come before any other imports in your code. Otherwise, patching may not be done before the standard library is loaded which will then cause ParallelSSH to block.
If you are seeing messages like
This operation would block forever, this is the cause.
The most basic usage of
parallel-ssh is, unsurprisingly, to run a command on multiple hosts in parallel.
Examples in this documentation will be using
2.7 and below.
Make a list or other iterable of the hosts to run on:
from __future__ import print_function from pssh.pssh_client import ParallelSSHClient hosts = ['host1', 'host2', 'host3', 'host4']
host4 are valid host names. IP addresses may also be used.
Create a client for these hosts:
client = ParallelSSHClient(hosts)
The client object can, and should, be reused. Existing connections to hosts will remain alive as long as the client object is kept alive. Subsequent commands to the same host(s) will reuse their existing connection and benefit from much faster response times.
Now one or more commands can be run via the client:
output = client.run_command('whoami')
Once the call to
run_command returns, the command has started executing in parallel.
Output is keyed by host and contains a host output object. From that, SSH output is available.
Standard output, aka
for line in output['host1'].stdout: print(line)
<your username here>
There is nothing special needed to ensure output is available.
Please note that retrieving all of a command’s standard output by definition requires that the command has completed.
stdout for any host to completion will therefor block until that host’s command has completed unless interrupted.
stdout is a generator. Iterating over it will consume the remote standard output stream via the network as it becomes available. To retrieve all of stdout can wrap it with list, per below.
stdout = list(output['host1'].stdout)
This will store the entirety of stdout into memory and may exhaust available memory if command output is large enough.
Exit codes are available on the host output object.
First, ensure that all commands have finished and exit codes gathered by joining on the output object, then iterate over all host’s output to print their exit codes.
client.join(output) for host, host_output in output.items(): print("Host %s exit code: %s" % (host, host_output.exit_code))
- Host output class documentation.
parallel-ssh will use an available SSH agent’s credentials to login to hosts via private key authentication.
User/password authentication can be used by providing user name and password credentials:
client = ParallelSSHClient(hosts, user='my_user', password='my_pass')
It is also possible to programmatically use a private key for authentication.
The helper function
load_private_key is provided to easily load all possible key types. It takes either a file path or a file-like object.
from pssh.pssh_client import ParallelSSHClient from pssh.utils import load_private_key pkey = load_private_key('my_pkey.pem') client = ParallelSSHClient(hosts, pkey=pkey)
There is a built in host logger that can be enabled to automatically log output from remote hosts. This requires the
consume_output flag to be enabled on
The helper function
pssh.utils.enable_host_logger will enable host logging to standard output, for example:
from pssh.utils import enable_host_logger enable_host_logger() output = client.run_command('uname') client.join(output, consume_output=True)
Along with standard output and error, input is also available on the host output object. It can be used to send input to the remote host where required, for example password prompts or any other prompt requiring user input.
stdin attribute is a file-like object giving access to the remote stdin channel that can be written to:
output = client.run_command('read') stdin = output['localhost'].stdin stdin.write("writing to stdin\\n") stdin.flush() for line in output['localhost'].stdout: print(line)
writing to stdin
parallel-ssh will fail early on any errors connecting to hosts, whether that be connection errors such as DNS resolution failure or unreachable host, SSH authentication failures or any other errors.
stop_on_errors flag is provided to tell the client to go ahead and attempt the command(s) anyway and return output for all hosts, including the exception on any hosts that failed:
output = client.run_command('whoami', stop_on_errors=False)
With this flag, the
exception attribute will contain the exception on any failed hosts, or
client.join(output) for host, host_output in output.items(): print("Host %s: exit code %s, exception %s" % ( host, host_output.exit_code, host_output.exception))
host1: 0, None host2: None, AuthenticationException <..>
Possible exceptions can be found in