- All local file operations now use a thread pool to improve local file I/O performance. This includes loading private key files from a local file path, identity authentication using local files as well as SFTP read/write operations on local files.
- Added
HostOutput.fully_qualified_commandfor a bytes-string of the fully qualified command executed on that host after any and all host argument subtitutions, user switching, sudo, shell switching, encoding via specified encoding et al. Populated on calls torun_commandonly.
- Added compression support for all clients via
SSHClient(compress=True),ParallelSSHClient(compress=True)andHostConfig(compress=True)- defaults to off. #252 - Added "keyboard interactive" login support for native clients. This is fully automated username and password
authentication via SSH's keyboard interactive authentication mechanism and does not actually require a human at the
keyboard. Used in cases where the server does not allow any other authentication mechanism.
Note that server configuration may disallow remote command execution via
run_commandwhen keyboard interactive authentication is required - use interactive shells to run commands with in such cases. See Interactive Shells documentation. Also supported viaHostConfigentries. Currently native clients only. - Added
pssh.exceptions.InvalidAPIUseErrorfor errors raised on client initialisation when an invalid API use is detected. For example, keyboard interactive authentication enabled without a password provided. - Updated minimum
ssh2-pythonandssh-pythonrequirements.
- Handle disconnects better to allow for file descriptor reuse for both clients.
- Parallel clients no longer forcefully disconnect their clients at de-allocation -
now done by each individual
SSHClientinstead when thatSSHClientgoes out of scope. This allows reading of output and anything associated with output, exit codes et al, to work as long as one of either the client or an associated output object is alive. SSHClient.disconnectis now a no-op and deprecated - handled by object de-allocation.SSHClient.eagainis now a public function - wrapper for polling socket and calling a given socket using function.SSHClient.eagain_writeis now a public function - wrapper for polling socket and calling a given socket using write function.SSHClient,TunnelServerandLocalForwardernow use their own gevent pools for greenlets spawned so they are cleaned up correctly at shutdown.SSHClient.executeis now deprecated in favour ofSSHClient.run_command.
- Forwarder threads used for proxies would not exit gracefully at interpreter shutdown, sometimes causing segfaults.
- Client, both parallel and single, going out of scope would cause reading output from existing output objects to break.
- Explicitly calling
SSHClient.disconnectwould sometimes cause segfaults at interpreter shutdown. - Keepalives being configured on native client would keep client in scope forever.
- Minimum version updates for
ssh2-pythonand ssh-python`. - Added support for Python 3.12+, removed support for Python <3.8.
- Package tests under top level
testsdirectory are now cross platform and may be run by vendors. Project CI specific ntegration tests moved into their own space.
- Calling
HostOutput.stdin.flushwith apssh.clients.sshclient would raise exception.
- Added
aliasoptional parameter toSSHClientandHostConfigfor 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.
- Calling
ParallelSSHClient.joinwithout ever runningrun_commandwould raise exception. Is now a no-op.
- Updated default log formatter set by pssh.utils enable logger functions.
- 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
timeoutsetting was used - #344.
- Updated minimum required versions for ssh2-python and ssh-python.
- All client configuration can now be provided via
HostConfigon parallel clients. proxy_pkeycan now also be provided as bytes for proxy authentication from in-memory private key data - #338- Removed deprecated since
2.0.0dictionary support forhost_configentries.
- Even more rare race condition would sometimes cause
scp_sendto write incomplete files - #337
pssh.exceptions.ConnectionErroris now the same as built-inConnectionErrorand 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.
scp_sendin native clients would sometimes fail to send all data in a race condition with client going out of scope.
- All clients now support private key data as bytes in
pkeyparameter for authentication from in-memory private key data - #317. See documentation for examples. - 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.
copy_fileperformance would be abnormally low when copying plain text files - 100x performance increase. Binary file copying performance has also increased.
- All clients now support IPv6 addresses for both DNS and IP entries in host list.
- Added
ipv6_onlyflag toParallelSSHClientandSSHClientfor 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.
HostOutputwould have empty host on some exceptions whenstop_on_errorsisFalse- #297- Race condition when forcefully closing channel via
SSHClient.close_channelwhile channel data was left unread.
userkeyword argument no longer required on Windows - exception is raised if user cannot be identified.- Removed deprecated since
2.0.0functions and parameters.
copy_remote_filewith 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
- Password authentication via
pssh.clients.sshwould not work - #276
- Sending files via
scp_sendorsftp_putwith timeout set could timeout unexpectedly on opening remote file - #271.
- 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.
- Successful identity file authentication would raise error - #264.
- Python 2 no longer supported.
- Updated class arguments, refactor for
pssh.clients.native.tunnel.
- Closed clients with proxy host enabled would not shutdown their proxy servers.
- Clients with proxy host enabled would not disconnect the proxy client on
.disconnectbeing called. - Default identity files would not be used when private key was not specified - #222.
ParallelSSHClient(<..>, identity_auth=Falsewould not be honoured.
- Added interactive shell support to single and parallel clients - see documentation.
- Added
pssh.utils.enable_debug_loggerfunction. ParallelSSHClienttimeout parameter is now also applied to starting remote commands viarun_command.HostOutput.stdinnow handles EAGAIN automatically when writing - #165.- Assigning to
ParallelSSHClient.hostscleans up clients of hosts no longer in host list - #220.
SSHClientwith proxy enabled could not be used without setting port - #248- Encoding would not be applied to command string on
run_commandand interactive shells, utf-8 used instead - #174.
- Client output implementation Python 2 support.
SSHClient.read_outputandread_stderrnow take buffer to read from as argument instead of channel.SSHClient.wait_finishednow takesHostOutputargument instead of channel.
- Output for multiple commands on one host run at the same time would be lost.
SSHClientnow starts buffering output from remote host, both standard output and standard error, when a command is run.SSHClient.read_output,SSHClient.read_stderrand iterating on stdout/stderr fromHostOutputnow read from the internal buffer rather than the SSH channel directly.ParallelSSHClient.joinno longer requiresconsume_outputto be set in order to get exit codes without first reading output.ParallelSSHClient.joinwith timeout no longer consumes output by default. It is now possible to usejoinwith a timeout and capture output afterjoincompletes.ParallelSSHClient.reset_output_generatorsis now a no-op and no longer required to be called after timeouts.HostOutput.stdoutandstderrare now dynamic properties.- Added
HostOutput.read_timeoutattribute. Can be used to see what read timeout was whenrun_commandwas called and to change timeout when next reading fromHostOutput.stdoutandstderr. - Added
HostOutput.encodingattribute for encoding used whenrun_commandwas called. Encoding can now be changed for when next reading output. ParallelSSHClient.joinwith timeout no longer affectsstdoutorstderrread timeout set whenrun_commandwas called.- LibSSH clients under
pssh.clients.sshnow 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.nativeandpssh.clients.ssh. ParallelSSHClient.joincan now be called without arguments and defaults to last ran commands.ParallelSSHClient.finishedcan 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 NoneAs is this:
client.run_command(<..>, read_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.
- New single host tunneling, SSH proxy, implementation for increased performance.
- Native
SSHClientnow acceptsproxy_host,proxy_portand associated parameters - see API documentation. - Proxy configuration can now be provided via
HostConfig. - Added
ParallelSSHClient.connect_authfunction for connecting and authenticating to hosts in parallel.
- Added certificate authentication support for the
pssh.clients.sshclients.
See Upgrading to API 2.0 for examples of code that will need updating.
- Removed paramiko clients and dependency.
ParallelSSHClient.run_commandnow always returns a list ofHostOutput-return_listargument is a no-op and may be removed.ParallelSSHClient.get_last_outputnow always returns a list ofHostOutput.SSHClient.run_commandnow returnsHostOutput.- Removed deprecated since 1.0.0
HostOutputdictionary attributes. - Removed deprecated since 1.0.0 imports and modules.
- Removed paramiko based
load_private_keyandread_openssh_configfunctions frompssh.utils. - Removed paramiko based
pssh.tunnel. - Removed paramiko based
pssh.agent. - Removed deprecated
ParallelSSHClient.get_outputfunction. - Removed deprecated
ParallelSSHClient.get_exit_codeandget_exit_codesfunctions. - Removed deprecated
ParallelSSHClienthost_configdictionary implementation - now list ofHostConfig. - Removed
HostOutput.cmdattribute. - Removed
ParallelSSHClient.host_clientsattribute. - Made
ParallelSSHClient(timeout=<seconds>)a global timeout setting for all operations. - Removed
run_command(greenlet_timeout=<..>)argument - now uses global timeout setting. - Renamed
run_commandtimeouttoread_timeout=<seconds>)for setting output read timeout individually - defaults to global timeout setting. - Removed
pssh.nativepackage and native code. ParallelSSHClient.scp_sendnow supportscopy_argskeyword argument for providing per-host file name arguments like rest ofscp_*andcopy_*functionality.- Changed exception names to end in
ErrorfromException- backwards compatible. UnknownHostException,AuthenticationException,ConnectionErrorException,SSHExceptionno longer available as importsfrom pssh- usefrom pssh.exceptions.
- Removed now unnecessary locking around SSHClient initialisation so it can be parallelised - #219.
ParallelSSHClient.joinwith encoding would not pass on encoding when reading from output buffers - #214.- Clients could raise
Timeoutearly when timeout settings were used with many hosts.
- Package architecture has changed to
none-any.
- Added
pssh.config.HostConfigfor providing per-host configuration. Replaces dictionaryhost_configwhich is now deprecated. See per-host configuration documentation. ParallelSSHClient.scp_sendandscp_recvwith directory target path will now copy source file to directory keeping existing name instead of failing when recurse is off - #183.pssh.clients.ssh.SSHClientwait_finishedtimeout is now separate fromSSHClient(timeout=<timeout>)session timeout.ParallelSSHClient.joinwith timeout now has finished and unfinished commands asTimeoutexception arguments for use by client code.
ParallelSSHClient.copy_filewith recurse enabled and absolute destination path would create empty directory in home directory of user - #197.ParallelSSHClient.copy_fileandscp_recvwith recurse enabled would not create remote directories when copying empty local directories.ParallelSSHClient.scp_sendwould require SFTP when recurse is off and remote destination path contains directory - #157.ParallelSSHClient.scp_recvcould block infinitely on large - 200-300MB or more - files.SSHClient.wait_finishedwould not apply timeout value given.
- Reading from output streams with timeout via run_command(<..>, timeout=<timeout>) would raise timeout early when trying to read from a stream with no data written to it while other streams have pending data - #180.
- Added ssh-python (libssh) based native client with run_command implementation.
ParallelSSHClient.joinwith timeout no longer consumes output by default to allow reading of output after timeout.
ParallelSSHClient.joinwith timeout would raiseTimeoutbefore value given when client was busy with other commands.
Note
ssh-python client at pssh.clients.ssh.ParallelSSHClient is available for testing. Please report any issues.
To use:
from pssh.clients.ssh import ParallelSSHClientThis release adds (yet another) client, this one based on ssh-python (libssh). Key features of this client are more supported authentication methods compared to ssh2-python.
Future releases will also enable certificate authentication for the ssh-python client.
Please migrate to one of the two native clients if have not already as paramiko is very quickly accumulating yet more bugs and the 2.0.0 release which removes it is imminent.
Users that require paramiko for any reason can pin their parallel-ssh versions to parallel-ssh<2.0.0.
- ParallelSSHClient going out of scope would cause new client sessions to fail if client.join was not called prior - #200
- Moved polling to gevent.select.poll to increase performance and better handle high number of sockets - #189
HostOutput.exit_codeis now a dynamic property returning eitherNonewhen exit code not ready or the exit code as reported by channel.ParallelSSHClient.get_exit_codesis now a no-op and scheduled to be removed.- Native client exit codes are now more explicit and return
Noneif no exit code is ready. Would previously return0by default.
- Removed OSX Python 3.6 and 3.7 wheels. OSX wheels for brew python, currently 3.8, on OSX 10.14 and 10.15 are provided.
- Native client would fail on opening sockets with large file descriptor values - #189
- Added
return_listoptional argument torun_commandto return list ofHostOutputobjects as output rather than dictionary - defaults toFalse. List output will become default starting from2.0.0. - Updated native clients for new version of
ssh2-python. - Manylinux 2010 wheels.
- Sockets would not be closed on client going out of scope - #175
- Calling
join()would reset encoding set onrun_command- #159
- Native client SCP and SFTP uploads would not handle partial writes from waiting on socket correctly.
- Native client
copy_fileSFTP upload would get stuck repeating same writes until killed when copying multi-MB files from Windows clients - #148 - Native client
scp_sendwould not correctly preserve file mask of local file on the remote. - Native client tunnel, used for proxy implementation, would not handle partial writes from waiting on socket correctly.
- Removed libssh2 native library dependency in favour of bundled
ssh2-pythonlibssh2 library. - Changed native client forward agent default behaviour to off due to incompatibility with certain SSH server implementations.
- Added keep-alive functionality to native client - defaults to
60seconds.ParallelSSHClient(<..>, keepalive_seconds=<interval>)to configure interval. Set to0to disable. - Added
~/.ssh/id_ecdsadefault identity location to native client.
- Native parallel client
forward_ssh_agentflag would not be applied correctly.
- Native client socket timeout setting would be longer than expected - #133
- Added Windows 3.7 wheels
- Native client no longer requires public key file for authentication.
- Native clients raise
pssh.exceptions.PKeyFileErroron object initialisation if provided private key file paths cannot be found. - Native clients expand user directory (
~/<path>) on provided private key paths. - Parallel clients raise
TypeErrorwhen providedhostsis a string instead of list or other iterable.
- Better tunneling implementation for native clients that supports multiple tunnels over single SSH connection for connecting multiple hosts through single proxy.
- Added
greenlet_timeoutsetting to native clientrun_commandto pass on to getting greenlet result to allow for greenlets to timeout. - Native client raises specific exceptions on non-authentication errors connecting to host instead of generic
SessionError.
- Native client tunneling would not work correctly - #123.
timeoutsetting was not applied to native client sockets.- Native client would have
SessionErrorinstead ofTimeoutexceptions on timeout errors connecting to hosts.
- Re-generated C code with latest Cython release.
ssh2-python>= 0.14.0 support.
- Native client proxy initialisation failures were not caught by
stop_on_errors=False- #121.
- Host would always be 127.0.0.1 when using
proxy_hoston native client - #120.
- Added
scp_sendandscp_recvfunctions to native clients for sending and receiving files via SCP respectively. - Refactoring - clients moved to their own sub-package -
pssh.clients- with backwards compatibility for imports frompssh.pssh_clientandpssh.pssh2_client. - Show underlying exception from native client library when raising
parallel-sshexceptions. hostparameter added to all exceptions raised by parallel clients - #116- Deprecation warning for client imports.
- Deprecation warning for default client changing from paramiko to native client as of
2.0.0. - Upgrade embedded
libssh2in binary wheels to latest version plus enhancements. - Adds support for ECDSA host keys for native client.
- Adds support for SHA-256 host key fingerprints for native client.
- Added SSH agent forwarding to native client, defaults to on as per paramiko client -
forward_ssh_agentkeyword parameter. - Windows wheels switched to OpenSSL back end for native client.
- Windows wheels include zlib and have compression enabled for native client.
- Added OSX 10.13 wheel build.
- Windows native client could not connect to newer SSH servers - thanks Pavel.
Note - libssh2 changes apply to binary wheels only. For building from source, see documentation.
- Use of
sudoin native client incorrectly required escaping of command.
- Compatibility with
ssh2-python>=0.11.0.
- Output generators automatically restarted on call to
joinso output can resume on any timeouts.
- Output
pssh.exceptions.Timeoutexception raising was not enabled.
ParallelSSH2Client.joinwith timeout now consumes output to ensure command completion status is accurate.- Output reading now raises
pssh.exceptions.Timeoutexception when timeout is requested and reached with command still running.
ParallelSSH2Client.joinwould always raiseTimeoutwhen output has not been consumed even if command has finished - #104.
ParallelSSH2Client.joinnow raisespssh.exceptions.Timeoutexception when timeout is requested and reached with command still running.
ParallelSSH2Client.jointimeout duration was incorrectly for per-host rather than total.- SFTP read flags were not fully portable.
- Binary wheels would have bad version info and require git for installation.
- Added
timeoutoptional parameter tojoinandrun_command, for reading output, on native clients.
- From source builds when Cython is installed with recent versions of
ssh2-python.
- Native clients proxy implementation
- Native clients connection and authentication retry mechanism
Proxy/tunnelling implementation is experimental - please report any issues.
- PyPy builds
- New
ssh2-python(libssh2) native library based clients - Added
retry_delaykeyword parameter to parallel clients - Added
get_last_outputfunction for retrieving output of last executed commands - Added
cmdsattribute to parallel clients for last executed commands
- Remote path for SFTP operations was created incorrectly on Windows - #88 - thanks @moscoquera
- Parallel client key error when openssh config with a host name override was used - #93
- Clean up after paramiko clients
- Accept Paramiko version
2but <2.2(it's buggy).
- Allow passing on of additional keyword arguments to underlying SSH library via
run_command- #85
- ParallelSSHClient.join no longer consumes output buffers
- Command output is now a dictionary of host name -> host output object with stdout and et al attributes. Host output supports dictionary-like item lookup for backwards compatibility. No code changes are needed to output use though documentation will from now on refer to the new attribute style output. Dictionary-like item access is deprecated and will be removed in future major release, like 2.x.
- Made output encoding configurable via keyword argument on run_command and get_output
- pssh.output.HostOutput class added to hold host output
- Added copy_remote_file function for copying remote files to local ones in parallel
- Deprecated since 0.70.0 ParallelSSHClient API endpoints removed
- Removed setuptools >= 28.0.0 dependency for better compatibility with existing installations. Pip version dependency remains for Py 2.6 compatibility with gevent - documented on project's readme
- Documented use_pty parameter of run_command
- SSHClient read_output_buffer is now public function and has gained callback capability
- If using the single SSHClient directly, read_output_buffer should now be used to read output buffers - this is not needed for ParallelSSHClient
- run_command now uses named positional and keyword arguments