Commit Graph

41 Commits (master)

Author SHA1 Message Date
Alex Willmer 109feec6d5 Fix lints found by flake8 2 years ago
Alex Willmer 18c89de5a9 Remove unused module imports 2 years ago
David Wilson f039c81bb0 [stream-refactor] rename Process attrs, fix up more create_child_test 5 years ago
David Wilson 8d1b01d8ef Refactor Stream, introduce quasi-asynchronous connect, much more
Split Stream into many, many classes

  * mitogen.parent.Connection: Handles connection setup logic only.
    * Maintain references to stdout and stderr streams.
    * Manages TimerList timer to cancel connection attempt after
      deadline
    * Blocking setup code replaced by async equivalents running on the
      broker

  * mitogen.parent.Options: Tracks connection-specific options. This
    keeps the connection class small, but more importantly, it is
    generic to the future desire to build and execute command lines
    without starting a full connection.

  * mitogen.core.Protocol: Handles program behaviour relating to events
    on a stream. Protocol performs no IO of its own, instead deferring
    it to Stream and Side. This makes testing much easier, and means
    libssh can reimplement Stream and Side to reuse MitogenProtocol

  * mitogen.core.MitogenProtocol: Guts of the old Mitogen stream
    implementtion

  * mitogen.core.BufferedWriter: Guts of the old Mitogen buffered
    transmit implementation, made generic

  * mitogen.core.DelineatedProtocol: Guts of the old IoLogger, knows how
    to split up input and pass it on to a
    on_line_received()/on_partial_line_received() callback.

  * mitogen.parent.BootstrapProtocol: Asynchronous equivalent of the old
    blocking connect code. Waits for various prompts (MITO001 etc) and
    writes the bootstrap using a BufferedWriter. On success, switches
    the stream to MitogenProtocol.

  * mitogen.core.Message: move encoding parts of MitogenProtocol out to
    Message (where it belongs) and write a bunch of new tests for
    pickling.

  * The bizarre Stream.construct() is gone now, Option.__init__ is its
    own constructor. Should fix many LGTM errors.

* Update all connection methods:  Every connection method is updated to
  use async logic, defining protocols as required to handle interactive
  prompts like in SSH or su. Add new real integration tests for at least
  doas and su.

* Eliminate manual fd management: File descriptors are trapped in file
  objects at their point of origin, and Side is updated to use file
  objects rather than raw descriptors. This eliminates a whole class of
  bugs where unrelated FDs could be closed by the wrong component. Now
  an FD's open/closed status is fused to it everywhere in the library.

* Halve file descriptor usage: now FD open/close state is tracked by
  its file object, we don't need to duplicate FDs everywhere so that
  receive/transmit side can be closed independently. Instead both sides
  back on to the same file object. Closes #26, Closes #470.

* Remove most uses of dup/dup2: Closes #256. File descriptors are
  trapped in a common file object and shared among classes. The
  remaining few uses for dup/dup2 are as close to minimal as possible.

* Introduce mitogen.parent.Process: uniform interface for subprocesses
  created either via mitogen.fork or the subprocess module. Remove all
  the crap where we steal a pid from subprocess guts. Now we use
  subprocess to manage its processes as it should be. Closes #169 by
  using the new Timers facility to poll for a slow-to-exit subprocess.

* Fix su password race: Closes #363. DelineatedProtocol naturally
  retries partially received lines, preventing the cause of the original
  race.

* Delete old blocking IO utility functions
  iter_read()/write_all()/discard_until().

Closes #26
Closes #147
Closes #169
Closes #256
Closes #363
Closes #419
Closes #470
5 years ago
David Wilson 1f77d24bec Update copyright year everywhere. 5 years ago
David Wilson 0e193c223c issue #508: master: minify all Mitogen/ansible_mitogen sources.
Minify-safe files are marked with a magical "# !mitogen: minify_safe"
comment anywhere in the file, which activates the minifier. The result
is naturally cached by ModuleResponder, therefore lru_cache is gone too.

Given:

    import os, mitogen
    @mitogen.main()
    def main(router):
        c = router.ssh(hostname='k3')
        c.call(os.getpid)
        router.sudo(via=c)

SSH footprint drops from 56.2 KiB to 42.75 KiB (-23.9%)
Ansible "shell: hostname" drops 149.26 KiB to 117.42 KiB (-21.3%)
5 years ago
David Wilson 0fa5fe5559 parent: handle masters with blank sys.executable; closes #356. 6 years ago
David Wilson 410016ff47 Initial Python 3.x port work.
* ansible: use unicode_literals everywhere since it only needs to be
  compatible back to 2.6.
* compat/collections.py: delete this entirely and rip out the parts of
  functools that require it.
* Introduce serializable Kwargs dict subclass that translates keys to
  Unicode on instantiation.
* enable_debug_logging() must set _v/_vv globals.
* cStringIO does not exist in 3.x.
* Treat IOLogger and LogForwarder input as latin-1.
* Avoid ResourceWarnings in first stage by explicitly closing fps.
* Fix preamble_size.py syntax errors.
6 years ago
David Wilson d2714752ee docs: tidy ups 6 years ago
David Wilson 00edf0d66d core: have ExternalContext accept a config dict rather than kwargs.
The parameter lists had gotten out of control.
6 years ago
David Wilson 356647bef4 issue #132: initial unidirectional routing mode. 6 years ago
David Wilson 1fc7df5be5 Move canonical library version to __init__.py. 6 years ago
David Wilson 7c88e4d013 Move _DEAD into header, autogenerate dead messages
This change blocks off 2 common scenarios where a race condition is
upgraded to a hang, when the library could internally do better.

* Since we don't know whether the receiver of a `reply_to` is expecting
  a raw or pickled message, and since in the case of a raw reply, there
  is no way to signal "dead" to the receiver, override the reply_to
  field to explicitly mark a message as dead using a special handle.

  This replaces the serialized _DEAD sentinel value with a slightly
  neater interface, in the form of the reserved IS_DEAD handle, and
  enables an important subsequent change: when a context cannot route a
  message, it can send a generic 'dead' reply back towards the message
  source, ensuring any sleeping thread is woken with ChannelError.

  The use of this field could potentially be extended later on if
  additional flags are needed, but for now this seems to suffice.

* Teach Router._invoke() to reply with a dead message when it receives a
  message for an invalid local handle.

* Teach Router._async_route() to reply with a dead message when it
  receives an unroutable message.
6 years ago
David Wilson 1ff27ada49 Add maximum message size checks. Closes #151. 6 years ago
David Wilson 8676c40674 core: make _start_transmit / _stop_transmit async-only
For now at least, these APIs are always used in an asynchronous context,
so stop using the defer mechanism.
6 years ago
David Wilson 6a74edce6b issue #155: parent: move master.Context into parent.
The Context and Router APIs for constructing children and making
function calls should be available in every parent context, as user code
wants to have access to the same API.
6 years ago
David Wilson a956aa409e Remove duplicate set_cloexec calls everywhere
Now it's handled in Side() constructor, it can disappear elsewhere.
6 years ago
David Wilson ff617824a1 ansible: fix some flake8 errors
* Unused imports
* Undefined names in helpers.py
* Copyright header wrapping
6 years ago
David Wilson 8ec6ae1da0 importer: module whitelist/blacklist support
Hoped to avoid it, but it's the obvious solution for Ansible.
6 years ago
David Wilson 37e3151be8 fakessh: restore unpickle() semantics. 6 years ago
David Wilson b158259c86 Split up parent and master modules
Knocks 4kb off network footprint for a proxy connection.
6 years ago
David Wilson 326886832e Add license text everywhere. 6 years ago
Alex Willmer 3831ac360f Replace all calls to file() with open()
Although these are synonyms in Python 2.x, when using MyPy to typecheck
code use of file() causes spurious errors.

This commit also serves as one small step to Python 3.x compatibility,
since 3.x removes the file() builtin.
6 years ago
Alex Willmer 77d57a7e38 fakessh: Remove colon causing SyntaxError
fixes #58
6 years ago
David Wilson 658806bde8 fakessh: interruptible wait compatible with <2.7; closes #55 6 years ago
David Wilson c9daa2ff30 docs: move fakessh docs into Sphinx. 6 years ago
David Wilson 14783c75e8 issue #9: log warning when a cross-sibling CALL_FUNCTION occurs
First step to making it a fatal error.
6 years ago
David Wilson 9c4bf37cfc Remove final vestiges of context.key. 6 years ago
David Wilson 05cc74d142 core: Support profiling 6 years ago
David Wilson 400c971f4a fakessh: SSH server uses user's shell to parse command line. 6 years ago
David Wilson a9387b0504 core: remove pointless eval() of ARGV0 environment variable. 6 years ago
David Wilson 769ece2514 fakessh: improve logging slightly.
Makes it easier to match up reads/writes across log files by using
message byte count
6 years ago
David Wilson 76d1e66790 fakessh: use decorators rather than call_with_deadline(with_context=..) 6 years ago
David Wilson 8d4005c264 fakessh: fix non-master context ID allocation. 6 years ago
David Wilson bd8001d481 fakessh: Fix NameError. 6 years ago
David Wilson e7c70127bf fakessh: return child exit status 6 years ago
David Wilson 77b8d28c68 fakessh: Use local process's sys.executable. 6 years ago
David Wilson 175fe7a4e1 fakessh: IoPump() doesn't need Process reference. 6 years ago
David Wilson 8dad396e27 Make subsystem requests die with a useful error. 6 years ago
David Wilson 4f50707b82 core: support takes_econtext and takes_router decorators. 6 years ago
David Wilson e7ff6259a3 Initial commit. 6 years ago