Asynchronous parallel SSH client library.

Overview

parallel-ssh

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 clients with extremely high performance, making use of C libraries.

License Latest Version https://circleci.com/gh/ParallelSSH/parallel-ssh/tree/master.svg?style=svg Latest documentation

Installation

pip install parallel-ssh

An update to pip may be needed to be able to install binary wheels.

pip install -U pip
pip install parallel-ssh

Usage Example

See documentation on read the docs for more complete examples.

Run uname on two hosts in parallel.

from pssh.clients import ParallelSSHClient

hosts = ['localhost', 'localhost']
client = ParallelSSHClient(hosts)

output = client.run_command('uname')
for host_output in output:
    for line in host_output.stdout:
        print(line)
    exit_code = host_out.exit_code
Output:
Linux
Linux

Single Host Client

Single host client with similar API can be used if parallel functionality is not needed.

from pssh.clients import SSHClient

host = 'localhost'
cmd = 'uname'
client = SSHClient(host)

host_out = client.run_command(cmd)
for line in host_out.stdout:
    print(line)
exit_code = host_out.exit_code

Questions And Discussion

Github discussions can be used to discuss, ask questions and share ideas regarding the use of parallel-ssh.

Native clients

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.

See this post for a performance comparison of different Python SSH libraries.

Alternative clients based on ssh-python (libssh) are also available under pssh.clients.ssh. See client documentation for a feature comparison of the available clients in the library.

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.

Native Code Client Features

  • Highest performance and least overhead of any Python SSH library
  • Thread safe - makes use of native threads for CPU bound calls like authentication
  • Natively asynchronous utilising C libraries implementing the SSH protocol
  • Significantly reduced overhead in CPU and memory usage

Why This Library

Because other options are either immature, unstable, lacking in performance or all of the aforementioned.

Certain other self-proclaimed leading Python SSH libraries leave a lot to be desired from a performance and stability point of view, as well as suffering from a lack of maintenance with hundreds of open issues, unresolved pull requests and inherent design flaws.

The SSH libraries parallel-ssh uses are, on the other hand, long standing mature C libraries in libssh2 and libssh that have been in production use for decades and are part of some of the most widely distributed software available today - Git itself, OpenSSH, Curl and many others.

These low level libraries are far better placed to provide the maturity, stability and performance needed from an SSH client for production use.

parallel-ssh provides easy to use SSH clients that hide the complexity, while offering stability and native code levels of performance and as well as the ability to scale to hundreds or more concurrent hosts.

See alternatives for a more complete comparison of alternative SSH libraries, as well as performance comparisons mentioned previously.

Waiting for Completion and Exit Codes

The client's join function can be used to wait for all commands in output to finish.

After join returns, commands have finished and all output can be read without blocking.

Once either standard output is iterated on to completion, or client.join() 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 - see join and output timeouts documentation.

HostOutput.exit_code is a dynamic property and will return None when exit code is not ready, meaning command has not finished, or unavailable due to error.

Once all output has been gathered exit codes become available even without calling join as per previous examples.

output = client.run_command('uname')

client.join()

for host_out in output:
    for line in host_out.stdout:
        print(line)
    print(host_out.exit_code)
Output:
Linux
0
Linux
0

Similarly, exit codes are available after client.join() without reading output.

output = client.run_command('uname')

client.join()

for host_output in output:
    print(host_out.exit_code)
Output:
0
0

Built in Host Output Logger

There is also a built in host logger that can be enabled to log output from remote hosts for both stdout and stderr. 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.run_command('uname')
client.join(consume_output=True)
Output:
[localhost]       Linux

SCP

SCP is supported - native client only - and provides the best performance for file copying.

Unlike with the SFTP functionality, remote files that already exist are not overwritten and an exception is raised instead.

Note that enabling recursion with SCP requires server SFTP support for creating remote directories.

To copy a local file to remote hosts in parallel with SCP:

from pssh.clients import ParallelSSHClient
from gevent import joinall

hosts = ['myhost1', 'myhost2']
client = ParallelSSHClient(hosts)
cmds = client.scp_send('../test', 'test_dir/test')
joinall(cmds, raise_error=True)

See SFTP and SCP documentation for more examples.

SFTP

SFTP is supported in the native client.

To copy a local file to remote hosts in parallel:

from pssh.clients 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 with configurable file names via the copy_remote_file function.

In addition, per-host configurable file name functionality is provided for both SFTP and SCP - see documentation.

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

See SFTP and SCP documentation for more examples.

https://ga-beacon.appspot.com/UA-9132694-7/parallel-ssh/README.rst?pixel
Comments
  • Reading from stdout with timeout set can raise Timeout before it has occurred

    Reading from stdout with timeout set can raise Timeout before it has occurred

    Issue 1: I am using native client and my code is hosts = ['localhost'] client = ParallelSSHClient(hosts) output = client.run_command('uname;pwd',return_list = True) client.join(output,timeout = 5)

    ###Expected behaviour#### It should execute and return the output of commands

    ###Actual Behaviour#### getting timeout exception

    The same timeout when i am using with run_command its working fine but with join method its failing Can you explain on what is difference between timeout use with run_command vs timeout use in join method

    Issue 2: What will be the case if i have entered host name wrong hosts = ['localhost','wrong_host_name'] output = client.run_command('uname;sleep 10;pwd',return_list = True,timeout = 5)

    ###Expected behaviour#### for localhost : print uname and timeout after that for wrong_host_name : show exception (As Expected)

    ###Actual Behaviour### for localhost : print uname --> sleep for 10 --> print pwd for wrong_host_name : wait for 10 sec to connect and after that throw exception

    Please help me understand on how timeouts is working for

    1. ParallelSSHClient
    2. run_command
    3. join

    Issue 3: If any host name is wrong in the list and I am not using any timeout throughout the script client.join(output) is stuck indefinitely

    Thanks

    bug 
    opened by dharam1 33
  • Client password authentication does not work on OpenSSH server versions < 7.0

    Client password authentication does not work on OpenSSH server versions < 7.0

    Bug report:

    I have a remote host (say as some IP ip1). I can connect to it:

    • Via the Paramiko based Parallel Client (pssh.clients.miko.parallel.ParallelSSHClient).
        from pssh.clients.miko.parallel import ParallelSSHClient
        hostConfig = {
                                "ip1":{
                                           "user":"....",
                                           "password":"...."
                                },
                                "ip2:{
                                           "user":"....",
                                           "password":"...."}
        }
        cl = ParallelSSHClient(list(hostConfig.keys()),host_config=hostConfig)
        cl.run_command("ls")
        # I get correct output.
    
    
    • Via the regular Paramiko SSHClient also.
    • Via the linux ssh command.

    But using the Native parallel client is giving errors

    Steps to reproduce: (Same steps as for Paramiko parallel client code above, just replace the import)

        from pssh.clients.native.parallel import ParallelSSHClient
        hostConfig = {
                                "ip1":{
                                           "user":"....",
                                           "password":"...."
                                },
                                "ip2:{
                                           "user":"....",
                                           "password":"...."}
        }
        cl = ParallelSSHClient(list(hostConfig.keys()),host_config=hostConfig)
        cl.run_command("ls")
        # Waits a few minutes, then gives auth errors.
    

    Expected behaviour: Give the outputs of commands.

    Actual behaviour:

    Gives a whole bunch of authentication errors:

    Traceback (most recent call last):
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 277, in auth
        self._identity_auth()
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 259, in _identity_auth
        raise AuthenticationException("No authentication methods succeeded")
    pssh.exceptions.AuthenticationException: No authentication methods succeeded
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 286, in _password_auth
        self.session.userauth_password(self.user, self.password)
      File "ssh2/session.pyx", line 266, in ssh2.session.Session.userauth_password
      File "ssh2/utils.pyx", line 131, in ssh2.utils.handle_error_codes
    ssh2.exceptions.AuthenticationError
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 192, in _init
        self.auth()
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 282, in auth
        self._password_auth()
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 288, in _password_auth
        raise AuthenticationException("Password authentication failed")
    pssh.exceptions.AuthenticationException: Password authentication failed
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 277, in auth
        self._identity_auth()
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 259, in _identity_auth
        raise AuthenticationException("No authentication methods succeeded")
    pssh.exceptions.AuthenticationException: No authentication methods succeeded
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 286, in _password_auth
        self.session.userauth_password(self.user, self.password)
      File "ssh2/session.pyx", line 266, in ssh2.session.Session.userauth_password
      File "ssh2/utils.pyx", line 131, in ssh2.utils.handle_error_codes
    ssh2.exceptions.AuthenticationError
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 192, in _init
        self.auth()
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 282, in auth
        self._password_auth()
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 288, in _password_auth
        raise AuthenticationException("Password authentication failed")
    pssh.exceptions.AuthenticationException: Password authentication failed
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 277, in auth
        self._identity_auth()
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 259, in _identity_auth
        raise AuthenticationException("No authentication methods succeeded")
    pssh.exceptions.AuthenticationException: No authentication methods succeeded
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 286, in _password_auth
        self.session.userauth_password(self.user, self.password)
      File "ssh2/session.pyx", line 266, in ssh2.session.Session.userauth_password
      File "ssh2/utils.pyx", line 131, in ssh2.utils.handle_error_codes
    ssh2.exceptions.AuthenticationError
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 192, in _init
        self.auth()
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 282, in auth
        self._password_auth()
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 288, in _password_auth
        raise AuthenticationException("Password authentication failed")
    pssh.exceptions.AuthenticationException: Password authentication failed
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/parallel.py", line 223, in run_command
        greenlet_timeout=greenlet_timeout)
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/base_pssh.py", line 96, in run_command
        self.get_output(cmd, output, timeout=greenlet_timeout)
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/base_pssh.py", line 141, in get_output
        (channel, host, stdout, stderr, stdin) = cmd.get(timeout=timeout)
      File "src/gevent/greenlet.py", line 709, in gevent._greenlet.Greenlet.get
      File "src/gevent/greenlet.py", line 317, in gevent._greenlet.Greenlet._raise_exception
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/gevent/_compat.py", line 47, in reraise
        raise value.with_traceback(tb)
      File "src/gevent/greenlet.py", line 766, in gevent._greenlet.Greenlet.run
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/parallel.py", line 237, in _run_command
        raise ex
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/parallel.py", line 230, in _run_command
        self._make_ssh_client(host)
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/parallel.py", line 387, in _make_ssh_client
        keepalive_seconds=self.keepalive_seconds)
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 132, in __init__
        THREAD_POOL.apply(self._init)
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/gevent/pool.py", line 159, in apply
        return self.spawn(func, *args, **kwds).get()
      File "src/gevent/event.py", line 268, in gevent._event.AsyncResult.get
      File "src/gevent/event.py", line 296, in gevent._event.AsyncResult.get
      File "src/gevent/event.py", line 286, in gevent._event.AsyncResult.get
      File "src/gevent/event.py", line 266, in gevent._event.AsyncResult._raise_exception
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/gevent/_compat.py", line 47, in reraise
        raise value.with_traceback(tb)
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/gevent/threadpool.py", line 281, in _worker
        value = func(*args, **kwargs)
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 195, in _init
        return self._connect_init_retry(retries)
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 174, in _connect_init_retry
        return self._init(retries=retries)
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 195, in _init
        return self._connect_init_retry(retries)
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 174, in _connect_init_retry
        return self._init(retries=retries)
      File "/home/rahulrb/.virtualenvs/test/lib/python3.6/site-packages/pssh/clients/native/single.py", line 197, in _init
        raise AuthenticationException(msg, self.host, self.port, ex)
    pssh.exceptions.AuthenticationException: ('Authentication error while connecting to %s:%s - %s', '<ip1>', 22, AuthenticationException('Password authentication failed',))
    

    Additional info:

    • pssh version 1.9.1
    • ssh2_python version 0.17.0
    • paramiko version 2.4.2
    invalid cannot reproduce 
    opened by Rahul-RB 30
  • ParallelSSHClient: timeout option with proxy host

    ParallelSSHClient: timeout option with proxy host

    Hi,

    I have just tried to test with a Python script ParallelSSHClient and run_command with approximately 50 hosts behind a proxy host.

    I've realized that if you had one host in your host list which didn't boot correctly but you still establish a blocking TCP connexion the run_command return the output after bit more two minutes (eg. raise exception Connect Failed). So I decided to pass timeout option to the client with 10 seconds but the behaviour is the same and I must wait two minutes. So I pushed my script on the proxy host and launch ParallelSSHClient without proxy_host option and the output is returned after 10 seconds with an exception as expected (eg. timed out) .

    Can you confirm me this behaviour and how I should apply a timeout for my hosts list SSH connection when I specify a proxy_host ? Indeed I don't want to wait two minutes in the case of all hosts boot correctly except one.

    You can see below my script and the result of the tests with one host.

    Thanks in advance for your help

    NOTE1 : If I want a timeout of 10 seconds I must specify .10 (with 10 I must wait 40 seconds). NOTE2 : I notice in your documentation that you have a timeout=120 in ParallelSSHClient method and a typo in docstring with "Defaults to 10".

    script

    #!/usr/bin/env python
    
    from __future__ import print_function
    import sys
    import time
    from pssh import ParallelSSHClient
    
    def main(args):
        start_time = time.time()
        if len(args) > 1:
            client = ParallelSSHClient([args[0]],
                                       user='root',
                                       proxy_host=args[1],
                                       proxy_user=args[2],
                                       timeout=.10,
                                       channel_timeout=.10)
        else:
            client = ParallelSSHClient(args,
                                       user='root',
                                       timeout=.10,
                                       channel_timeout=.10)
        output = client.run_command("uptime", stop_on_errors=False)
        end_time = time.time() - start_time
        print('run_command duration : %d seconds' % end_time)
        print(output)
    
    if __name__ == '__main__':
        main(sys.argv[1:])
    
    

    with_proxy : script launch on my computer

    my_computer:~$ time ssh -o ConnectTimeout=10 -o "ProxyCommand=ssh grenoble.iot-lab.info -W %h:%p" [email protected]
    Connection timed out during banner exchange
    
    real	0m10.021s
    user	0m0.012s
    sys	0m0.000s
    
    my_computer:~$ ./test_pssh.py node-a8-111 grenoble.iot-lab.info <proxy_user>
    run_command duration : 127 seconds
    {'node-a8-111': 
    	host=node-a8-111
    	cmd=<Greenlet at 0x7f2db08a39b0>
    	channel=None
    	stdout=None
    	stderr=None
    	stdin=None
    	exception=("Error connecting to host '%s:%s' - %s", 'node-a8-111', 22, 'Connect failed')
    }
    

    without_proxy: script launch on the proxy host

    proxy_host:~$ time ssh -o ConnectTimeout=10 [email protected]
    ssh: connect to host node-a8-111 port 22: Connection timed out
    
    real	0m10.022s
    user	0m0.004s
    sys	0m0.004s
    
    proxy_host:~$ ./test_pssh.py node-a8-111
    run_command duration : 10 seconds
    {'node-a8-111': 
    	host=node-a8-111
    	cmd=<Greenlet at 0x7f2429667050>
    	channel=None
    	stdout=None
    	stderr=None
    	stdin=None
    	exception=("Error connecting to host '%s:%s' - %s - retry %s/%s", 'node-a8-111', 22, 'timed out', 3, 3)
    }
    
    enhancement 
    opened by fsaintma 16
  • SocketRecvError

    SocketRecvError

    Sometimes I get a SocketRcvError after the script execution

    Traceback (most recent call last): File "C:/Users/btissi/PycharmProjects/Test/script_4_test.py", line 41, in for line in host_output.stdout: File "C:\Users\btissi\PycharmProjects\Test\venv\lib\site-packages\pssh\clients\native\single.py", line 401, in read_output_buffer for line in output_buffer: File "pssh/native/_ssh2.pyx", line 45, in _read_output File "ssh2\channel.pyx", line 116, in ssh2.channel.Channel.read File "ssh2\channel.pyx", line 144, in ssh2.channel.Channel.read_ex File "ssh2\utils.pyx", line 179, in ssh2.utils.handle_error_codes ssh2.exceptions.SocketRecvError

    The code is the follow:

    hosts = ['10.1.23.23', '10.1.23.24']
    client = ParallelSSHClient(hosts, user='xx', password='xx')
    command_stp = "show spanning-tree detail | inc ieee|occurr|from|is exec"
    output = client.run_command(command_stp)
    
    for host, host_output in output.items():
        for line in host_output.stdout:
            print(line)
    

    When I run the code with only one hosts it works like a charm and doesn't raise any exceptions.

    Switches model: WS-C3750X-48PF-S

    Is it a common problem?

    bug 
    opened by brunotissi 15
  • Allow multiple ports on the same host via host_config

    Allow multiple ports on the same host via host_config

    Hello,

    I maybe missed something but when trying to reach multiple target, they are always identified by the host. Which means you can only have one connection per host.

    In my case, I try to reach some machines behind NAT. Different machines are pointed by different ports, but all on the same host of course.

    Even by using a 'host_config', it's again specified by host. One easy way would allows to specify the remote-address on the config dictionary. (eg: like HostName in ~/.ssh/config)

    I can reach my goal by instanciating one ssh per client by providing each time the host and port, but I loose the efficiency of parallelism.

    enhancement 
    opened by maxux 14
  • Run commands with per-host command argument(s)

    Run commands with per-host command argument(s)

    Hi,

    I'm currently looking for a way to run ssh sessions in parallel, and came across pssh. But looking at the docs, it will only allow me to run the same command on many hosts. Is it possible to run different commands on many hosts in parallel?

    Thanks, Christian

    enhancement 
    opened by derchrisuk 14
  • Q: Supported commands

    Q: Supported commands

    Sorry for using the issue section but I could not find a mailing list or similar.

    I am using PSSH to execute a script on - for now - a single node

    sshKey=paramiko.RSAKey.from_private_key_file('mysshkeypath',password='mypw'))
    ParallelSSHClient(hosts=['myipaddress'], user='node', pkey=sshKey)
    client.exec_command(`/home/node/circus/start.sh`)
    

    with /home/node/circus/start.sh being

    touch /tmp/test1
    circusd /home/node/circus/circus.ini &>/tmp/console.log &
    touch /tmp/test2
    

    While the touches get executed, the circusd is not. No console.log is created. When I execute the above call using a single SSH client everything works just fine. If I remove the & to make it a synchronous call, Circus spawns and PSSH blocks until I kill the process on the remote machine manually - as expected.

    Can someone explain me what is the problem here? Am I using PSSH wrong? This does not seem to be a Circus-issue since I can start the scripts locally and via SSH client without any issue.

    opened by sebschlicht 14
  • Quickly completed commands sometimes stall

    Quickly completed commands sometimes stall

    I've done some work to convert from paramiko to parallel-ssh, but have hit an issue where I'm sometimes seeing very short commands stall and take several minutes to complete. In this case, we're running cat on a small fio config file. I've been able to reproduce this with a simple script, getting results like this:

    Started at 2022-04-25 09:01:52.893054, ended at 2022-04-25 09:01:53.672184, total time is 0:00:00.779130
    Started at 2022-04-25 09:01:54.592475, ended at 2022-04-25 09:01:55.372624, total time is 0:00:00.780149
    Started at 2022-04-25 09:01:56.312288, ended at 2022-04-25 09:01:57.041410, total time is 0:00:00.729122
    Started at 2022-04-25 09:01:57.896660, ended at 2022-04-25 09:04:58.563031, total time is 0:03:00.666371
    

    I'm running this on an Ubuntu 20.04 system with the target also being an Ubuntu 20.04 system. I have not seen this issue with commands that take longer to run.

    Script:

    #!/usr/bin/env python3
    '''
    Quick script to try to reproduce stall with paralle-ssh
    '''
    
    from pssh.clients.native import SSHClient
    from pssh import exceptions
    from datetime import datetime
    
    hostname = "<target host>"
    cmd = "cat /tmp/red-bdev-rand-rw.fio"
    stdout = ""
    stderr = ""
    cmd_timeout = 180.0
    login = "<user>"
    password = "<password>"
    port_num = 22
    connect_retry_count = 3
    keyfile = "<keyfile>"
    
    client = SSHClient(host=hostname, user=login, password=password, port=port_num,
                num_retries=connect_retry_count, allow_agent=False, identity_auth=False, pkey=keyfile, timeout=cmd_timeout)
    
    start = datetime.now()
    host_out = client.run_command(cmd, use_pty=True, timeout=cmd_timeout)
    client.wait_finished(host_output=host_out)
    
    try:
        for line in host_out.stdout:
            stdout += line
        for line in host_out.stderr:
            stderr += line
        retcode = host_out.exit_code
    except exceptions.Timeout as err:
        # May as well pull all available output
        for line in host_out.stdout:
            stdout += line
        for line in host_out.stderr:
            stderr += line
        retcode = host_out.exit_code
        raise AssertionError(f"Command {cmd} timed out on host {hostname} after {cmd_timeout} seconds. "
                                    f"Partial output: {stdout} stderr: {stderr}") from err
    except Exception as err:
        raise AssertionError(f"Failed in rtfutils with error {err}") from err
    finally:
        client.close_channel(channel=host_out.channel)
        done = datetime.now()
    
    print(f"Started at {start}, ended at {done}, total time is {done - start}")
    

    Contents of the red-bdev-rand-rw.fio file:

    #red-bdev-rand-rw test
    [global]
    name=red-bdev-rand-rw
    ioengine=${IOENGINE}
    filename=${FILENAME}
    size=${SIZE}
    direct=1
    group_reporting=1
    thread=1
    time_based=1
    runtime=90
    blocksize_range=4k:3m
    rw=randrw
    [file1]
    iodepth=16
    numjobs=1
    [file2]
    iodepth=16
    numjobs=2
    [file3]
    iodepth=16
    numjobs=4
    [file4]
    iodepth=8
    numjobs=8
    [file5]
    iodepth=4
    numjobs=16
    [file6]
    iodepth=4
    numjobs=32
    
    bug 
    opened by rward-ddn 12
  • Allow copying files from remote host(s) to local host

    Allow copying files from remote host(s) to local host

    Adds support for copying files from remote hosts to local host as described in #40.

    A new method, copy_file_to_local, has been added to both pssh_client and ssh_client. In ssh_client, its logic is pretty similar to copy_file, but was different enough that I figured it would be better to create a new method rather than make copy_file more complex. In pssh_client, the logic is almost identical between copy_file and copy_file_to_local; the method was duplicated to maintain the pattern between ssh_client and pssh_client.

    While I think keeping copy_file simple and creating a new method is better, I also see the benefit of using one method to perform both functions, and am completely open to rolling the two functions together.

    Filenames are de-duplicated by appending an underscore followed by the hostname when using pssh_client to copy files to the local host.

    opened by Caid11 11
  • Libssh client does not attempt agent authentication

    Libssh client does not attempt agent authentication

    I dont know if this is an issue, but the discussion area seems to have no activity. I am trying to switch over to parallel-ssh because it uses python and I can stay organized better than a bunch of bash scripts, and I hate ansible.

    I have pssh setup to use the public keys I copied to my remote servers using ssh-copy-id. On my dev machine I can used ssh-agent and ssh-add to make it so I can log into a remote using "ssh host1" and if the agent has a PID, I am not challenged with a password.

    I am not sure how to set this up in parallel-ssh. I have tried just not entering a password in the client constructor but that gives me authentication errors. I have tried to use pkey but that gives errors too - the auth() method says FileError but no detail, and I cannot debug into the public key auth method I guess because it is wrapped C.

    bug 
    opened by gminorcoles 10
  • [Documentation] Running commands that do not terminate

    [Documentation] Running commands that do not terminate

    I am using run_command() function to run bash command remotely. My current issue is I want to start a server on remote device. The server runs forever, which blocks run_command() function.

    Is there a way to use run this method as non-blocking function?

    question good first issue documentation 
    opened by jiashenC 10
  • install error in package ssh2-python

    install error in package ssh2-python

    Describe the bug the problem is caused first by from ssh2.error_codes import LIBSSH2_ERROR_EAGAI which tries to load error_codes.cpython-37m-darwin.so but fails the reason is that '/private/var/folders/zb/t0r1t7451tx4vfhc9jbk2rzr0000gn/T/pip-install-vik15j8x/ssh2-python_fc1f843181664c9aa95e798b0c981b59/build_dir/src/libssh2.1.dylib' (no such file)

    To Reproduce

    Steps to reproduce the behavior:

    1. pip3 install parallel-ssh

    Expected behavior installed

    Actual behaviour error msg

    Screenshots Bildschirm­foto 2022-12-05 um 16 02 26

    Additional information on Mac os cmake and gcc installed cmake version 3.24.2 gcc 12.2.0

    opened by FengJiDetecon 2
  • AttributeError: 'ssh.channel.Channel' object has no attribute 'flush'

    AttributeError: 'ssh.channel.Channel' object has no attribute 'flush'

    Trying to call stdin.flush() results with the following exception. This is with libssh pssh.clients.ssh.SSHClient client.

    self = <pssh.clients.base.single.Stdin object at 0x7f2c6491ca60>
    
        def flush(self):
            """Flush pending data written to stdin."""
    >       return self._client._eagain(self._channel.flush)
    E       AttributeError: 'ssh.channel.Channel' object has no attribute 'flush'
    
    .venv/lib64/python3.10/site-packages/pssh/clients/base/single.py:71: AttributeError
    
    bug 
    opened by pbrezina 0
  • Cannot authenticate with a private key

    Cannot authenticate with a private key

    Describe the bug

    When I try to connect to a host using a private key, it doesn't work. With the ssh command line client, it works fines.

    To Reproduce

    Steps to reproduce the behavior:

    1. Run podman run -p 2022:22 docker.io/walac/pyktest-ssh:latest (the docker image is publicly available)
    2. Run the following python script
    from pssh.clients import SSHClient
    import logging as l
    
    l.getLogger('pssh.host_logger').setLevel(l.DEBUG)
    l.getLogger('pssh').setLevel(l.DEBUG)
    
    pkey = \
    b"""-----BEGIN OPENSSH PRIVATE KEY-----
    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
    -----END OPENSSH PRIVATE KEY-----"""
    
    ssh = SSHClient(host='localhost',
                    user='root',
                    pkey=pkey,
                    port=2022,
                    num_retries=1,
                    identity_auth=False)
    

    Expected behavior

    A connection to the remote host is established.

    Actual behavior

    Traceback (most recent call last):
      File "/home/wcosta/.local/lib/python3.10/site-packages/pssh/clients/base/single.py", line 204, in _auth_retry
        self.auth()
      File "/home/wcosta/.local/lib/python3.10/site-packages/pssh/clients/base/single.py", line 349, in auth
        return self._pkey_auth(self.pkey)
      File "/home/wcosta/.local/lib/python3.10/site-packages/pssh/clients/base/single.py", line 389, in _pkey_auth
        return self._pkey_from_memory(_pkey)
      File "/home/wcosta/.local/lib/python3.10/site-packages/pssh/clients/native/single.py", line 255, in _pkey_from_memory
        self.session.userauth_publickey_frommemory(
      File "ssh2/session.pyx", line 293, in ssh2.session.Session.userauth_publickey_frommemory
      File "ssh2/utils.pyx", line 166, in ssh2.utils.handle_error_codes
    ssh2.exceptions.AuthenticationError
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/home/wcosta/test.py", line 47, in <module>
        ssh = SSHClient(host='localhost',
      File "/home/wcosta/.local/lib/python3.10/site-packages/pssh/clients/native/single.py", line 138, in __init__
        super(SSHClient, self).__init__(
      File "/home/wcosta/.local/lib/python3.10/site-packages/pssh/clients/base/single.py", line 188, in __init__
        self._init()
      File "/home/wcosta/.local/lib/python3.10/site-packages/pssh/clients/base/single.py", line 196, in _init
        self._auth_retry()
      File "/home/wcosta/.local/lib/python3.10/site-packages/pssh/clients/base/single.py", line 210, in _auth_retry
        raise AuthenticationError(msg, self.host, self.port, ex, retries, self.num_retries)
    pssh.exceptions.AuthenticationError: ('Authentication error while connecting to %s:%s - %s - retries %s/%s', 'localhost', 2022, AuthenticationError(), 1, 1)
    

    Additional information

    parallel-ssh in ./.local/lib/python3.10/site-packages (2.12.0)
    ssh-python in /usr/lib64/python3.10/site-packages (from parallel-ssh) (0+unknown)
    gevent>=1.3.0 in ./.local/lib/python3.10/site-packages (from parallel-ssh) (21.12.0)
    ssh2-python in ./.local/lib/python3.10/site-packages (from parallel-ssh) (1.0.0)
    zope.event in ./.local/lib/python3.10/site-packages (from gevent>=1.3.0->parallel-ssh) (4.5.0)
    zope.interface in ./.local/lib/python3.10/site-packages (from gevent>=1.3.0->parallel-ssh) (5.4.0)
    setuptools in /usr/lib/python3.10/site-packages (from gevent>=1.3.0->parallel-ssh) (59.6.0)
    greenlet<2.0,>=1.1.0 in /usr/lib64/python3.10/site-packages (from gevent>=1.3.0->parallel-ssh) (1.1.2)
    
    blocked by upstream 
    opened by walac 3
  • Cleanup socket on connection error/timeout

    Cleanup socket on connection error/timeout

    When constructing a connection to a server, and the server is not responsive, the socket is not closed in a timely fashion and can cause a secondary exception when cleaning up in the exception handler due to the resource leak. This is

    ConnectionError: ("Error connecting to host '%s:%s' - %s - retry %s/%s", 'kg-meter2', 22, 'timed out', 3, 3) E
    E During handling of the above exception, another exception occurred: E
    E Traceback (most recent call last): E File "/home/kgodwin/.local/lib/python3.8/site-packages/_pytest/unraisableexception.py", line 43, in _hook E self.unraisable = unraisable E ResourceWarning: unclosed <socket object, fd=23, family=2, type=1, proto=0>

    opened by kurt-cb 0
  • [libssh clients only] Allow certificate data and type to be provided instead of certificate file

    [libssh clients only] Allow certificate data and type to be provided instead of certificate file

    Is your feature request related to a problem? Please describe. Certificate authentication does not support certificate data. A certificate file must be provided

    Describe the solution you'd like Allow certificate data and certificate type to be specified programmatically without a file.

    Describe alternatives you've considered Writing certificate data to temporary file with correct certificate header.

    Additional context This is specific to the pssh.clients.ssh clients.

    opened by pkittenis 0
Releases(2.12.0)
  • 2.12.0(Aug 20, 2022)

    Changes

    • Added alias optional parameter to SSHClient and HostConfig for passing through from parallel clients. Used to set an SSH host name alias, for cases where the real host name is the same and there is a need to differentiate output from otherwise identical host names - #355. Thank you @simonfelding.
    • Parallel clients now read a common private key only once, reusing it for all clients it applies to, to improve performance.
    • Performance improvements for all clients when reading output.
    • Output reading for all clients has been changed to be less prone to race conditions.

    Fixes

    • Calling ParallelSSHClient.join without ever running run_command would raise exception. Is now a no-op.
    Source code(tar.gz)
    Source code(zip)
  • 2.11.1(Jul 31, 2022)

    Changes

    • Updated default log formatter set by pssh.utils enable logger functions.

    Fixes

    • Using native clients under pssh.clients.native with very short lived commands would sometimes cause unexpected stalls/delays in reading output from completed commands when a client timeout setting was used - #344.
    Source code(tar.gz)
    Source code(zip)
  • 2.11.0.post2(Jul 31, 2022)

  • 2.11.0.post1(Jul 31, 2022)

  • 2.11.0(Jul 31, 2022)

  • 2.10.0(Apr 1, 2022)

    Changes

    • All client configuration can now be provided via HostConfig on parallel clients.
    • proxy_pkey can now also be provided as bytes for proxy authentication from in-memory private key data - #338
    • Removed deprecated since 2.0.0 dictionary support for host_config entries.
    Source code(tar.gz)
    Source code(zip)
  • 2.9.1(Mar 22, 2022)

  • 2.9.0(Mar 20, 2022)

    Changes

    • pssh.exceptions.ConnectionError is now the same as built-in ConnectionError and deprecated - to be removed.

    • Clients now attempt to connect with all addresses in DNS list. In the case where an address refuses connection, other available addresses are attempted without delay.

      For example where a host resolves to both IPv4 and v6 addresses while only one address is accepting connections, or multiple v4/v6 addresses where only some are accepting connections.

    • Connection actively refused error is no longer subject to retries.

    Fixes

    • scp_send in native clients would sometimes fail to send all data in a race condition with client going out of scope.
    Source code(tar.gz)
    Source code(zip)
  • 2.8.0(Nov 28, 2021)

    Changes

    • All clients now support private key data as bytes in pkey parameter for authentication from in-memory private key data - #317.
    • Parallel clients now read a provided private key path only once and use in-memory data for authentication to avoid reading same file multiple times, if a path is provided.
    Source code(tar.gz)
    Source code(zip)
  • 2.7.1(Nov 27, 2021)

    Fixes

    • copy_file performance would be abnormally low when copying plain text files - 100x performance increase. Binary file copying performance has also increased.
    Source code(tar.gz)
    Source code(zip)
  • 2.7.0(Oct 31, 2021)

    Changes

    • All clients now support IPv6 addresses for both DNS and IP entries in host list - #291
    • Added ipv6_only flag to ParallelSSHClient and SSHClient for choosing only IPv6 addresses when both v4 and v6 are available.
    • Removed Python 2 from binary wheel compatibility as it is no longer supported and not guaranteed to work.
    • Host name is now an argument for all exceptions raised by single clients.

    Fixes

    • HostOutput would have empty host on some exceptions when stop_on_errors is False - #297
    • Race condition when forcefully closing channel via SSHClient.close_channel while channel data was left unread.
    Source code(tar.gz)
    Source code(zip)
  • 2.6.0post1(Aug 26, 2021)

  • 2.6.0(Aug 26, 2021)

    Changes

    • user keyword argument no longer required on Windows - exception is raised if user cannot be identified.
    • Removed deprecated since 2.0.0 functions and parameters.

    Fixes

    • copy_remote_file with recurse enabled would not use a provided encoding for sub-directories - #284
    • Reconnecting to the same proxy host when proxy is configured would sometimes cause segfauls - ##304
    Source code(tar.gz)
    Source code(zip)
  • 2.5.4(Jan 28, 2021)

  • 2.5.3(Jan 9, 2021)

  • 2.5.2(Jan 6, 2021)

    Fixes

    • Agent authentication would not work for the libssh clients under pssh.clients.ssh - #267.
    • Password authentication would be attempted if all other methods failed even when no password was provided.
    • Gevent minimum version was too low - #269.
    Source code(tar.gz)
    Source code(zip)
  • 2.5.1(Jan 4, 2021)

  • 2.5.0(Jan 2, 2021)

    Changes

    • Python 2 no longer supported.
    • Updated class arguments, refactor for pssh.clients.native.tunnel.

    Fixes

    • Closed clients with proxy host enabled would not shutdown their proxy servers.
    • Clients with proxy host enabled would not disconnect the proxy client on .disconnect being called.
    • Default identity files would not be used when private key was not specified - #222.
    • ParallelSSHClient(<..>, identity_auth=False) would not be honoured.
    Source code(tar.gz)
    Source code(zip)
  • 2.4.0(Dec 26, 2020)

    Changes

    • Added interactive shell support to single and parallel clients - see documentation.
    • Added pssh.utils.enable_debug_logger function.
    • ParallelSSHClient timeout parameter is now also applied to starting remote commands via run_command.
    • HostOutput.stdin now handles EAGAIN automatically when writing - #165.
    • Assigning to ParallelSSHClient.hosts cleans up clients of hosts no longer in host list - #220.

    Fixes

    • SSHClient with proxy enabled could not be used without setting port - #248
    • Encoding would not be applied to command string on run_command and interactive shells, utf-8 used instead - #174.
    Source code(tar.gz)
    Source code(zip)
  • 2.3.2(Dec 9, 2020)

  • 2.3.1(Dec 6, 2020)

    Changes

    • SSHClient.read_output and read_stderr now take buffer to read from as argument instead of channel.
    • SSHClient.wait_finished now takes HostOutput argument instead of channel.

    Fixes

    • Output for multiple commands on one host run at the same time would be lost.
    Source code(tar.gz)
    Source code(zip)
  • 2.3.0(Dec 4, 2020)

    Changes

    • SSHClient now starts buffering output from remote host, both standard output and standard error, when a command is run.
    • SSHClient.read_output, SSHClient.read_stderr and iterating on stdout/stderr from HostOutput now read from the internal buffer rather than the SSH channel directly.
    • ParallelSSHClient.join no longer requires consume_output to be set in order to get exit codes without first reading output.
    • ParallelSSHClient.join with timeout no longer consumes output by default. It is now possible to use join with a timeout and capture output after join completes.
    • ParallelSSHClient.reset_output_generators is now a no-op and no longer required to be called after timeouts.
    • HostOutput.stdout and stderr are now dynamic properties.
    • Added HostOutput.read_timeout attribute. Can be used to see what read timeout was when run_command was called and to change timeout when next reading from HostOutput.stdout and stderr.
    • Added HostOutput.encoding attribute for encoding used when run_command was called. Encoding can now be changed for when next reading output.
    • ParallelSSHClient.join with timeout no longer affects stdout or stderr read timeout set when run_command was called.
    • LibSSH clients under pssh.clients.ssh now allow output to be read as it becomes available without waiting for remote command to finish first.
    • Reading from output behaviour is now consistent across all client types - parallel and single clients under both pssh.clients.native and pssh.clients.ssh.
    • ParallelSSHClient.join can now be called without arguments and defaults to last ran commands.
    • ParallelSSHClient.finished can now be called without arguments and defaults to last ran commands.

    This is now possible:

       output = client.run_command(<..>)
       client.join(output)
       assert output[0].exit_code is not None
    

    As is this:

       client.run_command(<..>, timeout=1)
       client.join(output, timeout=1)
       for line in output[0].stdout:
           print(line)
    

    Output can be read after and has separate timeout from join.

    See documentation for more examples on use of timeouts.

    Source code(tar.gz)
    Source code(zip)
  • 2.2.0(Dec 1, 2020)

    Changes

    • New single host tunneling, SSH proxy, implementation for increased performance.
    • Native SSHClient now accepts proxy_host, proxy_port and associated parameters - see API documentation
    • Proxy configuration can now be provided via HostConfig.
    • Added ParallelSSHClient.connect_auth function for connecting and authenticating to hosts in parallel.
    Source code(tar.gz)
    Source code(zip)
  • 2.1.0post1(Oct 25, 2020)

  • 2.1.0(Oct 25, 2020)

  • 2.0.0(Oct 6, 2020)

    Changes

    See Upgrading to API 2.0 for examples of code that will need updating.

    • Removed paramiko clients and dependency.
    • ParallelSSHClient.run_command now always returns a list of HostOutput - return_list argument is a no-op and will be removed in future releases.
    • ParallelSSHClient.get_last_output now always returns a list of HostOutput.
    • SSHClient.run_command now returns HostOutput.
    • Removed deprecated since 1.0.0 HostOutput dictionary attributes.
    • Removed deprecated since 1.0.0 imports and modules.
    • Removed paramiko based load_private_key and read_openssh_config functions from pssh.utils.
    • Removed paramiko based pssh.tunnel.
    • Removed paramiko based pssh.agent.
    • Removed deprecated ParallelSSHClient.get_output function.
    • Removed deprecated ParallelSSHClient.get_exit_code and get_exit_codes functions.
    • Removed deprecated ParallelSSHClient host_config dictionary implementation - now list of HostConfig.
    • Removed HostOutput.cmd attribute.
    • Removed ParallelSSHClient.host_clients attribute.
    • Made ParallelSSHClient(timeout=<seconds>) a global timeout setting for all operations.
    • Removed run_command(greenlet_timeout=<..>) argument - now uses global timeout setting.
    • Renamed run_command timeout to read_timeout=<seconds>) for setting output read timeout individually - defaults to global timeout setting.
    • Removed pssh.native package and native code.
    • ParallelSSHClient.scp_send now supports copy_args keyword argument for providing per-host file name arguments like rest of scp_* and copy_* functionality.
    • Changed exception names to end in Error from Exception - backwards compatible.
    • UnknownHostException, AuthenticationException, ConnectionErrorException, SSHException no longer available as imports from pssh - use from pssh.exceptions.

    Fixes

    • Removed now unnecessary locking around SSHClient initialisation so it can be parallelised - #219.
    • ParallelSSHClient.join with encoding would not pass on encoding when reading from output buffers - #214.
    • Clients could raise Timeout early when timeout settings were used with many hosts.

    Packaging

    • Package architecture has changed to none-any.
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0.rc1(Oct 3, 2020)

    Changes

    See Upgrading to API 2.0 <upgrade-link>_ for examples of code that will need updating.

    • Removed paramiko clients and dependency.
    • ParallelSSHClient.run_command now always returns a list of HostOutput - return_list argument is a no-op and may be removed.
    • ParallelSSHClient.get_last_output now always returns a list of HostOutput.
    • SSHClient.run_command now returns HostOutput.
    • Removed deprecated since 1.0.0 HostOutput dictionary attributes.
    • Removed deprecated since 1.0.0 imports and modules.
    • Removed paramiko based load_private_key and read_openssh_config functions from pssh.utils.
    • Removed paramiko based pssh.tunnel.
    • Removed paramiko based pssh.agent.
    • Removed deprecated ParallelSSHClient.get_output function.
    • Removed deprecated ParallelSSHClient.get_exit_code and get_exit_codes functions.
    • Removed deprecated ParallelSSHClient host_config dictionary implementation - now list of HostConfig.
    • Removed HostOutput.cmd attribute.
    • Removed ParallelSSHClient.host_clients attribute.
    • Made ParallelSSHClient(timeout=<seconds>) a global timeout setting for all operations.
    • Removed run_command(greenlet_timeout=<..>) argument - now uses global timeout setting.
    • Renamed run_command timeout to read_timeout=<seconds>) for setting output read timeout individually - defaults to global timeout setting.
    • Removed pssh.native package and native code.
    • No native code means package architecture has changed to none-any.

    Fixes

    • Removed now unnecessary locking around SSHClient initialisation so it can be parallelised - #219.
    • ParallelSSHClient.join with encoding would not pass on encoding when reading from output buffers - #214.
    • Clients could raise Timeout early when timeout settings were used with many hosts.
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0b3(Sep 18, 2020)

  • 2.0.0b2(Sep 18, 2020)

  • 2.0.0b1(Sep 18, 2020)

Let's learn how to build, release and operate your containerized applications to Amazon ECS and AWS Fargate using AWS Copilot.

🚀 Welcome to AWS Copilot Workshop In this workshop, you'll learn how to build, release and operate your containerised applications to Amazon ECS and

Donnie Prakoso 15 Jul 14, 2022
Bash-based Python-venv convenience wrapper

venvrc Bash-based Python-venv convenience wrapper. Demo Install Copy venvrc file to ~/.venvrc, and add the following line to your ~/.bashrc file: # so

1 Dec 29, 2022
Repository tracking all OpenStack repositories as submodules. Mirror of code maintained at opendev.org.

OpenStack OpenStack is a collection of interoperable components that can be deployed to provide computing, networking and storage resources. Those inf

Mirrors of opendev.org/openstack 4.6k Dec 28, 2022
CI repo for building Skia as a shared library

Automated Skia builds This repo is dedicated to building Skia binaries for use in Skija. Prebuilt binaries Prebuilt binaries can be found in releases.

Humble UI 20 Jan 06, 2023
A job launching library for docker, EC2, GCP, etc.

doodad A library for packaging dependencies and launching scripts (with a focus on python) on different platforms using Docker. Currently supported pl

Justin Fu 55 Aug 27, 2022
Asynchronous parallel SSH client library.

parallel-ssh Asynchronous parallel SSH client library. Run SSH commands over many - hundreds/hundreds of thousands - number of servers asynchronously

1.1k Dec 31, 2022
Oracle Cloud Infrastructure Object Storage fsspec implementation

Oracle Cloud Infrastructure Object Storage fsspec implementation The Oracle Cloud Infrastructure Object Storage service is an internet-scale, high-per

Oracle 9 Dec 18, 2022
Python utility function to communicate with a subprocess using iterables: for when data is too big to fit in memory and has to be streamed

iterable-subprocess Python utility function to communicate with a subprocess using iterables: for when data is too big to fit in memory and has to be

Department for International Trade 5 Jul 10, 2022
Ansible for DevOps examples.

Ansible for DevOps Examples This repository contains Ansible examples developed to support different sections of Ansible for DevOps, a book on Ansible

Jeff Geerling 6.6k Jan 08, 2023
Kube kombu - Running kombu consumers with support of liveness probe for kubernetes

Setup and Running Kombu consumers Steps: Install python 3.9 or greater on your s

Anmol Porwal 5 Dec 10, 2022
Automate SSH in python easily!

RedExpect RedExpect makes automating remote machines over SSH very easy to do and is very fast in doing exactly what you ask of it. Based on ssh2-pyth

Red_M 19 Dec 17, 2022
A Habitica Integration with Github Workflows.

Habitica-Workflow A Habitica Integration with Github Workflows. How To Use? Fork (and Star) this repository. Set environment variable in Settings - S

Priate 2 Dec 20, 2021
Chef-like functionality for Fabric

/ / ___ ___ ___ ___ | | )| |___ | | )|___) |__ |__/ | __/ | | / |__ -- Chef-like functionality for Fabric About Fabric i

Sébastien Pierre 1.3k Dec 21, 2022
Ajenti Core and stock plugins

Ajenti is a Linux & BSD modular server admin panel. Ajenti 2 provides a new interface and a better architecture, developed with Python3 and AngularJS.

Ajenti Project 7k Jan 03, 2023
Copy a Kubernetes pod and run commands in its environment

copypod Utility for copying a running Kubernetes pod so you can run commands in a copy of its environment, without worrying about it the pod potential

Memrise 4 Apr 08, 2022
MicroK8s is a small, fast, single-package Kubernetes for developers, IoT and edge.

MicroK8s The smallest, fastest Kubernetes Single-package fully conformant lightweight Kubernetes that works on 42 flavours of Linux. Perfect for: Deve

Ubuntu 7.1k Jan 08, 2023
pyinfra automates infrastructure super fast at massive scale. It can be used for ad-hoc command execution, service deployment, configuration management and more.

pyinfra automates/provisions/manages/deploys infrastructure super fast at massive scale. It can be used for ad-hoc command execution, service deployme

Nick Barrett 2.1k Dec 29, 2022
Simple, Pythonic remote execution and deployment.

Welcome to Fabric! Fabric is a high level Python (2.7, 3.4+) library designed to execute shell commands remotely over SSH, yielding useful Python obje

Fabric 13.8k Jan 06, 2023
Manage your azure VM easily!

Azure-manager Manage your VM in Azure using cookies.

Team 1injex 129 Dec 17, 2022
Bitnami Docker Image for Python using snapshots for the system packages repositories

Python Snapshot packaged by Bitnami What is Python Snapshot? Python is a programming language that lets you work quickly and integrate systems more ef

Bitnami 1 Jan 13, 2022