Skip to content

Commit 6c0ebce

Browse files
authored
Updated exception names, added tests. Updated changelog. (#233)
* Updated exception names, added tests. * Removed top level pssh module exception imports. * Updated documentation. * Updated exception handling for renamed exceptions - backwards compatible. * Updated init. * Updated changelog.
1 parent 8dd2f3e commit 6c0ebce

File tree

11 files changed

+159
-126
lines changed

11 files changed

+159
-126
lines changed

Changelog.rst

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ See `Upgrading to API 2.0 <https://parallel-ssh.readthedocs.io/en/latest/api_upg
2828
* Renamed ``run_command`` ``timeout`` to ``read_timeout=<seconds>)`` for setting output read timeout individually - defaults to global timeout setting.
2929
* Removed ``pssh.native`` package and native code.
3030
* ``ParallelSSHClient.scp_send`` now supports ``copy_args`` keyword argument for providing per-host file name arguments like rest of ``scp_*`` and ``copy_*`` functionality.
31+
* Changed exception names to end in ``Error`` from ``Exception`` - backwards compatible.
32+
* ``UnknownHostException``, ``AuthenticationException``, ``ConnectionErrorException``, ``SSHException`` no longer available as imports ``from pssh`` - use ``from pssh.exceptions``.
3133

3234

3335
Fixes

doc/installation.rst

+11-60
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,20 @@ Pip Install
1717
1818
If ``pip`` is not available on your Python platform, `see this installation guide <http://docs.python-guide.org/en/latest/starting/installation/>`_.
1919

20-
Dependencies
21-
--------------
20+
From Source Dependencies
21+
-------------------------
2222

23-
When installing from source, dependencies must be satisfied by ``pip install -r requirements.txt``. For pre-built binary wheel packages with dependencies included, see `Pip Install`_.
23+
When installing from source, dependencies must be satisfied by ``pip install -r requirements.txt`` or by system packages.
2424

25-
=============== ================
25+
For binary packages, see `Pip Install`_.
26+
27+
=============== =====================
2628
Dependency Minimum Version
27-
=============== ================
28-
``ssh2-python`` ``0.19.0``
29-
``ssh-python`` ``0.6.0``
30-
``gevent`` ``1.1``
31-
=============== ================
29+
=============== =====================
30+
``ssh2-python`` per requirements.txt
31+
``ssh-python`` per requirements.txt
32+
``gevent`` per requirements.txt
33+
=============== =====================
3234

3335

3436
Building from Source
@@ -54,54 +56,3 @@ Or for developing changes:
5456
5557
pip install -r requirements_dev.txt
5658
57-
Building System Packages
58-
--------------------------
59-
60-
For convenience, a script making use of Docker is provided at `ci/docker/build-packages.sh <https://github.com/ParallelSSH/parallel-ssh/blob/master/ci/docker/build-packages.sh>`_ that will build system packages for Centos/RedHat 6/7, Ubuntu 14.04/16.04, Debian 7/8 and Fedora 22/23/24.
61-
62-
This script and docker files can be adapted for other distributions.
63-
64-
Note that these packages make use of system libraries that may need to be updated to be compatible with ``parallel-ssh`` - see `Dependencies`_.
65-
66-
.. code-block:: shell
67-
68-
git clone [email protected]:ParallelSSH/parallel-ssh.git
69-
cd parallel-ssh
70-
# Checkout a tag for tagged builds - git tag; git checkout <tag>
71-
./ci/docker/build-packages.sh
72-
ls -1tr
73-
74-
.. code-block:: shell
75-
76-
python-parallel-ssh-1.2.0+4.ga811e69.dirty-1.el6.x86_64.rpm
77-
python-parallel-ssh-1.2.0+4.ga811e69.dirty-1.el7.x86_64.rpm
78-
python-parallel-ssh-1.2.0+4.ga811e69.dirty-1.fc22.x86_64.rpm
79-
python-parallel-ssh-1.2.0+4.ga811e69.dirty-1.fc23.x86_64.rpm
80-
python-parallel-ssh-1.2.0+4.ga811e69.dirty-1.fc24.x86_64.rpm
81-
python-parallel-ssh_1.2.0+4.ga811e69.dirty-debian7_amd64.deb
82-
python-parallel-ssh_1.2.0+4.ga811e69.dirty-debian8_amd64.deb
83-
84-
Specific System Package Build
85-
_______________________________
86-
87-
To build for only a specific system/distribution, run the two following commands, substituting distribution with the desired one from `ci/docker <https://github.com/ParallelSSH/parallel-ssh/blob/master/ci/docker>`_. See `existing Dockerfiles <https://github.com/ParallelSSH/parallel-ssh/tree/master/ci/docker/ubuntu16.04/Dockerfile>`_ for examples on how to create system packages for other distributions.
88-
89-
Debian based
90-
+++++++++++++
91-
92-
.. code-block:: shell
93-
94-
docker build --cache-from parallelssh/parallel-ssh-pkgs:debian7 ci/docker/debian7 -t debian7
95-
docker run -v "$(pwd):/src/" debian7 --iteration debian7 -s python -t deb setup.py
96-
97-
98-
RPM based
99-
++++++++++
100-
101-
.. code-block:: shell
102-
103-
docker build --cache-from parallelssh/parallel-ssh-pkgs:centos7 ci/docker/centos7 -t centos7
104-
docker run -v "$(pwd):/src/" centos7 --rpm-dist el7 -s python -t rpm setup.py
105-
106-
107-
See `fpm <http://fpm.readthedocs.io/en/latest/>`_ for making system packages of various types.

doc/quickstart.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ With this flag, the ``exception`` output attribute will contain the exception on
333333
.. code-block:: python
334334
335335
host1: 0, None
336-
host2: None, AuthenticationException <..>
336+
host2: None, AuthenticationError <..>
337337
338338
.. seealso::
339339

pssh/__init__.py

+12-17
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
# This file is part of parallel-ssh.
2-
2+
#
33
# Copyright (C) 2014-2020 Panos Kittenis.
4-
4+
#
55
# This library is free software; you can redistribute it and/or
66
# modify it under the terms of the GNU Lesser General Public
77
# License as published by the Free Software Foundation, version 2.1.
8-
8+
#
99
# This library is distributed in the hope that it will be useful,
1010
# but WITHOUT ANY WARRANTY; without even the implied warranty of
1111
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1212
# Lesser General Public License for more details.
13-
13+
#
1414
# You should have received a copy of the GNU Lesser General Public
1515
# License along with this library; if not, write to the Free Software
1616
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
@@ -20,25 +20,20 @@
2020
Run SSH commands over many - hundreds/hundreds of thousands - number of servers
2121
asynchronously and with minimal system load on the client host.
2222
23-
New users should start with
24-
:py:func:`pssh.clients.ParallelSSHClient.run_command`
23+
New users should start with `pssh.clients.ParallelSSHClient.run_command` and
24+
`pssh.clients.SSHClient.run_command`
2525
26-
See also :py:class:`pssh.ParallelSSHClient` and :py:class:mod:`pssh.SSHClient`
26+
See also `pssh.clients.ParallelSSHClient` and pssh.clients.SSHClient`
2727
for class documentation.
2828
"""
2929

30-
# flake8: noqa: E402, F401, F402
3130

32-
import logging
31+
from logging import getLogger, NullHandler
3332
from ._version import get_versions
3433
__version__ = get_versions()['version']
3534
del get_versions
36-
from .exceptions import UnknownHostException, \
37-
AuthenticationException, ConnectionErrorException, SSHException
38-
3935

40-
host_logger = logging.getLogger('pssh.host_logger')
41-
logger = logging.getLogger('pssh')
42-
if hasattr(logging, 'NullHandler'):
43-
host_logger.addHandler(logging.NullHandler())
44-
logger.addHandler(logging.NullHandler())
36+
host_logger = getLogger('pssh.host_logger')
37+
logger = getLogger('pssh')
38+
host_logger.addHandler(NullHandler())
39+
logger.addHandler(NullHandler())

pssh/clients/base/parallel.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from gevent.hub import Hub
2626

2727
from ...constants import DEFAULT_RETRIES, RETRY_DELAY
28-
from ...exceptions import HostArgumentException, Timeout
28+
from ...exceptions import HostArgumentError, Timeout
2929
from ...output import HostOutput
3030

3131

@@ -92,7 +92,7 @@ def run_command(self, command, user=None, stop_on_errors=True,
9292
*args, **kwargs)
9393
for host_i, host in enumerate(self.hosts)]
9494
except IndexError:
95-
raise HostArgumentException(
95+
raise HostArgumentError(
9696
"Number of host arguments provided does not match "
9797
"number of hosts ")
9898
else:
@@ -328,15 +328,15 @@ def copy_file(self, local_file, remote_file, recurse=False, copy_args=None):
328328
:param copy_args: (Optional) format local_file and remote_file strings
329329
with per-host arguments in ``copy_args``. ``copy_args`` length must
330330
equal length of host list -
331-
:py:class:`pssh.exceptions.HostArgumentException` is raised otherwise
331+
:py:class:`pssh.exceptions.HostArgumentError` is raised otherwise
332332
:type copy_args: tuple or list
333333
334334
:rtype: List(:py:class:`gevent.Greenlet`) of greenlets for remote copy
335335
commands
336336
337337
:raises: :py:class:`ValueError` when a directory is supplied to
338338
local_file and recurse is not set
339-
:raises: :py:class:`pssh.exceptions.HostArgumentException` on number of
339+
:raises: :py:class:`pssh.exceptions.HostArgumentError` on number of
340340
per-host copy arguments not equal to number of hosts
341341
:raises: :py:class:`IOError` on I/O errors writing files
342342
:raises: :py:class:`OSError` on OS errors like permission denied
@@ -355,7 +355,7 @@ def copy_file(self, local_file, remote_file, recurse=False, copy_args=None):
355355
{'recurse': recurse})
356356
for host_i, host in enumerate(self.hosts)]
357357
except IndexError:
358-
raise HostArgumentException(
358+
raise HostArgumentError(
359359
"Number of per-host copy arguments provided does not match "
360360
"number of hosts")
361361
else:
@@ -412,13 +412,13 @@ def copy_remote_file(self, remote_file, local_file, recurse=False,
412412
:param copy_args: (Optional) Format remote_file and local_file strings
413413
with per-host arguments in ``copy_args``. ``copy_args`` length must
414414
equal length of host list -
415-
:py:class:`pssh.exceptions.HostArgumentException` is raised otherwise
415+
:py:class:`pssh.exceptions.HostArgumentError` is raised otherwise
416416
:type copy_args: tuple or list
417417
:rtype: list(:py:class:`gevent.Greenlet`) of greenlets for remote copy
418418
commands
419419
:raises: :py:class:`ValueError` when a directory is supplied to
420420
local_file and recurse is not set
421-
:raises: :py:class:`pssh.exceptions.HostArgumentException` on number of
421+
:raises: :py:class:`pssh.exceptions.HostArgumentError` on number of
422422
per-host copy arguments not equal to number of hosts
423423
:raises: :py:class:`IOError` on I/O errors writing files
424424
:raises: :py:class:`OSError` on OS errors like permission denied
@@ -440,7 +440,7 @@ def copy_remote_file(self, remote_file, local_file, recurse=False,
440440
local_file % copy_args[host_i], recurse=recurse, **kwargs)
441441
for host_i, host in enumerate(self.hosts)]
442442
except IndexError:
443-
raise HostArgumentException(
443+
raise HostArgumentError(
444444
"Number of per-host copy arguments provided does not match "
445445
"number of hosts")
446446
else:

pssh/clients/base/single.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131

3232
from ..common import _validate_pkey_path
3333
from ...constants import DEFAULT_RETRIES, RETRY_DELAY
34-
from ...exceptions import UnknownHostException, AuthenticationException, \
35-
ConnectionErrorException
34+
from ...exceptions import UnknownHostError, AuthenticationError, \
35+
ConnectionError
3636
from ...output import HostOutput
3737

3838

@@ -98,7 +98,7 @@ def _auth_retry(self, retries=1):
9898
sleep(self.retry_delay)
9999
return self._auth_retry(retries=retries+1)
100100
msg = "Authentication error while connecting to %s:%s - %s"
101-
raise AuthenticationException(msg, self.host, self.port, ex)
101+
raise AuthenticationError(msg, self.host, self.port, ex)
102102

103103
def disconnect(self):
104104
raise NotImplementedError
@@ -143,9 +143,9 @@ def _connect(self, host, port, retries=1):
143143
if retries < self.num_retries:
144144
sleep(self.retry_delay)
145145
return self._connect(host, port, retries=retries+1)
146-
ex = UnknownHostException("Unknown host %s - %s - retry %s/%s",
147-
host, str(ex.args[1]), retries,
148-
self.num_retries)
146+
ex = UnknownHostError("Unknown host %s - %s - retry %s/%s",
147+
host, str(ex.args[1]), retries,
148+
self.num_retries)
149149
ex.host = host
150150
ex.port = port
151151
raise ex
@@ -156,7 +156,7 @@ def _connect(self, host, port, retries=1):
156156
sleep(self.retry_delay)
157157
return self._connect(host, port, retries=retries+1)
158158
error_type = ex.args[1] if len(ex.args) > 1 else ex.args[0]
159-
ex = ConnectionErrorException(
159+
ex = ConnectionError(
160160
"Error connecting to host '%s:%s' - %s - retry %s/%s",
161161
host, port, str(error_type), retries,
162162
self.num_retries,)
@@ -182,7 +182,7 @@ def _identity_auth(self):
182182
logger.debug("Authentication succeeded with identity file %s",
183183
identity_file)
184184
return
185-
raise AuthenticationException("No authentication methods succeeded")
185+
raise AuthenticationError("No authentication methods succeeded")
186186

187187
def _init_session(self, retries=1):
188188
raise NotImplementedError

pssh/clients/native/parallel.py

+14-14
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from ..common import _validate_pkey_path
2626
from ..base.parallel import BaseParallelSSHClient
2727
from ...constants import DEFAULT_RETRIES, RETRY_DELAY
28-
from ...exceptions import ProxyError, Timeout, HostArgumentException
28+
from ...exceptions import ProxyError, Timeout, HostArgumentError
2929

3030

3131
logger = logging.getLogger(__name__)
@@ -181,7 +181,7 @@ def run_command(self, command, sudo=False, user=None, stop_on_errors=True,
181181
:type use_pty: bool
182182
:param host_args: (Optional) Format command string with per-host
183183
arguments in ``host_args``. ``host_args`` length must equal length of
184-
host list - :py:class:`pssh.exceptions.HostArgumentException` is
184+
host list - :py:class:`pssh.exceptions.HostArgumentError` is
185185
raised otherwise
186186
:type host_args: tuple or list
187187
:param encoding: Encoding to use for output. Must be valid
@@ -204,13 +204,13 @@ def run_command(self, command, sudo=False, user=None, stop_on_errors=True,
204204
:py:class:`pssh.output.HostOutput` as value
205205
*or* list(:py:class:`pssh.output.HostOutput`) when
206206
``return_list=True``
207-
:raises: :py:class:`pssh.exceptions.AuthenticationException` on
207+
:raises: :py:class:`pssh.exceptions.AuthenticationError` on
208208
authentication error
209-
:raises: :py:class:`pssh.exceptions.UnknownHostException` on DNS
209+
:raises: :py:class:`pssh.exceptions.UnknownHostError` on DNS
210210
resolution error
211-
:raises: :py:class:`pssh.exceptions.ConnectionErrorException` on error
211+
:raises: :py:class:`pssh.exceptions.ConnectionError` on error
212212
connecting
213-
:raises: :py:class:`pssh.exceptions.HostArgumentException` on number of
213+
:raises: :py:class:`pssh.exceptions.HostArgumentError` on number of
214214
host arguments not equal to number of hosts
215215
:raises: :py:class:`TypeError` on not enough host arguments for cmd
216216
string format
@@ -328,15 +328,15 @@ def copy_file(self, local_file, remote_file, recurse=False, copy_args=None):
328328
:param copy_args: (Optional) format local_file and remote_file strings
329329
with per-host arguments in ``copy_args``. ``copy_args`` length must
330330
equal length of host list -
331-
:py:class:`pssh.exceptions.HostArgumentException` is raised otherwise
331+
:py:class:`pssh.exceptions.HostArgumentError` is raised otherwise
332332
:type copy_args: tuple or list
333333
334334
:rtype: list(:py:class:`gevent.Greenlet`) of greenlets for remote copy
335335
commands
336336
337337
:raises: :py:class:`ValueError` when a directory is supplied to
338338
local_file and recurse is not set
339-
:raises: :py:class:`pssh.exceptions.HostArgumentException` on number of
339+
:raises: :py:class:`pssh.exceptions.HostArgumentError` on number of
340340
per-host copy arguments not equal to number of hosts
341341
:raises: :py:class:`pss.exceptions.SFTPError` on SFTP initialisation
342342
errors
@@ -393,7 +393,7 @@ def copy_remote_file(self, remote_file, local_file, recurse=False,
393393
:param copy_args: (Optional) format remote_file and local_file strings
394394
with per-host arguments in ``copy_args``. ``copy_args`` length must
395395
equal length of host list -
396-
:py:class:`pssh.exceptions.HostArgumentException` is raised otherwise
396+
:py:class:`pssh.exceptions.HostArgumentError` is raised otherwise
397397
:type copy_args: tuple or list
398398
:param encoding: Encoding to use for file paths.
399399
:type encoding: str
@@ -403,7 +403,7 @@ def copy_remote_file(self, remote_file, local_file, recurse=False,
403403
404404
:raises: :py:class:`ValueError` when a directory is supplied to
405405
local_file and recurse is not set
406-
:raises: :py:class:`pssh.exceptions.HostArgumentException` on number of
406+
:raises: :py:class:`pssh.exceptions.HostArgumentError` on number of
407407
per-host copy arguments not equal to number of hosts
408408
:raises: :py:class:`pss.exceptions.SFTPError` on SFTP initialisation
409409
errors
@@ -482,7 +482,7 @@ def scp_send(self, local_file, remote_file, recurse=False, copy_args=None):
482482
recurse=recurse)
483483
for host_i, host in enumerate(self.hosts)]
484484
except IndexError:
485-
raise HostArgumentException(
485+
raise HostArgumentError(
486486
"Number of per-host copy arguments provided does not match "
487487
"number of hosts")
488488

@@ -528,15 +528,15 @@ def scp_recv(self, remote_file, local_file, recurse=False, copy_args=None,
528528
:param copy_args: (Optional) format remote_file and local_file strings
529529
with per-host arguments in ``copy_args``. ``copy_args`` length *must*
530530
equal length of host list -
531-
:py:class:`pssh.exceptions.HostArgumentException` is raised otherwise
531+
:py:class:`pssh.exceptions.HostArgumentError` is raised otherwise
532532
:type copy_args: tuple or list
533533
534534
:rtype: list(:py:class:`gevent.Greenlet`) of greenlets for remote copy
535535
commands.
536536
537537
:raises: :py:class:`ValueError` when a directory is supplied to
538538
local_file and recurse is not set.
539-
:raises: :py:class:`pssh.exceptions.HostArgumentException` on number of
539+
:raises: :py:class:`pssh.exceptions.HostArgumentError` on number of
540540
per-host copy arguments not equal to number of hosts.
541541
:raises: :py:class:`pss.exceptions.SCPError` on errors copying file.
542542
:raises: :py:class:`OSError` on local OS errors like permission denied.
@@ -563,6 +563,6 @@ def scp_recv(self, remote_file, local_file, recurse=False, copy_args=None,
563563
local_file % copy_args[host_i], recurse=recurse)
564564
for host_i, host in enumerate(self.hosts)]
565565
except IndexError:
566-
raise HostArgumentException(
566+
raise HostArgumentError(
567567
"Number of per-host copy arguments provided does not match "
568568
"number of hosts")

0 commit comments

Comments
 (0)