Commit Graph

263 Commits (master)

Author SHA1 Message Date
David Wilson dc3db49c5a issue #406: more leaked FDs when create_child() fails. 6 years ago
David Wilson 17631b0573 issue #406: parent: close extra_fd on failure too. 6 years ago
David Wilson b3841317dd issue #406: clean up FDs on failure explicitly
The previous approach was crap since it left e.g. socketpair instances
lying around for GC with their underlying FD already closed, coupled
with FD number reuse, led to random madness when GC finally runs.
6 years ago
David Wilson 375182b71b issue #406: don't leak side FDs on bootstrap failure. 6 years ago
David Wilson 14b389cb46 issue #406: don't leak FDs on failed child start. 6 years ago
David Wilson 804bacdadb docs: move most remaining docstrings back into *.py; closes #388
The remaining ones are decorators which don't seem to have an autodoc
equivlent.
6 years ago
David Wilson 1d32ed3b5a core: avoid shutdown() in IoLogger on WSL; closes #333. 6 years ago
David Wilson f2d288bb1e tests: ensure minify() result can be compiled for all of core. 6 years ago
David Wilson a7ee23719a issue #388: move a ton of documentation back into the source 6 years ago
David Wilson 0394dac2c7 docs: document RouteMonitor class. 6 years ago
David Wilson 71f9e84ab3 Add EOF error hints for LXC/LXD; closes #373. 6 years ago
David Wilson 22b4b186d7 issue #333: add versioning to EpollPoller too. 6 years ago
David Wilson 73cda2994f issue #333: add versioning, initial batch of poller tests
Now poller is start enough to know a start_receive() during an iteration
does not cause events yielded by that iteration to associate with the
wrong descriptor.

These changes are tangentially related to the associated ticket, but
event versioning is still the underlying issue.
6 years ago
David Wilson 58d0a45738 issue #76: quieten routing errors.
Receiving DEL_ROUTE without a corresponding ADD_ROUTE is now legit
behaviour, so don't print an error in this case.

Don't print an error for dropped messages if the reply_to indicates the
sender doesn't care about a response (dead and no_reply)
6 years ago
David Wilson fba52a0edf issue #76: add API for ansible_mitogen to get route list
Earlier commit moved Stream.routes attribute into a private map
belonging to RouteMonitor, to make upgrades smoother. This adds a new
accessor method to RouteMonitor.
6 years ago
David Wilson 431051f69b issue #76: parent: broadcast DEL_ROUTE to interested parties
Now rather than simply propagate DEL_ROUTE upwards towards the parent,
we broadcast it downward to any stream that ever sent a message toward
any of the routes that have just become disconnected.
6 years ago
David Wilson d7d40f1123 issue #76: reduce Context duplication during unpickling
When unpickling a context, arrange for there to be a single instance
representing that context, managed by the corresponding router. This
context_by_id() was already in use by parent.py, it just needs to move
down.

This to eventually reach the point where a single Context exists that
needs 'disconnect' fired on it, so all sleeping receivers are definitely
woken.
6 years ago
David Wilson 3aa5c4c53d issue #373: parse the child process wait status
Don't log the raw waitpid() result, convert it to a useful string first.
6 years ago
dw ad44ad16f1
Merge pull request #385 from moreati/python-3.x-cleanups
Test with Tox on Python 3.x
6 years ago
Alex Willmer 6da31c9dee docs: Remove unneeded backslash escapes
Python 3.x was emitting a DeprecationWarning. AFAICT there has been no
impact on the HTML rendering.
6 years ago
David Wilson 0fa5fe5559 parent: handle masters with blank sys.executable; closes #356. 6 years ago
Yannig Perré 6828926a36 Kubernetes connection support for mitogen. 6 years ago
David Wilson dfc67b89fd docs: some more cleanups
- add faulthandler/thread stacks to changelog.
- various api.rst cleanups.
- docs: explain chain_id in howitworks.
6 years ago
David Wilson 863c1b7597 parent: correct CallSpec name formatting for class methods. 6 years ago
David Wilson e241081cae ansible: stop sharing target temp_dir in runner.
This cannot work with delegate_to, since delegate_to permits multiple
concurrent tasks to be executing on the same target.
6 years ago
David Wilson 42d3f96d14 parent: do updates 6 years ago
David Wilson 43d9815f6d ansible: use CallChain everywhere.
This replaces the 'dump to logger' behaviour of pipelined calls from
before with a call chain that returns any exception on next synchronized
call.
6 years ago
David Wilson 4d3873c784 core: call chains v3: abstract it into a new CallChain class. 6 years ago
David Wilson a52f66328b parent: test fixes. 6 years ago
David Wilson a3957d6aaf parent: add Context.forget_chain(). 6 years ago
David Wilson 7d62a53264 issue #337: ssh: disabling PTYs round 2: make it automatic. 6 years ago
David Wilson c4c6ae88a4 parent: raise a descriptive error when openpty fails. 6 years ago
Jesse London 3453d4d7d0 Python 3 support for classmethod call targets
There were two problems with detection and handling of class methods as call targets in Python 3:

* Methods no longer define `im_self` -- this is now only `__self__`
* The `types` module no longer defines a `ClassType`

The universally-compatible (v2.6+) solution was to switch to using the `inspect` module -- whose interface has been stable -- and to checking the method attribute `__self__`.

(It doesn't hurt that `inspect` checks are more brief and we now no longer need the `types` module here.)
6 years ago
David Wilson 49f3a61164 parent: prevent subprocess.Popen.__del__ from calling waitpid().
Closes #253.
6 years ago
David Wilson ec8d759d46 docs: document one more. 6 years ago
David Wilson 442d88e3d7 docs: many more fixes/merges. 6 years ago
David Wilson 06e2e846c5 parent: don't generate illegal default remote names.
getpass.getuser() output may contain slashes, which must be avoided as
they break virtualenv when present in argv[0].

Closes #344.
6 years ago
David Wilson 81c8156965 Support LXD; closes #339. 6 years ago
David Wilson 22bab87821 issue #319: avoid TCSAFLUSH flag on WSL.
Closes #319.
6 years ago
David Wilson 56943d3141 issue #319: have cfsetraw() generate sensible flags.
Attempting to fix issue on WSL.

Closes #71
6 years ago
David Wilson 50a1bf6f22 issue #300: temporary workaround for shutdown issue.
Closes #300.
6 years ago
David Wilson 1171b06eb5 Merge remote-tracking branch 'origin/issue320' into dmw 6 years ago
David Wilson 76caf7d41d issue #320: ignore kqueue events marked KQ_EV_ERROR.
Since BasicStream.close() invokes _stop_transmit() followed by
os.close(), and KqueuePoller._stop_transmit() defers the unsubscription
until the IO loop resumes, kqueue generates an error event for the
associated FD, even though the changelist includes an unsubscription
command for the FD.

We could fix this by deferring close() until after the IO loop has run
once (simply by calling .defer()), but that generates extra wakeups for
no real reason.

Instead simply notice the error event and log it, rather than treating
it as a legitimate event.

Another approach to fixing this would be to process
_stop_receive()/_stop_transmit() eagerly, however that entails making
more syscalls.

Closes #320.
6 years ago
David Wilson f977be2868 issue #291: permit supplying a full Python argv. 6 years ago
David Wilson 336e90c5e3 parent: avoid needless quoting in Argv.
This just makes debug output a little more readable.
6 years ago
napkindrawing 745d72bb1d core: support for "doas" become_method 6 years ago
David Wilson 692275064b parent: fix TtyLogger str/unicode crash on 3.x. 6 years ago
David Wilson 29f15c236c core: remove needless size prefix from core_src_fd.
I think this is brainwrong held over from an early attempt to write the
duplicate copy of core_src on stdin.
6 years ago
David Wilson 8791d40081 parent: tidy up call_async() logging. 6 years ago
David Wilson 4ff47d6a93 parent: more 2/3x format fixes 6 years ago
David Wilson 6b4e047017 tests: 3.x parent_test fixes. 6 years ago
David Wilson 0422a8c263 parent: python_path setting depends on local or remote
For local, we want to default to the same Python version as the current
process. For remote, we want whatever is on offer.
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 d6126a9516 issue #275: parent/ssh: centralize EC0_MARKER and change it for ssh.py.
Must maintain a minimum buffer length prior to deciding whether we have
an interesting token, and 'EC0' is too short for that.
6 years ago
David Wilson fbd5837cf2 issue #275: parent: use TIOCSCTTY on Linux too.
This appears to be harmless, except for Python 2.6 on Linux/Travis,
where for some reason (some stdlib change?) simply opening the TTY is
insufficient.
6 years ago
David Wilson cfd2887292 issue #275: default to 'python' for default remote interpreter.
So we get 2.4/2.5/2.6/2.7/3.x.
6 years ago
David Wilson 884a72ee86 issue #277: core: move Darwin versioner check into first stage
The 'versioner.c' dodging check added in 0ef23d86 was wrong, since the
check occurred on the host machine, when the fix actually needs to apply
to the Darwin target.

Fixes ability to target OS X from a Red Hat controller, manifesting as
an error like:

    D mitogen: mitogen.parent.TtyLogStream('local.2472'):  'python(mitogen:dmw@localhost.localdomain:2449): realpath couldn\'t resolve "/usr/bin/python(mitogen:dmw@localhost.localdomain:2449)"'

The "realpath couldn't resolve" error comes from versioner.c:

    https://opensource.apple.com/source/perl/perl-104/versioner/versioner.c
6 years ago
David Wilson 0e958ea177 issue #278: tty logger Side constructed with incorrect Stream
Harmless, but produced the wrong log message prefix.
6 years ago
David Wilson b58603c7a4 issue #278: ssh: support ssh_debug_level option and log TTY output.
Now debug logs may be captured all the way through the connection.
6 years ago
David Wilson 2fbe1f1b54 Get integration tests running under 2.6.
Closes #270
Closes #273
6 years ago
David Wilson 9e78c20eba core/parent: add Context.call_no_reply(). 6 years ago
David Wilson f7d2eace08 tests: importer fixes 6 years ago
David Wilson 9492dbc4d7 parent: split out minify.py and add stub where master can install it.
This needs a cleaner mechanism to install it, at least this one is
documented.
6 years ago
David Wilson 469bde63c2 parent: fix log message ordering 6 years ago
David Wilson 3f595bbc7e issue #213: use import_module() in parent.py.
This dynamic import crap really needs to be ripped out of parent.py
again. Static imports work much better for the module loader too.
6 years ago
David Wilson d2714752ee docs: tidy ups 6 years ago
David Wilson ddf28987a0 master: split Select() into new module to reduce wire size.
service.py currently imports master.py(+parent.py) just to get Select().
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 7d0209d8de issue #249: have upgrade_router() upgrade the poller too.
Now when a child becomes a parent, it gets a new poller suitable for
many more children than was possible using select().
6 years ago
David Wilson 6d18ce81d8 issue #249: restore duplex behaviour for epoll
With epoll() there is only one kernel-side object per file descriptor,
which is why _control() is such a pain. Since we merge receive/transmit
watching into that single object, we must always test the mask for both
conditions when reading results.

Kqueue isn't/doesn't appear to be like this. The identity of a Kqueue
event is keyed on (fd, filter), and we register a separate event for
both transmit and receive, so the 'elif' in KqueuePoller.poll() does not
appear to need to change.

Previously, a FD marked for read+write would not indicate writeability
until it was no longer readable.
6 years ago
David Wilson 6b98818046 issue #249: epoll distinguishes between hangup and disconnect
..typical Linux, for certain descriptor types only. So our receive mask
must match both, and normalize it into a read event like every other
poller.
6 years ago
David Wilson 36a1024861 issue #249: port Latch to poller too.
This is probably going to suck for perf :/
6 years ago
David Wilson 1070dfae72 issue #249: fix iter_read() regression. 6 years ago
David Wilson dcf0aa351e issue #249: whoops, fix new poller timeouts. 6 years ago
David Wilson aa8f786413 issue #249: fix Poller.from_existing() for v2 API 6 years ago
David Wilson 5645629e5d issue #249: the new pollers must handle syscall restarts too. 6 years ago
David Wilson 4df020827d issue #249: explicitly close pollers when done. 6 years ago
David Wilson 9905f6d8b4 issue #249: make write_all() and iter_read() use PREFERRED_POLLER. 6 years ago
David Wilson b6124f8396 issue #249: EpollPoller v2. 6 years ago
David Wilson 9abcf63155 issue #249: Poller API v2 (BSD only).
Now it's BasicStream/Side-agnostic, so it can be reused for Latch and
iter_read().
6 years ago
David Wilson 7320c542df issue #249: EpollPoller() for Linux. 6 years ago
David Wilson bc7be1879d issue #249: initial poller implementation (BSD only) 6 years ago
David Wilson d1a22cb5d4 issue #186: parent: implement FORWARD_MODULE.
To support detach, we must be able to preload the target with every
module it will need prior to detachment. This implements the
intermediary part of the process (i.e. the Ansible fork parent) --
receiving LOAD_MODULE/FORWARD_MODULE pairs and ensuring they reach the
child.
6 years ago
David Wilson d65e047b12 issue #179: ec0_receive() and connect_bootstrap() should use deadline.
Now there is a single global deadline derived from ansible.cfg timeout=
value.
6 years ago
David Wilson 356647bef4 issue #132: initial unidirectional routing mode. 6 years ago
David Wilson 7f1060f54a issue #186: initial version of subtree detachment. 6 years ago
David Wilson 8bd34e1e28 ansible: gracefully report connection timeouts as StreamError. 6 years ago
David Wilson 3322eaef45 Basic "su" method. 6 years ago
David Wilson ff7fb00569 parent: return latch to wait() caller to allow graceful timeout 6 years ago
David Wilson 7316c08237 core: fix _tls_init() race.
The GIL could be lost between the check for an empty list and popping a
socket off the list. Previously _tls_init (per its name) used per-thread
storage, hence the bug.
6 years ago
David Wilson 7c5bbc5168 setns: support changing user.
To match existing third party plugin.
6 years ago
David Wilson 947d35649c parent: note exception machine's hostname.
For dumb situations where user (i.e. me) is trying to fix a problem in
the wrong place.
6 years ago
David Wilson e8b4c4e683 issue #223: implement setns connection type
machinectl does not support any sensible form of pipe to the child
process, so it is necessary to bypass it when talking to a systemd
container (see systemd/systemd#8850).

This can also form the basis for issue #223, where the post-fork
namespace switching dance required to connect to the Pythonless
container will be the same.
6 years ago
David Wilson 3196b6e7f7 Add FreeBSD jail support. 6 years ago
David Wilson b3d352c601 Add lxc container support. 6 years ago
David Wilson 1be03eb458 parent: change create_child interface.
To allow for additional arguments.
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 e56608ab91 parent: don't wait for SIGTERM to complete. 6 years ago
David Wilson cbe6be449e issue #201: parent: log a warning and work around race for now. 6 years ago
David Wilson 9fe14e841c parent: reap the child process if connection fails
For example if no response is received in :attr:`connect_timeout`
seconds, the child would be left running.
6 years ago
David Wilson 46a311165e issue #148: parent: prevent race in iter_read()
There is no guarantee on the ordering select() returns file descriptors.
So if, e.g. in the case of sudo_nonexistent.yml, sudo prints an error
to a single FD before exitting, there was previously no gurantee
iter_read() would read off the error before failing due to detecting
disconnect on any FD.

Now instead we keep reading while any non-disconnected FD exists.
6 years ago
David Wilson e43c6c531b Mostly implement hybrid TTY/socket mode for sudo and SSH.
Presently there is still no mechanism to add :attr:`tty_stream` to the
multiplexer after connection is successful, but for now it's not
expected that anything will be logged to it anyway.

Closes #148.
6 years ago
David Wilson c6284e00e9 Use subprocess to start child processes; closes #185. 6 years ago
David Wilson bdc76c8231 parent: do not attempt to reap child twice. 6 years ago
David Wilson 202ce0f641 Prevent construction of unicode Message.data
And fix one case of it in parent.py.
6 years ago
David Wilson cc980569a3 issue #159: initial context LRU implementation
Now Connection.close() *must* be called in the worker, to ensure the
reference count for a context drops correctly.

Remove 'discriminator' for now, I'm not using it for testing any more
and it complicated this code.

This code is a car crash, it needs rewritten again. Ideally some/most of
this behaviour could live on services.DeduplicatingService somehow, but
I couldn't come up with a sensible design.
6 years ago
David Wilson 4c8ec131f9 issue #16: initial smorgasbord of 3.x fixes. 6 years ago
David Wilson c4bef102fe issue #16: Python 2.4-3.x compatible exception handling. 6 years ago
David Wilson e5b784ed32 parent: reduce cutpaste
Unclear whether exec() is better or worse than __import__(), but at
least the semantics are correct.
6 years ago
David Wilson 813d139d48 Import v2.7.11 tokenize.py for use on older Pythons; closes #189.
It's worth note that 2.7.10 shipped with Sierra, managed to not notice
this due to using a Homebrew 2.7.14.
6 years ago
Alex Willmer 1bc32adad4 Issue #160: Cache minimize_source()
Before

```
python tests/bench/local.py
0 120.245933533
1 119.300842285
2 118.355035782
3 123.839855194
```

After

```
python tests/bench/local.py
0 66.3640499115
1 65.9508705139
2 72.4799633026
3 65.7958984375
```
6 years ago
Alex Willmer dc3f5730a2 Merge branch 'master' into eye-of-the-token-its-the-thrill-of-the-light 6 years ago
David Wilson cd098ef158 issue #183: re-raise StreamError in calling context.
This allows catching just StreamError regardless of via=None or
via=<context>. Deserves a more general solution, but it's easy to fix up
later.
6 years ago
Alex Willmer 48623763d6 minimize_source: Implement reindentation 6 years ago
Alex Willmer 556ee2aec6 minimize_source: Handling indentation
In the case that string(s) are replaced, any indent or dedent tags must
be re-inserted after the replacemnts.
6 years ago
Alex Willmer a1e9b9e8db Issue #160: Reimplement minimize_source as token filters
Benefits:

- More correct than re.sub()
- Better handling of trailing whitespace
- Recognises doc-strings regardless of quoting style

Limitations:

- Still not entirely correct
  - Creates a syntax error when function/class body is only a docstring
  - Doesn't handle indented docstrings yet
- Slower by 50x - 8-10 ms vs 0.2 ms for re.sub()
  - Not much scope for improving this, tokenize is 100% pure Python
- Complex state machine, harder to understand
- Higher line count in parent.py
- Untested with Mitogen parent on Python 2.x and child on Python 2.x+y

No change

- Only requires Python stdlib modules
6 years ago
David Wilson 6670cba41c Introduce handler policy functions; closes #138.
Now you can specify a function to add_handler() that authenticates the
message header, with has_parent_authority() and is_immediate_child()
built in.
6 years ago
David Wilson 1ff27ada49 Add maximum message size checks. Closes #151. 6 years ago
David Wilson 45b81009f3 parent: call TIOCSCTTY on FreeBSD. Closes #171 6 years ago
David Wilson adf527440f issue #155: parent: split out make_call_msg(). 6 years ago
David Wilson 52d980ad58 issue #155: fork: nop out get_boot_command, it's become quite expensive
-16% reduction in fork cost.
6 years ago
David Wilson 4dc001f496 parent: fire disconnect upon receiving DEL_ROUTE for context
This lets context.shutdown(wait=True) succeed in the master or any
parent.
6 years ago
David Wilson 41ae6623c6 issue #155: parent: generic name generation
Let us override a class attribute to specify prefix from fork.py, rather
than reimplement the same logic.
6 years ago
David Wilson 1155de85af issue #155: parent: propagate context name too.
This allows context_by_id() in the master to succeed in returning a
Context with a .name matching the context's name, needed for correct
logging.

Previously this would have logged the empty string, because the master
had no mechanism to know the name of a context created by a child.
6 years ago
David Wilson cba3347556 issue #155: move connection factories to parent.py. 6 years ago
David Wilson 972f77c6b5 parent: have close_nonstandard_fds() ask OS for FD_MAX 6 years ago
David Wilson 48351a1889 issue #155: parent: support Context.shutdown(), reap children on exit.
This permits graceful shutdown of individual contexts, without tearing
down everything.

Update mitogen.parent.Stream to also wait for the child to exit, to
prevent the buildup of zombie processes. This introduces a blocking wait
for process exit on the Broker thread, let's see if we can get away with
it. Chances are reasonable that it'll cause needless hangs on heavily
loaded machines.
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 1a8ac9f4d1 issue #155: introduce mitogen.fork / Router.fork() 6 years ago
David Wilson 878e7a0902 issue #155: pass reference to existing Router into Stream constructor
This is a hacky layering violation, but it seems the simplest approach
for now: fork needs access to Router, in order to recover the existing
Importer instance.
6 years ago
David Wilson 21ef540cd8 issue #155: parent: split create_socketpair() from create_child() 6 years ago
David Wilson c31a177ebe issue #155: parent: split get_main_kwargs() from get_preamble() 6 years ago
David Wilson b51365209e parent: needless duplicate ADD_ROUTE message
notice_stream() does that already.
6 years ago
David Wilson 08612d4ca2 issue #155: fix call_function_test regression
It's entirely unclear how test_aborted_on_local_context_disconnect ever
passed, but it was broken by the previous commit.
6 years ago
David Wilson 54ff1c90fa issue #155: add DEL_ROUTE, propagate ADD_ROUTE upwards
* IDs are allocated by the parent responsible for contructing a new
  child, using ALLOCATE_ID to the master as necessary to allocate new ID
  ranges.

* ADD_ROUTE is sent up the tree rather than down. This permits
  construction of the new context to complete concurrent to parent
  contexts learning about its existence. Since all streams are strictly
  ordered, it's not possible for any parent to observe messages from the
  new context prior to arrival of an ADD_ROUTE from the parent notifying
  of its existence.

  If the new context, for example, implements an Ansible async task, its
  parent can start executing that without waiting for any synchronous
  confirmation from any parent or the master.

* Since routes propagate up, it's no longer possible for a plain
  non-parent child to ever receive ADD_ROUTE, so that code can be moved
  out of core.py and into parent.py (-0.2kb compressed).

* Add a .routes attribute to parent.Stream, and respond to disconnection
  signal on the stream by propagating DEL_ROUTE for any ADD_ROUTE ever
  received from that stream.

* Centralize route management in a new parent.RouteMonitor class
6 years ago
David Wilson f4ba66e3ee issue #155: allocate child IDs in batches of 1000.
Avoids a roundtrip for every fork.
6 years ago
David Wilson f241eac5ce parent: allow Python to determine its install prefix from argv[0]
Fixes support for virtualenv. Closes #152.
6 years ago
David Wilson eba12e2ee2 issue #139: bump kernel socket buffer size to 128kb
This allows us to write 128kb at a time towards SSH, but it doesn't help
with sudo, where the ancient tty layer is always used.
6 years ago
David Wilson 587256bbce issue #141: unify connect deadline handling
Now there is a single deadline calculated by the parent.Stream
constructor, and reused for both SSH and sudo.
6 years ago
Alex Willmer f95b37429f parent: Read preamble in first stage with os.fdopen()
SSH command size: 439 (+4 bytes)
Preamble size: 8941 (no change)

This _increases_ the size of the first stage, but
- Eliminates one of the two remaining uses of `sys`
- Reads the preamble as a byte-string, no call `.encode()`
   is needed on Python 3 before calling `_()`
6 years ago
Alex Willmer a62edd0b7e parent: Use os.execl in first stage
SSH command size: 435 (-4 bytes)
Preamble size: 8962 (no change)

os.execl is the same as os.execv, but it take a variable number of
arguments instead of a single sequence.
6 years ago
Alex Willmer 545652c34f parent: Trim whitespace & e variable in first stage
SSH command size: 439 (-4 bytes)
Preamble size: 8962 (no change)
6 years ago
Alex Willmer 0336de6722 parent: Combine first stage imports
SSH command size: 443 (-5 bytes)
Preamble size: 8962
6 years ago
Alex Willmer 48949cd249 parent: Use 'zip' alias of 'zlib' decoder
SSH command size: 448 (-5 bytes)
Preamble size: 8941 (no change)

NB: The 'zip' alias was absent in Python 3.x, until Python 3.4. This
should change be reverted if Python 3.0, 3.2, or 3.3 support is
required.
6 years ago
Alex Willmer 0f82f68fee parent: Precompute preamble sizes for first stage
SSH command size: 453 (no change)
Preamble size: 8941 (-5 bytes)
6 years ago
Alex Willmer dfd7070ceb parent: reuse _=codecs.decode alias in exec'd first stage
SSH command size: 453 (-8 bytes)
Preamble size: 8946 (no change)
6 years ago
Alex Willmer 53a8c59ae5 parent: Remove redudant os.exit() in first stage
SSH command size: 461 (-8 bytes)
Preamble size: 8946 (no change)

Since python has reached the last statement this should occur anyway.
6 years ago
Alex Willmer e051cf0ea0 parent: Unroll os.close() loop in first stage
SSH command size: 469 (-11 bytes)
Preamble size: 8946 (no change)

Although the source is longer, the _compressed_ length is reduced.
6 years ago
Alex Willmer 85f36f4cb1 parent: Prefer "import foo;x=foo" in first stage
SSH command size: 481 (down 1)
Preamble size: 8946 (no change)
6 years ago