ansible/lib/ansible
Abhijit Menon-Sen f488de8599 Make sudo+requiretty and ANSIBLE_PIPELINING work together
Pipelining is a *significant* performance benefit, because each task can
be completed with a single SSH connection (vs. one ssh connection at the
start to mkdir, plus one sftp and one ssh per task).

Pipelining is disabled by default in Ansible because it conflicts with
the use of sudo if 'Defaults requiretty' is set in /etc/sudoers (as it
is on Red Hat) and su (which always requires a tty).

We can (and already do) make sudo/su happy by using "ssh -t" to allocate
a tty, but then the python interpreter goes into interactive mode and is
unhappy with module source being written to its stdin, per the following
comment from connections/ssh.py:

        # we can only use tty when we are not pipelining the modules.
        # piping data into /usr/bin/python inside a tty automatically
        # invokes the python interactive-mode but the modules are not
        # compatible with the interactive-mode ("unexpected indent"
        # mainly because of empty lines)

Instead of the (current) drastic solution of turning off pipelining when
we use a tty, we can instead use a tty but suppress the behaviour of the
Python interpreter to switch to interactive mode. The easiest way to do
this is to make its stdin *not* be a tty, e.g. with cat|python.

This works, but there's a problem: ssh will ignore -t if its input isn't
really a tty. So we could open a pseudo-tty and use that as ssh's stdin,
but if we then write Python source into it, it's all echoed back to us
(because we're a tty). So we have to use -tt to force tty allocation; in
that case, however, ssh puts the tty into "raw" mode (~ICANON), so there
is no good way for the process on the other end to detect EOF on stdin.
So if we do:

    echo -e "print('hello world')\n"|ssh -tt someho.st "cat|python"

…it hangs forever, because cat keeps on reading input even after we've
closed our pipe into ssh's stdin. We can get around this by writing a
special __EOF__ marker after writing in_data, and doing this:

    echo -e "print('hello world')\n__EOF__\n"|ssh -tt someho.st "sed -ne '/__EOF__/q' -e p|python"

This works fine, but in fact I use a clever python one-liner by mgedmin
to achieve the same effect without depending on sed (at the expense of a
much longer command line, alas; Python really isn't one-liner-friendly).

We also enable pipelining by default as a consequence.
2015-12-01 23:32:20 +05:30
..
cli ignore password flags in become conflict check 2015-12-01 08:18:31 -08:00
compat Bundle a new version of python-six for compatibility along with some code to make it easy for distributions to override the bunndled copy if they have a new enough version. 2015-10-16 08:21:28 -07:00
config Making the switch to v2 2015-05-03 21:47:26 -05:00
errors Clean up a few more pyflakes warnings 2015-10-19 11:20:21 -07:00
executor Make sure run_once tasks properly set variables for all active hosts 2015-11-30 11:27:05 -05:00
galaxy Fix traceback because we're using display from another object that no 2015-11-11 12:19:00 -08:00
inventory fix for dynamic (add_host) hosts not available in hostvars 2015-11-16 10:53:10 -08:00
module_utils boto is expecting that we pass it unicode strings. 2015-12-01 07:03:57 -08:00
modules Update submodule refs to go along with the StandardError change in ec2 moudles 2015-11-30 19:05:33 -08:00
new_inventory fix some warning of undefined name. 2015-10-09 12:43:42 +08:00
parsing Put in trap for args being None 2015-11-28 13:38:11 -05:00
playbook avoid inheritance issues with default=dict declaration at class level 2015-12-01 08:18:31 -08:00
plugins Make sudo+requiretty and ANSIBLE_PIPELINING work together 2015-12-01 23:32:20 +05:30
template Re-implement lookup wantlist 2015-11-29 23:45:54 -05:00
utils Finish up plugin porting to global display 2015-11-11 10:44:23 -08:00
vars Ensure port is (re)set for delegated-to hosts 2015-11-30 14:40:23 -05:00
__init__.py Add python3-compat boilerplate to all .py files in lib/ansible 2015-10-19 18:36:19 -07:00
constants.py Make sudo+requiretty and ANSIBLE_PIPELINING work together 2015-12-01 23:32:20 +05:30
test-requirements.txt Making the switch to v2 2015-05-03 21:47:26 -05:00