From c9daa2ff30ce943b18305a4726ab3f9b8fb5c508 Mon Sep 17 00:00:00 2001 From: David Wilson Date: Thu, 5 Oct 2017 14:25:32 +0530 Subject: [PATCH] docs: move fakessh docs into Sphinx. --- docs/api.rst | 84 ++++++++++++++++++++++++++++++++++++++++++++-- mitogen/fakessh.py | 70 -------------------------------------- 2 files changed, 82 insertions(+), 72 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 558182b3..d7d80a70 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -173,11 +173,91 @@ contexts. mitogen.fakessh --------------- -.. automodule:: mitogen.fakessh +.. module:: mitogen.fakessh + +fakessh is a stream implementation that starts a local subprocess with its +environment modified such that ``PATH`` searches for `ssh` return an mitogen +implementation of the SSH command. When invoked, this tool arranges for the +command line supplied by the calling program to be executed in a context +already established by the master process, reusing the master's (possibly +proxied) connection to that context. + +This allows tools like `rsync` and `scp` to transparently reuse the connections +and tunnels already established by the host program to connect to a target +machine, without wasteful redundant SSH connection setup, 3-way handshakes, or +firewall hopping configurations, and enables these tools to be used in +impossible scenarios, such as over `sudo` with ``requiretty`` enabled. + +The fake `ssh` command source is written to a temporary file on disk, and +consists of a copy of the :py:mod:`mitogen.core` source code (just like any +other child context), with a line appended to cause it to connect back to the +host process over an FD it inherits. As there is no reliance on an existing +filesystem file, it is possible for child contexts to use fakessh. + +As a consequence of connecting back through an inherited FD, only one SSH +invocation is possible, which is fine for tools like `rsync`, however in future +this restriction will be lifted. + +Sequence: + + 1. ``fakessh`` Context and Stream created by parent context. The stream's + buffer has a :py:func:`_fakessh_main` :py:data:`CALL_FUNCTION + ` enqueued. + 2. Target program (`rsync/scp/sftp`) invoked, which internally executes + `ssh` from ``PATH``. + 3. :py:mod:`mitogen.core` bootstrap begins, recovers the stream FD + inherited via the target program, established itself as the fakessh + context. + 4. :py:func:`_fakessh_main` :py:data:`CALL_FUNCTION + ` is read by fakessh context, + + a. sets up :py:class:`IoPump` for stdio, registers + stdin_handle for local context. + b. Enqueues :py:data:`CALL_FUNCTION ` for + :py:func:`_start_slave` invoked in target context, + + i. the program from the `ssh` command line is started + ii. sets up :py:class:`IoPump` for `ssh` command line process's + stdio pipes + iii. returns `(control_handle, stdin_handle)` to + :py:func:`_fakessh_main` + + 5. :py:func:`_fakessh_main` receives control/stdin handles from from + :py:func:`_start_slave`, + + a. registers remote's stdin_handle with local :py:class:`IoPump`. + b. sends `("start", local_stdin_handle)` to remote's control_handle + c. registers local :py:class:`IoPump` with + :py:class:`mitogen.core.Broker`. + d. loops waiting for `local stdout closed && remote stdout closed` + + 6. :py:func:`_start_slave` control channel receives `("start", stdin_handle)`, + + a. registers remote's stdin_handle with local :py:class:`IoPump` + b. registers local :py:class:`IoPump` with + :py:class:`mitogen.core.Broker`. + c. loops waiting for `local stdout closed && remote stdout closed` + .. currentmodule:: mitogen.fakessh +.. function:: run (dest, router, args, daedline=None, econtext=None) -.. autofunction:: run + Run the command specified by the argument vector `args` such that ``PATH`` + searches for SSH by the command will cause its attempt to use SSH to + execute a remote program to be redirected to use mitogen to execute that + program using the context `dest` instead. + + :param mitogen.core.Context dest: + The destination context to execute the SSH command line in. + + :param mitogen.core.Router router: + + :param list[str] args: + Command line arguments for local program, e.g. + ``['rsync', '/tmp', 'remote:/tmp']`` + + :returns: + Exit status of the child process. Router Class diff --git a/mitogen/fakessh.py b/mitogen/fakessh.py index bff53dbb..b8bb98c8 100644 --- a/mitogen/fakessh.py +++ b/mitogen/fakessh.py @@ -1,55 +1,3 @@ -""" -fakessh is a stream implementation that starts a local subprocess with its -environment modified such that ``PATH`` searches for `ssh` return an mitogen -implementation of the SSH command. When invoked, this tool arranges for the -command line supplied by the calling program to be executed in a context -already established by the master process, reusing the master's (possibly -proxied) connection to that context. - -This allows tools like `rsync` and `scp` to transparently reuse the connections -and tunnels already established by the host program to connect to a target -machine, without wasteful redundant SSH connection setup, 3-way handshakes, -or firewall hopping configurations, and enables these tools to be used in -impossible scenarios, such as over `sudo` with ``requiretty`` enabled. - -The fake `ssh` command source is written to a temporary file on disk, and -consists of a copy of the :py:mod:`mitogen.core` source code (just like any -other child context), with a line appended to cause it to connect back to the -host process over an FD it inherits. As there is no reliance on an existing -filesystem file, it is possible for child contexts to use fakessh. - -As a consequence of connecting back through an inherited FD, only one SSH -invocation is possible, which is fine for tools like `rsync`, however in future -this restriction will be lifted. - -Sequence: - - 1. ``fakessh`` Context and Stream created by parent context. The stream's - buffer has a `_fakessh_main()` ``CALL_FUNCTION`` enqueued. - 2. Target program (`rsync/scp/sftp`) invoked, which internally executes - `ssh` from ``PATH``. - 3. :py:mod:`mitogen.core` bootstrap begins, recovers the stream FD - inherited via the target program, established itself as the fakessh - context. - 4. `_fakessh_main()` ``CALL_FUNCTION`` is read by fakessh context, - a. sets up :py:class:`mitogen.fakessh.IoPump` for stdio, registers - stdin_handle for local context. - b. Enqueues ``CALL_FUNCTION`` for `_start_slave()` invoked in target context, - i. the program from the `ssh` command line is started - ii. sets up :py:class:`mitogen.fakessh.IoPump` for `ssh` command - line process's stdio pipes - iii. returns `(control_handle, stdin_handle)` to `_fakessh_main()` - 5. `_fakessh_main()` receives control/stdin handles from from `_start_slave()`, - a. registers remote's stdin_handle with local IoPump - b. sends `("start", local_stdin_handle)` to remote's control_handle - c. registers local IoPump with Broker - d. loops waiting for 'local stdout closed && remote stdout closed' - 6. `_start_slave()` control channel receives `("start", stdin_handle)`, - a. registers remote's stdin_handle with local IoPump - b. registers local IoPump with Broker - c. loops waiting for 'local stdout closed && remote stdout closed' -""" - import getopt import inspect import logging @@ -333,24 +281,6 @@ def _fakessh_main(dest_context_id, econtext): @mitogen.core.takes_econtext @mitogen.core.takes_router def run(dest, router, args, deadline=None, econtext=None): - """ - Run the command specified by the argument vector `args` such that ``PATH`` - searches for SSH by the command will cause its attempt to use SSH to - execute a remote program to be redirected to use mitogen to execute that - program using the context `dest` instead. - - :param mitogen.core.Context dest: - The destination context to execute the SSH command line in. - - :param mitogen.core.Router router: - - :param list[str] args: - Command line arguments for local program, e.g. - ``['rsync', '/tmp', 'remote:/tmp']`` - - :returns: - Exit status of the child process. - """ if econtext is not None: mitogen.master.upgrade_router(econtext)