Following on from #419, the following work item remains:
Command line building. To handle Ansible's raw action, we need to be able to turn connection configs into command lines, and run those commands, including typing any passwords and suchlike as we do already.
Lots of pieces are in place for it now. Roughly what's left:
The per-connection BootstrapProtocol subclasses need to change, so they know somehow that they don't just run until MITO000 appears on the stream. They need to know how to feed stdin of the program with arbitrary data, and record its output in an 8-bit clean manner
Figure out if Connection wants to handle running custom commands, or it wants split up even more to handle just the 'start this stream and wait for it to disconnect' part.
Modify the existing HistoryMixin to handle collecting up a big chunk of potentially binary data, and maybe teach it about size limits or similar. Maybe re-work it so that it doesn't subclass DelimitedProtocol, but wraps the raw on_receive() instead.
Figure out the public API for it. Don't both with Router.ssh() etc. since they're going away anyway, make it something like mitogen.ssh.run(...), returning some kind of Receiver-like object that can be waited on etc.
Figure out how to make it work recursively using something like via=. This is needed for Ansible so raw: against a machine proxied via mitogen_via= is completely transparent.
Must preserve the ability for connection methods to continue typing passwords and understanding tool output as they do already.
Modify Ansible extension to use it. Connection.exec_command() seems to be where it wants to go, but this needs some heuristic or hard rule about when exec_command() should assume Python is installed on the remote and start a real connection, or when a raw command line should be run from the parent instead. It must always be consistent
Figure out how to enable Ansible 2.8's Python interpreter detection
FWIW, I just spent half an hour trying to figure out why ansible was complaining about not being able to find python when I was using the raw module. Mitogen turned out to be the issue. I've set "strategy: linear" in that playbook now. Thankfully it's a short one so mitogen didn't have much of an impact anyway.