Skip to content

Commit

Permalink
Upgrade (#398)
Browse files Browse the repository at this point in the history
* Fixed issue with stdin flush for libssh clients
* Updated changelog
* Updated sshd template
* Updated versioneer
* Updated logging
* Refactored tests, imports
* Updated CI cfg
* Updated docstrings
* Updated imports
* Updated readme
* Prettify tests
  • Loading branch information
pkittenis authored Jan 13, 2025
1 parent c7fc51a commit f1d46fc
Show file tree
Hide file tree
Showing 48 changed files with 1,296 additions and 610 deletions.
33 changes: 12 additions & 21 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
version: 2.1

orbs:
python: circleci/[email protected]

jobs:
python_test:
parameters:
python_ver:
type: string
default: "3.6"
default: "3.10"
docker:
- image: circleci/python:<< parameters.python_ver >>
- image: cimg/python:<< parameters.python_ver >>
steps:
- checkout
- python/load-cache:
dependency-file: requirements_dev.txt
key: depsv3-{{ .Branch }}.{{ arch }}-PY<< parameters.python_ver >>
- run:
name: Deps
command: |
Expand All @@ -24,23 +19,25 @@ jobs:
- run:
command: |
pip install -U -r requirements_dev.txt
set -x
eval "$(ssh-agent -s)"
name: Build
- python/save-cache:
dependency-file: requirements_dev.txt
key: depsv3-{{ .Branch }}.{{ arch }}-PY<< parameters.python_ver >>
- run:
command: |
python setup.py check --restructuredtext
name: Check readme
- run:
command: |
flake8 pssh
flake8 tests ci/integration_tests
name: flake
- run:
command: |
set -x
eval "$(ssh-agent -s)"
pytest
name: Test
- run:
command: |
pytest ci/integration_tests
name: Integration tests
- run:
command: |
Expand All @@ -59,22 +56,16 @@ jobs:

release:
docker:
- image: circleci/python:3.8
- image: cimg/python:3.10
steps:
- checkout
- python/load-cache:
key: releasedepsv1-{{ .Branch }}.{{ arch }}
dependency-file: requirements.txt
- run:
name: Deps
command: |
sudo apt-get update
sudo apt-get install python3-pip
pip install -U pip
pip install -U twine
- python/save-cache:
key: releasedepsv1-{{ .Branch }}.{{ arch }}
dependency-file: requirements.txt
- run:
name: Build Wheels/Source Dist
command: |
Expand All @@ -94,10 +85,10 @@ workflows:
matrix:
parameters:
python_ver:
- "3.6"
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
filters:
tags:
ignore: /.*/
Expand Down
1 change: 1 addition & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ coverage:
ignore:
- "embedded_server/.*"
- "tests/.*"
- "ci/integration_tests/.*"
8 changes: 4 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pypy
# Documentation builds
doc/_build

tests/unit_test_cert_key-cert.pub
tests/embedded_server/principals
tests/embedded_server/sshd_config_*
tests/embedded_server/*.pid
ci/integration_tests/int_test_cert_key-cert.pub
ci/integration_tests/embedded_server/principals
ci/integration_tests/embedded_server/sshd_config_*
ci/integration_tests/embedded_server/*.pid
19 changes: 19 additions & 0 deletions Changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
Change Log
============


2.13.0
+++++++

Changes
-------

* Minimum version updates for ``ssh2-python`` and `ssh-python``.
* Added support for Python 3.12+, removed support for Python <3.8.
* Package tests under top level ``tests`` directory are now cross platform and may be run by vendors.
Project CI specific ntegration tests moved into their own space.


Fixes
------

* Calling ``HostOutput.stdin.flush`` with a ``pssh.clients.ssh`` client would raise exception.


2.12.0
+++++++

Expand Down
8 changes: 8 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,12 @@ include pssh/_version.py
include LICENSE
include COPYING
include COPYING.LESSER
exclude .codecov.yml
exclude .coveragerc
exclude .git*
exclude .pre-commit*
exclude .readthedocs.yml
recursive-exclude tests *
recursive-exclude ci *
recursive-exclude .circleci *
recursive-exclude .github *
9 changes: 3 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Native code based clients with extremely high performance, making use of C libra
:alt: Latest documentation

.. _`read the docs`: https://parallel-ssh.readthedocs.org/en/latest/
.. _`SFTP and SCP documentation`: https://parallel-ssh.readthedocs.io/en/latest/advanced.html#sftp-scp

************
Installation
Expand Down Expand Up @@ -239,7 +240,7 @@ To copy a local file to remote hosts in parallel with SCP:
cmds = client.scp_send('../test', 'test_dir/test')
joinall(cmds, raise_error=True)
See `SFTP and SCP documentation <https://parallel-ssh.readthedocs.io/en/latest/advanced.html#sftp-scp>`_ for more examples.
See `SFTP and SCP documentation`_ for more examples.


*****
Expand Down Expand Up @@ -275,8 +276,4 @@ In addition, per-host configurable file name functionality is provided for both

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

See `SFTP and SCP documentation <https://parallel-ssh.readthedocs.io/en/latest/advanced.html#sftp-scp>`_ for more examples.


.. image:: https://ga-beacon.appspot.com/UA-9132694-7/parallel-ssh/README.rst?pixel
:target: https://github.com/igrigorik/ga-beacon
See `SFTP and SCP documentation`_ for more examples.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@ HostCertificate {{parent_dir}}/ca_host_key-cert.pub
TrustedUserCAKeys {{parent_dir}}/ca_user_key.pub
AuthorizedPrincipalsFile {{parent_dir}}/principals

MaxAuthTries 999
MaxSessions 999
MaxStartups 999
# PerSourceMaxStartups 999
# PerSourcePenaltyExemptList *.*.*.*


AcceptEnv LANG LC_*
Subsystem sftp internal-sftp
AuthorizedKeysFile {{parent_dir}}/authorized_keys
MaxSessions 100
PidFile {{parent_dir}}/{{random_server}}.pid
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,14 @@ def test_pssh_client_run_command_get_output(self):
(stderr,
expected_stderr,))

def test_pssh_client_run_long_command(self):
expected_lines = 5
output = self.client.run_command(self.long_cmd(expected_lines))
self.client.join(output)
stdout = list(output[0].stdout)
self.assertTrue(len(stdout) == expected_lines,
msg="Expected %s lines of response, got %s" % (
expected_lines, len(stdout)))
# def test_pssh_client_run_long_command(self):
# expected_lines = 5
# output = self.client.run_command(self.long_cmd(expected_lines))
# self.client.join(output)
# stdout = list(output[0].stdout)
# self.assertTrue(len(stdout) == expected_lines,
# msg="Expected %s lines of response, got %s" % (
# expected_lines, len(stdout)))

def test_pssh_client_auth_failure(self):
client = ParallelSSHClient([self.host], port=self.port,
Expand Down Expand Up @@ -328,29 +328,29 @@ def test_zero_timeout(self):
cmd = spawn(client.run_command, 'sleep .1', stop_on_errors=False)
output = cmd.get(timeout=.3)
self.assertTrue(output[0].exception is None)

def test_pssh_client_long_running_command_exit_codes(self):
expected_lines = 2
output = self.client.run_command(self.long_cmd(expected_lines))
self.assertIsNone(output[0].exit_code)
self.assertFalse(self.client.finished(output))
self.client.join(output, consume_output=True)
self.assertTrue(self.client.finished(output))
self.assertEqual(output[0].exit_code, 0)
stdout = list(output[0].stdout)
self.assertEqual(len(stdout), 0)

def test_pssh_client_long_running_command_exit_codes_no_stdout(self):
expected_lines = 2
output = self.client.run_command(self.long_cmd(expected_lines))
self.assertEqual(len(output), len(self.client.hosts))
self.assertIsNone(output[0].exit_code)
self.assertFalse(self.client.finished(output))
self.client.join(output)
self.assertTrue(self.client.finished(output))
self.assertEqual(output[0].exit_code, 0)
stdout = list(output[0].stdout)
self.assertEqual(expected_lines, len(stdout))
#
# def test_pssh_client_long_running_command_exit_codes(self):
# expected_lines = 2
# output = self.client.run_command(self.long_cmd(expected_lines))
# self.assertIsNone(output[0].exit_code)
# self.assertFalse(self.client.finished(output))
# self.client.join(output, consume_output=True)
# self.assertTrue(self.client.finished(output))
# self.assertEqual(output[0].exit_code, 0)
# stdout = list(output[0].stdout)
# self.assertEqual(len(stdout), 0)
#
# def test_pssh_client_long_running_command_exit_codes_no_stdout(self):
# expected_lines = 2
# output = self.client.run_command(self.long_cmd(expected_lines))
# self.assertEqual(len(output), len(self.client.hosts))
# self.assertIsNone(output[0].exit_code)
# self.assertFalse(self.client.finished(output))
# self.client.join(output)
# self.assertTrue(self.client.finished(output))
# self.assertEqual(output[0].exit_code, 0)
# stdout = list(output[0].stdout)
# self.assertEqual(expected_lines, len(stdout))

def test_pssh_client_retries(self):
"""Test connection error retries"""
Expand Down Expand Up @@ -945,7 +945,7 @@ def test_host_config(self):
host_config=host_config,
num_retries=1)
output = client.run_command(self.cmd, stop_on_errors=False)

client.join(output)
self.assertEqual(len(hosts), len(output))
try:
Expand Down Expand Up @@ -1121,7 +1121,7 @@ def test_pty(self):
expected_stdout = []
# With a PTY, stdout and stderr are combined into stdout
self.assertEqual(expected_stderr, stdout)
self.assertEqual([], stderr)
self.assertEqual(expected_stdout, stderr)
self.assertTrue(exit_code == 0)

def test_output_attributes(self):
Expand Down Expand Up @@ -1442,11 +1442,10 @@ def test_scp_send_dir(self):
remote_test_dir, remote_filepath = 'remote_test_dir', 'test_file_copy'
with open(local_filename, 'w') as file_h:
file_h.writelines([test_file_data + os.linesep])
remote_filename = os.path.sep.join([remote_test_dir, remote_filepath])
remote_file_abspath = os.path.expanduser('~/' + remote_filename)
remote_filename_relpath = os.path.sep.join([remote_test_dir, remote_filepath])
remote_test_dir_abspath = os.path.expanduser('~/' + remote_test_dir)
try:
cmds = self.client.scp_send(local_filename, remote_filename)
cmds = self.client.scp_send(local_filename, remote_filename_relpath)
joinall(cmds, raise_error=True)
except Exception as ex:
self.assertIsInstance(ex, SCPError)
Expand Down Expand Up @@ -1558,8 +1557,10 @@ def test_scp_bad_copy_args(self):

def test_scp_send_exc(self):
client = ParallelSSHClient([self.host], pkey=self.user_key, num_retries=1)

def _scp_send(*args):
raise Exception

def _client_send(*args):
return client._handle_greenlet_exc(_scp_send, 'fake')
client._scp_send = _client_send
Expand All @@ -1568,8 +1569,10 @@ def _client_send(*args):

def test_scp_recv_exc(self):
client = ParallelSSHClient([self.host], pkey=self.user_key, num_retries=1)

def _scp_recv(*args):
raise Exception

def _client_recv(*args):
return client._handle_greenlet_exc(_scp_recv, 'fake')
client._scp_recv = _client_recv
Expand Down Expand Up @@ -1899,8 +1902,9 @@ def test_read_multi_same_hosts(self):
self.client.run_command(self.cmd),
]
for output in outputs:
for host_out in output:
for i, host_out in enumerate(output):
stdout = list(host_out.stdout)
self.assertEqual(host_out.client.host, hosts[i])
self.assertListEqual(stdout, [self.resp])

@patch('pssh.clients.base.single.socket')
Expand Down
Loading

0 comments on commit f1d46fc

Please sign in to comment.