You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Added concurrent RW buffer class and tests
* Migrated ssh client to concurrent rw buffer. Added iteration support to reader. Updated ssh client line parsing.
* Added partial read timeout with and without join test and for updated API calls.
* Updated host output to make stdout/stderr dynamic properties.
* Deprecated reset generators function - now a no-op.
* Added read timeout and encoding attributes to host output.
* Updated changelog, documentation.
Copy file name to clipboardExpand all lines: Changelog.rst
+43Lines changed: 43 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,49 @@
1
1
Change Log
2
2
============
3
3
4
+
2.3.0
5
+
+++++
6
+
7
+
Changes
8
+
-------
9
+
10
+
* ``SSHClient`` now starts buffering output from remote host, both standard output and standard error, when a command is run.
11
+
* ``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.
12
+
* ``ParallelSSHClient.join`` no longer requires ``consume_output`` to be set in order to get exit codes without first reading output.
13
+
* ``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.
14
+
* ``ParallelSSHClient.reset_output_generators`` is now a no-op and no longer required to be called after timeouts.
15
+
* ``HostOutput.stdout`` and ``stderr`` are now dynamic properties.
16
+
* 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``.
17
+
* Added ``HostOutput.encoding`` attribute for encoding used when ``run_command`` was called. Encoding can now be changed for when next reading output.
18
+
* ``ParallelSSHClient.join`` with timeout no longer affects ``stdout`` or ``stderr`` read timeout set when ``run_command`` was called.
19
+
* LibSSH clients under ``pssh.clients.ssh`` now allow output to be read as it becomes available without waiting for remote command to finish first.
20
+
* Reading from output behaviour is now consistent across all client types - parallel and single clients under both ``pssh.clients.native`` and ``pssh.clients.ssh``.
21
+
* ``ParallelSSHClient.join`` can now be called without arguments and defaults to last ran commands.
22
+
* ``ParallelSSHClient.finished`` can now be called without arguments and defaults to last ran commands.
23
+
24
+
25
+
This is now possible:
26
+
27
+
.. code-block:: python
28
+
29
+
output = client.run_command(<..>)
30
+
client.join(output)
31
+
assert output[0].exit_code isnotNone
32
+
33
+
As is this:
34
+
35
+
.. code-block:: python
36
+
37
+
client.run_command(<..>, timeout=1)
38
+
client.join(output, timeout=1)
39
+
for line in output[0].stdout:
40
+
print(line)
41
+
42
+
Output can be read after and has separate timeout from join.
43
+
44
+
See `documentation for more examples on use of timeouts <https://parallel-ssh.readthedocs.io/en/latest/advanced.html#partial-output>`_.
Copy file name to clipboardExpand all lines: doc/advanced.rst
+21-27Lines changed: 21 additions & 27 deletions
Original file line number
Diff line number
Diff line change
@@ -188,7 +188,9 @@ See :py:mod:`HostConfig <pssh.config.HostConfig>` for all possible configuration
188
188
Join and Output Timeouts
189
189
**************************
190
190
191
-
Clients have timeout functionality on reading output and ``client.join``. Join timeout is a timeout on all parallel commands in total and is separate from ``ParallelSSHClient(timeout=<..>)`` which is applied to SSH session operations individually.
191
+
Clients have timeout functionality on reading output and ``client.join``.
192
+
193
+
Join timeout is applied to all parallel commands in total and is separate from ``ParallelSSHClient(timeout=<..>)`` which is applied to SSH session operations individually.
192
194
193
195
Timeout exceptions contain attributes for which commands have finished and which have not so client code can get output from any finished commands when handling timeouts.
194
196
@@ -207,18 +209,18 @@ The client will raise a ``Timeout`` exception if *all* remote commands have not
207
209
208
210
.. code-block:: python
209
211
210
-
output = client.run_command(.., timeout=5)
212
+
output = client.run_command(.., read_timeout=5)
211
213
for host_out in output:
212
214
try:
213
215
for line in host_out.stdout:
214
-
pass
216
+
print(line)
215
217
for line in host_out.stderr:
216
-
pass
218
+
print(line)
217
219
except Timeout:
218
220
pass
219
221
220
222
221
-
In the case of reading from output such as in the example above, timeout value is per output stream - meaning separate timeouts for stdout and stderr as well as separate timeout per host remote command.
223
+
In the case of reading from output such as in the example above, timeout value is per output stream - meaning separate timeouts for stdout and stderr as well as separate timeout per host output.
222
224
223
225
*New in 1.5.0*
224
226
@@ -253,6 +255,7 @@ In the above example, output is printed only for those commands which have compl
253
255
254
256
Client code may choose to then join again only on the unfinished output if some commands have failed in order to gather remaining output.
255
257
258
+
.. _partial-output:
256
259
257
260
Reading Partial Output of Commands That Do Not Terminate
# Closing channel which has PTY has the effect of terminating
278
280
# any running processes started on that channel.
@@ -281,18 +283,20 @@ In some cases, such as when the remote command never terminates unless interrupt
281
283
# Join is not strictly needed here as channel has already been closed and
282
284
# command has finished, but is safe to use regardless.
283
285
client.join(output)
286
+
# Can now read output up to when the channel was closed without blocking.
287
+
rest_of_stdout =list(output[0].stdout)
284
288
285
289
Without a PTY, a ``join`` call with a timeout will complete with timeout exception raised but the remote process will be left running as per SSH protocol specifications.
286
290
287
-
Furthermore, once reading output has timed out, it is necessary to restart the output generators as by Python design they only iterate once. This is done by ``client.reset_output_generators`` in the above example.
291
+
.. note::
288
292
289
-
Generator reset is also performed automatically by calls to ``join`` and does not need to be done manually when ``join`` is used after output reading.
293
+
Read timeout may be changed after ``run_command`` has been called by changing ``HostOutput.read_timeout`` for that particular host output.
290
294
291
295
.. note::
292
296
293
-
``join`` with a timeout forces output to be consumed as otherwise the pending output will keep the channel open and make it appear as if command has not yet finished.
297
+
When output from commands is not needed, it is best to use ``client.join(consume_output=True)`` so that output buffers are consumed automatically.
294
298
295
-
To capture output when using ``join`` with a timeout, gather output first before calling ``join``, making use of output timeout as well, and/or make use of :ref:`host logger` functionality.
299
+
If output is not read or automatically consumed by ``join`` output buffers will continually grow, resulting in increasing memory consumption while the client is running, though memory use rises very slowly.
296
300
297
301
298
302
Per-Host Configuration
@@ -320,19 +324,7 @@ In the above example, the client is configured to connect to hostname ``localhos
320
324
321
325
When using ``host_config``, the number of ``HostConfig`` entries must match the number of hosts in ``client.hosts``. An exception is raised on client initialisation if not.
322
326
323
-
324
-
.. note::
325
-
326
-
Currently only ``port``, ``user``, ``password`` and ``private_key`` ``HostConfig`` values are used.
327
-
328
-
329
-
.. note::
330
-
331
-
Proxy host configuration is currently per ``ParallelSSHClient`` and cannot yet be provided via per-host configuration.
332
-
Multiple clients can be used to make use of multiple proxy hosts.
333
-
334
-
This feature will be provided in future releases.
335
-
327
+
As of `2.2.0`, proxy configuration can also be provided in ``HostConfig``.
336
328
337
329
.. _per-host-cmds:
338
330
@@ -586,7 +578,7 @@ For example, to copy the local files ``['local_file_1', 'local_file_2']`` as rem
586
578
587
579
The client will copy ``local_file_1`` to ``host1`` as ``remote_file_1`` and ``local_file_2`` to ``host2`` as ``remote_file_2``.
588
580
589
-
Each item in ``copy_args`` list should be a dictionary as shown above. Number of ``copy_args`` must match length of ``client.hosts`` if provided or exception will be raised.
581
+
Each item in ``copy_args`` list should be a dictionary as shown above. Number of items in ``copy_args`` must match length of ``client.hosts`` if provided or exception will be raised.
590
582
591
583
``copy_remote_file``, ``scp_send`` and ``scp_recv`` may all be used in the same manner to configure remote and local file names per host.
592
584
@@ -605,6 +597,7 @@ If wanting to copy a file from a single remote host and retain the original file
Copy file name to clipboardExpand all lines: doc/quickstart.rst
+2-9Lines changed: 2 additions & 9 deletions
Original file line number
Diff line number
Diff line change
@@ -117,23 +117,16 @@ Standard output, aka ``stdout``, for a given :py:class:`HostOutput <pssh.output.
117
117
<line by line output>
118
118
<..>
119
119
120
-
There is nothing special needed to ensure output is available.
121
-
122
-
Please note that retrieving all of a command's standard output by definition requires that the command has completed.
123
-
124
-
Iterating over ``stdout`` for any host *to completion* will therefor *only complete* when that host's command has completed unless interrupted.
120
+
Iterating over ``stdout`` will only end when the remote command has finished unless interrupted.
125
121
126
122
The ``timeout`` keyword argument to ``run_command`` may be used to cause output generators to timeout if no output is received after the given number of seconds - see `join and output timeouts <advanced.html#join-and-output-timeouts>`_.
127
123
128
-
``stdout`` is a generator. Iterating over it will consume the remote standard output stream via the network as it becomes available. To retrieve all of stdout can wrap it with list, per below.
124
+
``stdout`` is a generator. To retrieve all of stdout can wrap it with list, per below.
129
125
130
126
.. code-block:: python
131
127
132
128
stdout =list(host_out.stdout)
133
129
134
-
.. warning::
135
-
136
-
This will store the entirety of stdout into memory.
0 commit comments