Skip to main content

Asynchronous parallel SSH library

Project description

Non-blocking, asynchronous parallel SSH client library.

Run SSH commands over many - hundreds/hundreds of thousands - number of servers asynchronously and with minimal system load on the client host.

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

License Latest Version https://travis-ci.org/ParallelSSH/parallel-ssh.svg?branch=master https://codecov.io/gh/ParallelSSH/parallel-ssh/branch/master/graph/badge.svg https://img.shields.io/pypi/wheel/parallel-ssh.svg Latest documentation

Installation

pip install parallel-ssh

Usage Example

See documentation on read the docs for more complete examples.

Run uname on two remote hosts in parallel with sudo.

from pssh.pssh_client import ParallelSSHClient

hosts = ['myhost1', 'myhost2']
client = ParallelSSHClient(hosts)

output = client.run_command('uname')
for host, host_output in output.items():
    for line in host_output.stdout:
        print(line)
Output:
Linux
Linux

Native client

Starting from version 1.2.0, a new client is supported in parallel-ssh which offers much greater performance and reduced overhead than the current default client.

The new client is based on libssh2 via the ssh2-python extension library and supports non-blocking mode natively. Binary wheel packages with libssh2 included are provided for Linux, OSX and Windows platforms and all supported Python versions.

See this post for a performance comparison of the available clients.

To make use of this new client, ParallelSSHClient can be imported from pssh.pssh2_client instead. Their respective APIs are almost identical.

The new client will become the default and will replace the current pssh.pssh_client in a new major version of the library - 2.0.0 - once remaining features have been implemented. The native client should be considered as beta status until the 2.0.0 release when it is made the default.

The current default client will remain available as an option under a new name.

For example:

from pprint import pprint
from pssh.pssh2_client import ParallelSSHClient

hosts = ['myhost1', 'myhost2']
client = ParallelSSHClient(hosts)

output = client.run_command('uname')
for host, host_output in output.items():
    for line in host_output.stdout:
        print(line)

See documentation for a feature comparison of the two clients.

Native Code Client Features

  • Highest performance and least overhead of any Python SSH libraries

  • Thread safe - makes use of native threads for blocking calls like authentication

  • Natively non-blocking utilising libssh2 via ssh2-python - no monkey patching of the Python standard library

  • Significantly reduced overhead in CPU and memory usage

Exit codes

Once either standard output is iterated on to completion, or client.join(output) is called, exit codes become available in host output. Iteration ends only when remote command has completed, though it may be interrupted and resumed at any point.

for host in output:
    print(output[host].exit_code)
Output:
0
0

The client’s join function can be used to block and wait for all parallel commands to finish:

client.join(output)

Similarly, output and exit codes are available after client.join is called:

output = client.run_command('exit 0')

# Wait for commands to complete and gather exit codes.
# Output is updated in-place.
client.join(output)
pprint(output.values()[0].exit_code)

# Output remains available in output generators
for host, host_output in output.items():
    for line in host_output.stdout:
        pprint(line)
Output:
0
<..stdout..>

There is also a built in host logger that can be enabled to log output from remote hosts. The helper function pssh.utils.enable_host_logger will enable host logging to stdout.

To log output without having to iterate over output generators, the consume_output flag can be enabled - for example:

from pssh.utils import enable_host_logger
enable_host_logger()
client.join(client.run_command('uname'), consume_output=True)
Output:
[localhost]       Linux

SFTP/SCP

SFTP is supported natively, no scp binary required.

For example to copy a local file to remote hosts in parallel:

from pssh.pssh_client import ParallelSSHClient
from pssh import utils
from gevent import joinall

utils.enable_logger(utils.logger)
hosts = ['myhost1', 'myhost2']
client = ParallelSSHClient(hosts)
cmds = client.copy_file('../test', 'test_dir/test')
joinall(cmds, raise_error=True)
Output:
Copied local file ../test to remote destination myhost1:test_dir/test
Copied local file ../test to remote destination myhost2:test_dir/test

There is similar capability to copy remote files to local ones suffixed with the host’s name with the copy_remote_file function.

Directory recursion is supported in both cases via the recurse parameter - defaults to off.

See SFTP documentation for more examples.

Design And Goals

ParallelSSH’s design goals and motivation are to provide a library for running non-blocking asynchronous SSH commands in parallel with little to no load induced on the system by doing so with the intended usage being completely programmatic and non-interactive.

To meet these goals, API driven solutions are preferred first and foremost. This frees up developers to drive the library via any method desired, be that environment variables, CI driven tasks, command line tools, existing OpenSSH or new configuration files, from within an application et al.

Scaling

Some guide lines on scaling ParallelSSH client and pool size numbers.

In general, long lived commands with little or no output gathering will scale better. Pool sizes in the multiple thousands have been used successfully with little CPU overhead in the single process running them in these use cases.

Conversely, many short lived commands with output gathering will not scale as well. In this use case, smaller pool sizes in the hundreds are likely to perform better with regards to CPU overhead in the event loop. Multiple python processes, each with its own event loop, may be used to scale this use case further as CPU overhead allows.

Gathering is highlighted here as output generation does not affect scaling. Only when output is gathered either over multiple still running commands, or while more commands are being triggered, is overhead increased.

Technical Details

To understand why this is, consider that in co-operative multi tasking, which is being used in this project via the gevent library, a co-routine (greenlet) needs to yield the event loop to allow others to execute - co-operation. When one co-routine is constantly grabbing the event loop in order to gather output, or when co-routines are constantly trying to start new short-lived commands, it causes overhead with other co-routines that also want to use the event loop.

This manifests itself as increased CPU usage in the process running the event loop and reduced performance with regards to scaling improvements from increasing pool size.

On the other end of the spectrum, long lived remote commands that generate no output only need the event loop at the start, when they are establishing connections, and at the end, when they are finished and need to gather exit codes, which results in practically zero CPU overhead at any time other than start or end of command execution.

Output generation is done remotely and has no effect on the event loop until output is gathered - output buffers are iterated on. Only at that point does the event loop need to be held.

User’s group

here is a public ParallelSSH Google group setup for this purpose - both posting and viewing are open to the public.

https://ga-beacon.appspot.com/UA-9132694-7/parallel-ssh/README.rst?pixel

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

parallel-ssh-1.2.1.post1.tar.gz (42.3 kB view details)

Uploaded Source

Built Distributions

parallel_ssh-1.2.1.post1-cp36-cp36m-win_amd64.whl (104.4 kB view details)

Uploaded CPython 3.6m Windows x86-64

parallel_ssh-1.2.1.post1-cp36-cp36m-win32.whl (95.0 kB view details)

Uploaded CPython 3.6m Windows x86

parallel_ssh-1.2.1.post1-cp35-cp35m-win_amd64.whl (103.9 kB view details)

Uploaded CPython 3.5m Windows x86-64

parallel_ssh-1.2.1.post1-cp35-cp35m-win32.whl (94.7 kB view details)

Uploaded CPython 3.5m Windows x86

parallel_ssh-1.2.1.post1-cp34-cp34m-win_amd64.whl (101.9 kB view details)

Uploaded CPython 3.4m Windows x86-64

parallel_ssh-1.2.1.post1-cp34-cp34m-win32.whl (95.5 kB view details)

Uploaded CPython 3.4m Windows x86

parallel_ssh-1.2.1.post1-cp27-cp27m-win_amd64.whl (103.1 kB view details)

Uploaded CPython 2.7m Windows x86-64

parallel_ssh-1.2.1.post1-cp27-cp27m-win32.whl (95.2 kB view details)

Uploaded CPython 2.7m Windows x86

File details

Details for the file parallel-ssh-1.2.1.post1.tar.gz.

File metadata

File hashes

Hashes for parallel-ssh-1.2.1.post1.tar.gz
Algorithm Hash digest
SHA256 0d02aabf963f6b7657dd12933a32d3ffa926b02d81c94915977e14f7b6494bc8
MD5 cef1494410b6b6ccd819a29dd16494ec
BLAKE2b-256 aa072a403d80a5d73bf88bc837bb741978b80caec17894321fbebdff8ba379d8

See more details on using hashes here.

File details

Details for the file parallel_ssh-1.2.1.post1-cp36-cp36m-win_amd64.whl.

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post1-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 60c9e8fb91e8c3531fddb130b90b23a1ca1c01a5f881e2928461c64ff578e893
MD5 1b674430f27786879577ac7b2b5d12dc
BLAKE2b-256 fb9830b934dbfef8e8108c1c3e5366d62cc28343f4330ae2aeee471bc46262d6

See more details on using hashes here.

File details

Details for the file parallel_ssh-1.2.1.post1-cp36-cp36m-win32.whl.

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post1-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 75527a3ba8578dbe093f4f26701c392b68c425aa31ea297c970013cd71b5ee7b
MD5 af863b1d0da3cf6b313f7dc0d5837799
BLAKE2b-256 d45086c5d92e6498f9386019dbcdbb71db3efa8685d280ed67df7d40dd9c9166

See more details on using hashes here.

File details

Details for the file parallel_ssh-1.2.1.post1-cp36-cp36m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post1-cp36-cp36m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 5f7d2c5ae389b2f12ef903382301674bfb96741806224712d6d0c997227c869a
MD5 35b39d73ec9e596307831fcd3e658f76
BLAKE2b-256 98c7d15d81cc41b980d62c5529a34cf265009461bea8cdad9b6494c4d8678111

See more details on using hashes here.

File details

Details for the file parallel_ssh-1.2.1.post1-cp35-cp35m-win_amd64.whl.

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post1-cp35-cp35m-win_amd64.whl
Algorithm Hash digest
SHA256 6129dd20f0be1e75d546ecd5040ed55db521ac0fc030369b1c3fe8ebb60f1963
MD5 2028c157424cc53b5c957f9f4bd98a7a
BLAKE2b-256 11ac75c41c1dbad0b58f9142ff1986d2073d2e70c2954de39b4d286760e9a8bf

See more details on using hashes here.

File details

Details for the file parallel_ssh-1.2.1.post1-cp35-cp35m-win32.whl.

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post1-cp35-cp35m-win32.whl
Algorithm Hash digest
SHA256 e350fdd2794a347207b4f2825aa2d356799e54e6ffb582b2f62e58d0c12350da
MD5 05ae115d3c43b0681baf7bdb0e6cff49
BLAKE2b-256 3d38beec08e92ef97a25fac3ca2e0ba53ae3e3cb971ef3b7ed52bbb2f9893a8d

See more details on using hashes here.

File details

Details for the file parallel_ssh-1.2.1.post1-cp35-cp35m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post1-cp35-cp35m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 364ce978905e133182ca516a11bb4fb65af38bc10ee614bf7971b6be8489a817
MD5 ee4f7210184d7644bb2cd7af8aeaa9d4
BLAKE2b-256 3f4416fed7537b05a3e83dcce0580f301c724d44cc568c066c595e736b9a6e38

See more details on using hashes here.

File details

Details for the file parallel_ssh-1.2.1.post1-cp34-cp34m-win_amd64.whl.

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post1-cp34-cp34m-win_amd64.whl
Algorithm Hash digest
SHA256 c918307c60c64b9bc36c5e0ae6bf822cccb087a050913b178a22ca0801d040cf
MD5 0176099e4eb7b0df60c5ffa4bdce06bd
BLAKE2b-256 b4e92174c39fdf077fef44e19ab33b62728bb56363d27618a2266aaa515408b9

See more details on using hashes here.

File details

Details for the file parallel_ssh-1.2.1.post1-cp34-cp34m-win32.whl.

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post1-cp34-cp34m-win32.whl
Algorithm Hash digest
SHA256 511f3273b5d59c90234085fdd216c232eaea9bce856bd678ad8c4e9fb9513c16
MD5 f6a3e03a06a452e8143dd98d8f292794
BLAKE2b-256 19abac640ab633e3cbbe87490a3348ff39df5cb2062b3a9266140d57bdb8212a

See more details on using hashes here.

File details

Details for the file parallel_ssh-1.2.1.post1-cp34-cp34m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post1-cp34-cp34m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 dc48a6619faafb2bb322f0e6adb720fb9a9c09b15fa3d91cb847f2dfdfbaca58
MD5 f0e4d6376622ce53ae6f14878ebd4779
BLAKE2b-256 cbb1219f9b415a6370d5f290190fec78222e97ebffad8360e8a9a53e9e809e7f

See more details on using hashes here.

File details

Details for the file parallel_ssh-1.2.1.post1-cp33-cp33m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post1-cp33-cp33m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 9836fc4297de3b4a572e18d7c9c602b17723f950300073599359a2072533c985
MD5 5bb3166817ed1955e67bc22ca83b2493
BLAKE2b-256 6c6a1ecd5b273ab818a2a9d517afb610d2b93cadbe2e6e9908efef75e8363f0e

See more details on using hashes here.

File details

Details for the file parallel_ssh-1.2.1.post1-cp27-cp27mu-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post1-cp27-cp27mu-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 d93482e72baab3dff1a85d1635e68d1ba717d64b83d58e373b6d01e82cf951e4
MD5 f6a2523e96fdb9a3e424ee7f6d49300f
BLAKE2b-256 a20db99c2b29b373ffd3618a4a530ccf7d75e58bfdf696e771333752cec81dc1

See more details on using hashes here.

File details

Details for the file parallel_ssh-1.2.1.post1-cp27-cp27m-win_amd64.whl.

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post1-cp27-cp27m-win_amd64.whl
Algorithm Hash digest
SHA256 ba4ada1f76f8e9e7c5d4c65a122f1f68deb8cd8f0a80175be375952b262c07e1
MD5 b7a490f4f19ed83f997ce00635070338
BLAKE2b-256 7133c07eab42c0154bdf92e8ed446a8c6a1022b59e27f8c032e7b1911c320094

See more details on using hashes here.

File details

Details for the file parallel_ssh-1.2.1.post1-cp27-cp27m-win32.whl.

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post1-cp27-cp27m-win32.whl
Algorithm Hash digest
SHA256 a69493e7885c7e6193b80799c0825d1c9358fe3db8b7a0229ffe8d90e73bf506
MD5 ed6423b71953519ae9483c302efb39a9
BLAKE2b-256 6e62e54fa239ea3a080ad1a80210baa71a9e4609f209cb2f13e6e8a29b8f486d

See more details on using hashes here.

File details

Details for the file parallel_ssh-1.2.1.post1-cp27-cp27m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post1-cp27-cp27m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 35bc102909197ee252e6de2bf8f4f9d9006cb578640aa0a3a6dfe7e73aa1b0c1
MD5 964d875bbfa974eabb500c653108c1a4
BLAKE2b-256 0cfb06479ea94103a8acdfecd9fceadd0003748d6bcf4720dab49f8f9ccc20e6

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page