Commit Graph

84 Commits (3b63da670fe70d4272fcc2963d927a50322749b7)

Author SHA1 Message Date
David Wilson 3b63da670f Fix up another handful of LGTM errors. 5 years ago
David Wilson 57012e0f72 Add mitogen.core.now() and use it everywhere; closes #614. 5 years ago
David Wilson 5af6c9b26f issue #615: use FileService for target->controll file transfers 5 years ago
David Wilson cc02906d2a issue #547: fix service_test failures. 5 years ago
David Wilson 769a8b2015 issue #547: core/service: race/deadlock-free service pool init
The previous method of spinning up a transient thread to import the
service pool in a child context could deadlock with use of the importer
on the main thread. Therefore wake the main thread to handle import for
us, and use a regular Receiver to buffer messages to the stub, which is
inherited rather than replaced by the real service pool.
5 years ago
David Wilson 11c7e3f561 service: centralize fetching thread name, and tidy up logs 5 years ago
David Wilson 5298e87548 Split out and make readable more log messages across both packages 5 years ago
David Wilson 2fede49078 service: clean up log messages, especially at shutdown 5 years ago
David Wilson e93762b3db service: avoid taking another lock in the usual case 5 years ago
David Wilson 50bfe4c746 service: don't acquire lock when pool already initialized 5 years ago
David Wilson 9035884c77 ansible: abstract worker process model.
Move all details of broker/router setup out of connection.py, instead
deferring it to a WorkerModel class exported by process.py via
get_worker_model(). The running strategy can override the configured
worker model via _get_worker_model().

ClassicWorkerModel is installed by default, which implements the
extension's existing process model.

Add optional support for the third party setproctitle module, so
children have pretty names in ps output.

Add optional support for per-CPU multiplexers to classic runs.
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 874e75276f issue #589: ensure real FileService/PushFileService are in the docs 5 years ago
David Wilson ae8ba24f59 service: make service list optional.
Used by the new work.
5 years ago
David Wilson 06e52ca89f issue #535: wire mitogen.os_fork into Broker and Pool. 5 years ago
David Wilson 514d35fd10 issue #535: service: support Pool.defer() like Broker.defer() 5 years ago
David Wilson d4c0250083 issue #532: PushFileService race.
There has always been a race in PushFileService since given a parent
asked to forward modules to two children via some intermediary:

    interm = router.local()
    c1 = router.local(via=interm)
    c2 = router.local(via=interm)

    service.propagate_to(c1, 'foo/bar.py')
    service.propagate_to(c2, 'foo/bar.py')

Two calls will be emitted to 'interm':

    PushFileService.store_and_forward(c1, 'foo/bar.py', [blob])
    PushFileService.store(c2, 'foo/bar.py')

Which will be processed in-order up to the point where service pool
threads in 'interm' are woken to process the message.

While it is guaranteed store_and_forward() will be processed first, no
guarantee existed that its assigned pool thread would wake and take
_lock first, thus it was possible for forward() to win the race, and for
a request to arrive to forward a file that had not been placed in local
cache yet.

Here we get rid of SerializedInvoker entirely, as it is partially to
blame for hiding the race: SerializedInvoker can only ensure no two
messages are processed simultaneously, it cannot ensure the messages are
processed in their intended order.

Instead, teach forward() that it may be called before
store_and_forward(), and if that is the case, to place the forward
request on to _waiters alongside any local threads blocked in get().
5 years ago
David Wilson 1f77d24bec Update copyright year everywhere. 5 years ago
David Wilson 54835d4c9b service: fix PushFileService exception
[costapp]

ERROR! [pid 25135] 21:10:56.284733 E mitogen.ctx.ssh.35.200.203.48: mitogen: While calling no-reply method PushFileService.forward
Traceback (most recent call last):
  File "master:/home/dmw/src/mitogen/mitogen/service.py", line 260, in _invoke
    ret = method(**kwargs)
  File "master:/home/dmw/src/mitogen/mitogen/service.py", line 718, in forward
    self._forward(path, context)
  File "master:/home/dmw/src/mitogen/mitogen/service.py", line 633, in _forward
    stream = self.router.stream_by_id(context.context_id)
AttributeError: 'unicode' object has no attribute 'context_id'
^C [ERROR]: User interrupted execution
5 years ago
David Wilson 23d7a961e7 service: start pool shutdown on broker shutdown. 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 d6c4a983e1 service: PushFileService never recorded a file as sent.
Ansible modules were being resent continuously - but only the main
script module, and any custom modutils if any were present.

Wire footprint drops by ~1/3rd for a 500 task run of 'shell: hostname':

-rw-r--r-- 1 root root 584K Jan 31 22:06 500mito-before2
-rw-r--r-- 1 root root 434K Jan 31 22:04 500mito-filesbugonly
5 years ago
David Wilson 2399a9e621 service: use correct profile aggregation name. 5 years ago
David Wilson a8716972fb issue #477: 2.4 stat() returned int timestamps not float. 5 years ago
David Wilson dd86a157ff issue #477: polyfill partition() use in mitogen.service. 5 years ago
David Wilson d8490bc90a issue #477: 2.4.x compat fixes for mitogen.service. 5 years ago
David Wilson 58d8813c03 issue #477: Py2.4 lacks all(). 5 years ago
David Wilson cce1dbf3b1 tests: quieten a bunch of spam printed during run 5 years ago
David Wilson 1d97493fcd tests: fallout from #447. 5 years ago
David Wilson dc92e529bc service: unregister receiver at shutdown; closes #445. 5 years ago
David Wilson 04755c3321 issue #426: tighten up PushFileService types.
Bytes/Unicode mixing caused a hang, so prevent bytes entirely.
5 years ago
David Wilson d8b9634c85 issue #426: PushFileService missing to_text() call. 5 years ago
David Wilson 6713b90acc FileService: exceptions must be sent explicitly for no-reply methods
FileService should not be using no-reply at all.
6 years ago
David Wilson 98696af9f8 service: log failing path in FileService call. 6 years ago
David Wilson 2bbab585f7 service: fix NameError during no-reply call on 3.x. 6 years ago
David Wilson f20e0bbac1 service: Allow registering path prefixes with FileService.
e.g. service.register_prefix('/') disables all security checks.
6 years ago
David Wilson fbd7346d02 examples: import the_basics.py. 6 years ago
David Wilson 15ddecdb58 issue #391: FileService metadata dict keys must be Unicode.
This is a regression since moving FileService from a 2.6-compatible file
with unicode_literals set, to a <2.5-compatible file.
6 years ago
David Wilson 2a2dda8e39 issue #364: remove stat() caching. 6 years ago
David Wilson 4267014ca6 issue #364: clarify logged error when incorrect file size detected 6 years ago
David Wilson f2d288bb1e tests: ensure minify() result can be compiled for all of core. 6 years ago
David Wilson 530fd18e4c service: wake FileService client on file open failure.
Previously client would hang and excption woud be dumped to logger.
6 years ago
David Wilson 32751cd356 master: allow batching context switches for forward_modules()
-7 switches per task.
6 years ago
David Wilson 442d88e3d7 docs: many more fixes/merges. 6 years ago
David Wilson 5d67ce7746 service: service pool threads should respect _profile_hook. 6 years ago
David Wilson 3a8ea930d7 core: fix NameError in Latch.put(), FileService exception 6 years ago
David Wilson 5da371c5dd service: fix UnboundLocalError. 6 years ago
David Wilson 970f54de85 service: remove stray debug 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 205052ed90 service: fix SerializedInvoker CallError handling.
This cutpaste needs refactored. Ensure the caller receives a copy of the
exception.
6 years ago