Commit Graph

224 Commits (93342ba60c4891f31698057164712bcfc9552b22)

Author SHA1 Message Date
David Wilson 93342ba60c Normalize docstring formatting 5 years ago
David Wilson 65e31f63fe [stream-refactor] fix Py2.4 failure by implementing missing Timer method 5 years ago
David Wilson 4eecc08047 [stream-refactor] merge stdout+stderr when reporting EofError
Fixes sudo regression
5 years ago
David Wilson 93abbcaf7a [stream-refactor] fix crash in runner/forking_active.yml 5 years ago
David Wilson 8769c3ce24 [stream-refactor] more readable log string format 5 years ago
David Wilson d411003b64 [stream-refactor] dont doubly log last partial line 5 years ago
David Wilson 1fb3852fa6 [stream-refactor] fix crash when no stderr present. 5 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 0f7bbcece9 parent: remove unused Timer parameter. 5 years ago
David Wilson f66611dc83 parent: docstring improvements, cfmakeraw() regression. 5 years ago
David Wilson 70ff4b674c parent: discard cancelled events in TimerList.get_timeout().
Otherwise get_timeout() keeps broker alive via keep_alive() for a
cancelled timer during shutdown.
5 years ago
David Wilson f43f886c37 parent: various style cleanups, remove unused function. 5 years ago
David Wilson 3aded0ca95 issue #170: add TimerList docstrings. 5 years ago
David Wilson 2fbc77a155 issue #170: implement timers. 5 years ago
Jordan Webb 1a02a86331
Add buildah transport 5 years ago
David Wilson bd4d55dc90 issue #550: parent: add explanatory comment. 5 years ago
David Wilson 87c8ab4323 issue #550: fix up TTY ioctls on WSL 2016 Anniversary Update 5 years ago
David Wilson c1d73e1f4f issue #535: parent: add create_socketpair(size=..) parameter. 5 years ago
David Wilson 9bcd2ec56c issue #542: return of select poller, new selection logic 5 years ago
David Wilson 1f77d24bec Update copyright year everywhere. 5 years ago
David Wilson 7ff4e6694c issue #536: rework how 2.3-compatible simplejson is served
Regardless of the version of simplejson loaded in the master, load up
the ModuleResponder cache with our 2.4-compatible version.

To cope with simplejson being loaded due to modules like ec2_group that
try to import it before importing 'json', also update target.py to
remove it from the whitelist if a local 'json' module import succeeds.
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 cfb94e463f parent: PartialZlib docstrings. 5 years ago
David Wilson 9adc38d8ec parent: pre-cache bootstrap if possible.
When the interpreter is modern enough, use zlib.compressobj() to
pre-compress the unchanging parts of the bootstrap once, then use
compressobj.copy() to append just the context's config during stream
construction.

Before: 100 loops, best of 3: 5.81 msec per loop
After: 10000 loops, best of 3: 35.9 usec per loop

With 100 targets this is enough to knock 6 seconds off startup, at 500
targets it becomes half a minute.

Test 'program':
        python -m timeit -s '
                import mitogen.parent as p;
                import mitogen.master as m;
                r=m.Router();
                s=p.Stream(r, 0, max_message_size=1);
                r.broker.shutdown()'\
                \
                's.get_preamble()'
5 years ago
David Wilson 7ca927608c parent: synchronize get_core_source()
Single task 100 SSH target run, before:

        3533181 function calls (3533083 primitive calls) in 616.688 seconds
        User time (seconds): 32.52
        System time (seconds): 2.71
        Percent of CPU this job got: 64%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:54.88

After:

        451602 function calls (451504 primitive calls) in 570.746 seconds
        User time (seconds): 29.48
        System time (seconds): 2.81
        Percent of CPU this job got: 67%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:48.20
5 years ago
David Wilson e77048ec2d utils: pad out reset_affinity() and integrate with detach_popen() 5 years ago
David Wilson 568044438d parent: don't kill children when profiling is active. 5 years ago
David Wilson 407294cd79 issue #498: prevent crash on double 'disconnect' signal.
Fixes:

ERROR! [pid 1096] 23:31:48.363215 E mitogen: _broker_main() crashed
Traceback (most recent call last):
  File "/home/dmw/src/mitogen/mitogen/core.py", line 2917, in _broker_main
    self._loop_once()
  File "/home/dmw/src/mitogen/mitogen/core.py", line 2875, in _loop_once
    self._call(side.stream, func)
  File "/home/dmw/src/mitogen/mitogen/core.py", line 2860, in _call
    stream.on_disconnect(self)
  File "/home/dmw/src/mitogen/mitogen/parent.py", line 1161, in on_disconnect
    super(Stream, self).on_disconnect(broker)
  File "/home/dmw/src/mitogen/mitogen/core.py", line 1534, in on_disconnect
    fire(self, 'disconnect')
  File "/home/dmw/src/mitogen/mitogen/core.py", line 390, in fire
    func(*args, **kwargs)
  File "/home/dmw/src/mitogen/mitogen/parent.py", line 1794, in <lambda>
    func=lambda: self._on_stream_disconnect(stream),
  File "/home/dmw/src/mitogen/mitogen/parent.py", line 1810, in _on_stream_disconnect
    routes = self._routes_by_stream.pop(stream)
KeyError: mitogen.ssh.Stream('ssh.localhost:2236')
5 years ago
David Wilson 9aa845669c issue #413: don't double-propagate DEL_ROUTE to parent.
propagate_up() sends ADD_ROUTE and DEL_ROUTE

propagate_down() sends only DEL_ROUTE, but didn't bother checking if
up() had sent it already.

Fixes:

     ERROR! [pid 41060] 17:55:30.739159 E mitogen.ctx.ssh.localhost:
     mitogen: RouteMonitor(): received DEL_ROUTE for 6081 from
     mitogen.fork.Stream(u'fork.41142'), expected
     mitogen.core.Stream('parent')
5 years ago
David Wilson e2478dcb9f issue #498: wrap Router dict mutations in a lock 5 years ago
David Wilson ec789513dc ssh: tidy up logs and stream names. 5 years ago
David Wilson 4095358ea4 Merge commit '5bd6bd0' into envtest
* commit '5bd6bd0':
  parent: don't send messages on streams that no longer exist; closes #480
5 years ago
David Wilson d0075e7e50 parent: --with-pydebug bootstrap could fail due to corrupted stream
Due to first stage writin 'XXX refs' on exit. So close stderr as last
step of first stage.
5 years ago
David Wilson 2e4d7b15d7 parent: don't kill child when profiling=True 5 years ago
David Wilson 61297c24e5 issue #477: call_function_test fixes for 2.4. 5 years ago
David Wilson f1a712fad3 issue #477: Python<2.5 ioctl() request parameter was signed. 5 years ago
David Wilson 5bd6bd06d1 parent: don't send messages on streams that no longer exist; closes #480 5 years ago
David Wilson ffd46e9f1c issue #477: parent: make iter_read() log disconnect reason. 5 years ago
David Wilson 87d2af4c6e issue #477: polyfill partition() use in mitogen.parent. 5 years ago
David Wilson 07f1b9bdd0 issue #477: Python 2.5 needs next() polyfill too. 5 years ago
David Wilson 0ee8ee78b8 issue #477: Py2.4 cannot tolerate unicode kwargs. 5 years ago
David Wilson f3dae10fe1 issue #477: 2.4/2.5 had no better poller than poll(). 5 years ago
David Wilson 881dc7d5ca issue #477: more 2.4-compatible thread.get_ident() use. 5 years ago
David Wilson fb750edfa7 issue #61: fix bare except (reported by LGTM) 5 years ago
David Wilson 767737265a issue #61: add inverse comparison (reported by LGTM) 5 years ago
David Wilson 51bd35280a issue #61: remove duplicated method (reported by LGTM) 5 years ago
David Wilson ea9ef50b3c issue #415: replace default Poller with select.poll()
30% latency reduction for IPC.
5 years ago
David Wilson fd90834944 issue #408: fix test fallout. 5 years ago
David Wilson 51ac309647 issue #408: 2.4 compat: replace iter_read with explicit generator
Can't use yield inside try/finally on 2.4.
5 years ago