11# This file is part of parallel-ssh.
22
3- # Copyright (C) 2014- Panos Kittenis
3+ # Copyright (C) 2014-2017 Panos Kittenis
44
55# This library is free software; you can redistribute it and/or
66# modify it under the terms of the GNU Lesser General Public
4848class ParallelSSHClient (object ):
4949 """Uses :py:class:`pssh.ssh_client.SSHClient`, performs tasks over SSH on multiple hosts in \
5050 parallel.
51-
51+
5252 Connections to hosts are established in parallel when ``run_command`` is called,
5353 therefor any connection and/or authentication exceptions will happen on the
5454 call to ``run_command`` and need to be caught.
5555 """
56-
57- def __init__ (self , hosts ,
58- user = None , password = None , port = None , pkey = None ,
59- forward_ssh_agent = True , num_retries = DEFAULT_RETRIES , timeout = 120 ,
60- pool_size = 10 , proxy_host = None , proxy_port = 22 , proxy_user = None ,
61- proxy_password = None , proxy_pkey = None ,
62- agent = None , allow_agent = True , host_config = None , channel_timeout = None ):
56+
57+ def __init__ (self , hosts , user = None , password = None , port = None , pkey = None ,
58+ forward_ssh_agent = True , num_retries = DEFAULT_RETRIES ,
59+ timeout = 120 , pool_size = 10 , proxy_host = None , proxy_port = 22 ,
60+ proxy_user = None , proxy_password = None , proxy_pkey = None ,
61+ agent = None , allow_agent = True , host_config = None ,
62+ channel_timeout = None ):
6363 """
6464 :param hosts: Hosts to connect to
6565 :type hosts: list(str)
66- :param user: (Optional) User to login as. Defaults to logged in user or \
67- user from ~/.ssh/config or /etc/ssh/ssh_config if set
66+ :param user: (Optional) User to login as. Defaults to logged in user or
67+ user from ~/.ssh/config or /etc/ssh/ssh_config if set
6868 :type user: str
69- :param password: (Optional) Password to use for login. Defaults to \
70- no password
69+ :param password: (Optional) Password to use for login. Defaults to
70+ no password
7171 :type password: str
72- :param port: (Optional) Port number to use for SSH connection. Defaults \
73- to None which uses SSH default
72+ :param port: (Optional) Port number to use for SSH connection. Defaults
73+ to `` None`` which uses SSH default
7474 :type port: int
7575 :param pkey: (Optional) Client's private key to be used to connect with
7676 :type pkey: :py:class:`paramiko.pkey.PKey`
77- :param num_retries: (Optional) Number of retries for connection attempts \
78- before the client gives up. Defaults to 3.
77+ :param num_retries: (Optional) Number of retries for connection attempts
78+ before the client gives up. Defaults to 3.
7979 :type num_retries: int
80- :param timeout: (Optional) Number of seconds to timeout connection \
81- attempts before the client gives up. Defaults to 10.
80+ :param timeout: (Optional) Number of seconds to wait before connection
81+ and authentication attempt times out. Note that total time before
82+ timeout will be
83+ ``timeout`` * ``num_retries`` + (5 * (``num_retries``-1)) number of
84+ seconds, where (5 * (``num_retries``-1)) refers to a five (5) second
85+ delay between retries.
8286 :type timeout: int
83- :param forward_ssh_agent: (Optional) Turn on SSH agent forwarding - \
84- equivalent to `ssh -A` from the `ssh` command line utility. \
85- Defaults to True if not set.
87+ :param forward_ssh_agent: (Optional) Turn on SSH agent forwarding -
88+ equivalent to `ssh -A` from the `ssh` command line utility.
89+ Defaults to `` True`` if not set.
8690 :type forward_ssh_agent: bool
87- :param pool_size: (Optional) Greenlet pool size. Controls on how many\
88- hosts to execute tasks in parallel. Defaults to 10. Values over 500 \
89- are not likely to increase performance due to overhead in the single \
90- thread running our event loop .
91+ :param pool_size: (Optional) Greenlet pool size. Controls on how many
92+ hosts to execute tasks in parallel. Defaults to 10. Overhead in event
93+ loop will determine how high this can be set to, see scaling guide
94+ lines in project's readme .
9195 :type pool_size: int
92- :param proxy_host: (Optional) SSH host to tunnel connection through \
93- so that SSH clients connect to self.host via client -> proxy_host -> \
94- host
96+ :param proxy_host: (Optional) SSH host to tunnel connection through
97+ so that SSH clients connect to host via client -> proxy_host -> host
9598 :type proxy_host: str
96- :param proxy_port: (Optional) SSH port to use to login to proxy host if \
97- set. Defaults to 22.
99+ :param proxy_port: (Optional) SSH port to use to login to proxy host if
100+ set. Defaults to 22.
98101 :type proxy_port: int
99- :param proxy_user: (Optional) User to login to ``proxy_host`` as. Defaults to \
100- logged in user.
102+ :param proxy_user: (Optional) User to login to ``proxy_host`` as.
103+ Defaults to logged in user.
101104 :type proxy_user: str
102- :param proxy_password: (Optional) Password to login to ``proxy_host`` with. \
103- Defaults to no password
105+ :param proxy_password: (Optional) Password to login to ``proxy_host``
106+ with. Defaults to no password
104107 :type proxy_password: str
105- :param proxy_pkey: (Optional) Private key to be used for authentication \
106- with ``proxy_host``. Defaults to available keys from SSHAgent and user's \
107- home directory keys
108+ :param proxy_pkey: (Optional) Private key to be used for authentication
109+ with ``proxy_host``. Defaults to available keys from SSHAgent and user's
110+ home directory keys
108111 :type proxy_pkey: :py:class:`paramiko.pkey.PKey`
109- :param agent: (Optional) SSH agent object to programmatically supply an \
110- agent to override system SSH agent with
112+ :param agent: (Optional) SSH agent object to programmatically supply an
113+ agent to override system SSH agent with
111114 :type agent: :py:class:`pssh.agent.SSHAgent`
112- :param host_config: (Optional) Per-host configuration for cases where \
113- not all hosts use the same configuration values.
115+ :param host_config: (Optional) Per-host configuration for cases where
116+ not all hosts use the same configuration values.
114117 :type host_config: dict
115- :param channel_timeout: (Optional) Time in seconds before reading from \
116- an SSH channel times out. For example with channel timeout set to one, \
117- trying to immediately gather output from a command producing no output \
118- for more than one second will timeout.
118+ :param channel_timeout: (Optional) Time in seconds before reading from
119+ an SSH channel times out. For example with channel timeout set to one,
120+ trying to immediately gather output from a command producing no output
121+ for more than one second will timeout.
119122 :type channel_timeout: int
120- :param allow_agent: (Optional) set to False to disable connecting to \
121- the system's SSH agent
123+ :param allow_agent: (Optional) set to False to disable connecting to
124+ the system's SSH agent
122125 :type allow_agent: bool
123126
124127 **Example Usage**
@@ -261,8 +264,8 @@ def __init__(self, hosts,
261264
262265 .. code-block:: python
263266
264- import paramiko
265- client_key = paramiko.RSAKey.from_private_key_file ('user.key')
267+ from pssh.utils import load_private_key
268+ client_key = load_private_key ('user.key')
266269 client = ParallelSSHClient(['myhost1', 'myhost2'], pkey=client_key)
267270
268271 **Multiple commands**
@@ -274,13 +277,14 @@ def __init__(self, hosts,
274277
275278 **Per-Host configuration**
276279
277- Per host configuration can be provided for any or all of user, password port
278- and private key. Private key value is a :py:class:`paramiko.pkey.PKey` object as
279- returned by :py:func:`pssh.utils.load_private_key`.
280+ Per host configuration can be provided for any or all of user, password
281+ port and private key. Private key value is a
282+ :py:class:`paramiko.pkey.PKey` object as returned by
283+ :py:func:`pssh.utils.load_private_key`.
280284
281- :py:func:`pssh.utils.load_private_key` accepts both file names and file-like
282- objects and will attempt to load all available key types, returning
283- ``None`` if they all fail.
285+ :py:func:`pssh.utils.load_private_key` accepts both file names and
286+ file-like objects and will attempt to load all available key types,
287+ returning ``None`` if they all fail.
284288
285289 .. code-block:: python
286290
@@ -768,19 +772,30 @@ def _update_host_output(self, output, host, exit_code, channel, stdout,
768772 exit_code = exit_code ,
769773 exception = exception )
770774
771- def join (self , output ):
775+ def join (self , output , consume_output = False ):
772776 """Block until all remote commands in output have finished
773- and retrieve exit codes"""
777+ and retrieve exit codes
778+
779+ :param output: Output of commands to join on
780+ :type output: dict as returned by
781+ :py:func:`pssh.pssh_client.ParallelSSHClient.get_output`
782+ """
774783 for host in output :
775784 output [host ].cmd .join ()
776785 if output [host ].channel is not None :
777786 output [host ].channel .recv_exit_status ()
787+ if consume_output :
788+ for line in output [host ].stdout :
789+ pass
790+ for line in output [host ].stderr :
791+ pass
778792 self .get_exit_codes (output )
779793
780794 def finished (self , output ):
781795 """Check if commands have finished without blocking
782796
783- :param output: As returned by :py:func:`pssh.pssh_client.ParallelSSHClient.get_output`
797+ :param output: As returned by
798+ :py:func:`pssh.pssh_client.ParallelSSHClient.get_output`
784799 :rtype: bool
785800 """
786801 for host in output :
@@ -793,7 +808,8 @@ def get_exit_codes(self, output):
793808 """Get exit code for all hosts in output *if available*.
794809 Output parameter is modified in-place.
795810
796- :param output: As returned by :py:func:`pssh.pssh_client.ParallelSSHClient.get_output`
811+ :param output: As returned by
812+ :py:func:`pssh.pssh_client.ParallelSSHClient.get_output`
797813 :rtype: None
798814 """
799815 for host in output :
0 commit comments