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://ci.appveyor.com/api/projects/status/github/parallelssh/parallel-ssh?svg=true&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 __future__ import print_function

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 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 wait for all commands in output object to finish:

client.join(output)

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

from pprint import pprint

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 must 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

SFTP is supported natively.

To copy a local file to remote hosts in parallel:

from pssh.pssh_client import ParallelSSHClient
from pssh.utils import enable_logger, logger
from gevent import joinall

enable_logger(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

There 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.post2.tar.gz (88.0 kB view details)

Uploaded Source

Built Distributions

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

Uploaded CPython 3.6m Windows x86-64

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

Uploaded CPython 3.6m Windows x86

parallel_ssh-1.2.1.post2-cp35-cp35m-win_amd64.whl (104.0 kB view details)

Uploaded CPython 3.5m Windows x86-64

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

Uploaded CPython 3.5m Windows x86

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

Uploaded CPython 3.4m Windows x86-64

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

Uploaded CPython 3.4m Windows x86

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

Uploaded CPython 2.7m Windows x86-64

parallel_ssh-1.2.1.post2-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.post2.tar.gz.

File metadata

File hashes

Hashes for parallel-ssh-1.2.1.post2.tar.gz
Algorithm Hash digest
SHA256 542ad7ae89fe0441e76a114609574cdd1da6578c849a0bcf1e5244acda9d6924
MD5 1e74f68eb0d44abb6b7e9223e39bfc4f
BLAKE2b-256 8c4702c079185cabc85157e003f355d54f36df3131529383fc8e39711a38015e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post2-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 ba762ba5c483ccabf736e42fab95729e54f2a19484e13b9dda39daff2a6364c7
MD5 eb539028fbe405f69b7826fc749456e8
BLAKE2b-256 99af2ba24bb244e1e4f19e961efde6933ec8447823be404456c098c0e1bd8a73

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post2-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 7e33df2a4e6ec052494401d24462fff99de0584abfa21c9deb8f5196652671c7
MD5 395228a8ea58f65adf76ca60b59280c0
BLAKE2b-256 a7c12d88a52319eb4338ef970f1dde88a636a365a79256d6745347e8ccc95c63

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post2-cp36-cp36m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 96269475f1b89893a7cc1028da4d0d7847be2720cb2c84620c9285e027f0030d
MD5 30a5a75cbd6b5dc33a8b758452cacdf9
BLAKE2b-256 3b95cb58803b912f4ef9097c66efca1acd5bbf0f982630ec26be478d1b0b02f8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post2-cp35-cp35m-win_amd64.whl
Algorithm Hash digest
SHA256 548f7b4a42d19a2351b4ec8517e6038bc7771e27eec6a1756c4ddb8177daf48c
MD5 a50a3b6d283ceef8876f078167056b46
BLAKE2b-256 af4a845240851969b84854310aa5ad583f5ec77d0b45172804b4c60a8dfe3f19

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post2-cp35-cp35m-win32.whl
Algorithm Hash digest
SHA256 8035b3f8935fdbeb81d65b6064af444f40225ca8f84e579246be9972f4abf541
MD5 9c90c4c209d9ebecaa34b0976b45f312
BLAKE2b-256 55df4c48ada43a5e23f965baaaf512b9330d4d529503692219e9b657698ec004

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post2-cp35-cp35m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 b0b106052bd0f97007b53e1f17de48ccd805e674c7ac73d778b6c7154cc89e51
MD5 424cd000e73ceaa197146fd29423c715
BLAKE2b-256 4a9e5ba77a1185b1d8c8d5dccb975d5ef76860c07dafd73473e029f35673faf3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post2-cp34-cp34m-win_amd64.whl
Algorithm Hash digest
SHA256 03681575e463fb8d540fc38705ecc4aa8a1fec041660a79f0e1da52687081482
MD5 c87228a17a62232a286c4e5e0f47a373
BLAKE2b-256 5940c339e880e1a0558031682a9906ca1a5645cd2d3631cdeac31ff884f07e89

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post2-cp34-cp34m-win32.whl
Algorithm Hash digest
SHA256 4f8a1cf95c462f6114dda5b73c9e2a1b037e3cfe656b098ba6bb60303c85cdc8
MD5 d34bbaa23e7b3024f3a69224d0ed90c4
BLAKE2b-256 7f7b1d4c47035e4062b336896395b18c9cdc61f38e75be66c84c616cbd23843a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post2-cp34-cp34m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 a4cf5de764efa200b82107fb5e4d5ff34746390b5415e1fd0209970dd629db19
MD5 a210dd9b0e5d0d83e18a3b2264bc1c90
BLAKE2b-256 f1ba21b583e0698b6a4bfef825ae94161b4605b0835c1343d8330f2ec9051fde

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post2-cp33-cp33m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 194fdd43afe1a7ded43211db3fcd076822166b67d81dade963717895196b3c9f
MD5 78ca89afdf9498ee73a29ecf5df05640
BLAKE2b-256 1199c94662fc7afdcccab60f31ad793a87acc15d98a9301b1446292ebc0e622d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post2-cp27-cp27mu-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 65b5c87f3c6d89bd3583d5370747d0cfd5b7e599f33a849c2a580ef5ca882f3c
MD5 1cd0408b3ff39edd3688dfa8bad1ac51
BLAKE2b-256 741daf8d6e201c352815f43354b200783d93b12843b2d39427fa470f350ed696

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post2-cp27-cp27m-win_amd64.whl
Algorithm Hash digest
SHA256 2098193cdb016e0f226dcaf2e3cd5bf792dde4e0147038a93613e15b275cb55d
MD5 d8942a2803d838b5629e469fcd29348f
BLAKE2b-256 07176e6fa01d8873902ddf5acbd2ad1b6af218319eff947f8b0e1c78ccc3c7a3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post2-cp27-cp27m-win32.whl
Algorithm Hash digest
SHA256 f8e6107077b9886a0c290a29dd8c88362d77b9743870c2f1fdb78023767f64fe
MD5 338c1a2d692069b0cc34fe3bf56d4c63
BLAKE2b-256 1e499773c19d6e77fd065a2cbcd98803b3039903f48fbeef2da3397a15bd575c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for parallel_ssh-1.2.1.post2-cp27-cp27m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 fcaaf362250689f9ad363021a404d963cce2f9b6257333d81df0e5cb40de38e4
MD5 4f684d8f7a44e341a3e06da107f39dea
BLAKE2b-256 b15c5434a81e2b8ec9acdc3be537801798104429ea0e98c5135eab4c97df73ab

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