From 565c6f1ae7acc7902e498b98c42a237b6d8daa05 Mon Sep 17 00:00:00 2001 From: Abhijit Menon-Sen Date: Tue, 22 Sep 2015 18:47:40 +0530 Subject: [PATCH] Make ansible_pipelining a connection variable SSH pipelining can be a significant performance improvement, but it will not work if sudoers is configured to requiretty. With this change, one could have pipelining enabled in ansible.cfg, but use sudo to turn off requiretty in a separate play (or task) where pipelining is disabled: - hosts: foo vars: ansible_pipelining: no tasks: - lineinfile: dest=/etc/sudoers line='Defaults requiretty' state=absent sudo_user: root (Note that sudoers has a complicated syntax, so the above lineinfile invocation may be too simplistic for production use; but the point is that a separate play can do something to disable requiretty.) --- lib/ansible/playbook/play_context.py | 4 +++- lib/ansible/plugins/action/__init__.py | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/ansible/playbook/play_context.py b/lib/ansible/playbook/play_context.py index 63bea3b53b..5c0c1a8735 100644 --- a/lib/ansible/playbook/play_context.py +++ b/lib/ansible/playbook/play_context.py @@ -51,6 +51,7 @@ MAGIC_VARIABLE_MAPPING = dict( port = ('ansible_ssh_port', 'ansible_port'), password = ('ansible_ssh_pass', 'ansible_password'), private_key_file = ('ansible_ssh_private_key_file', 'ansible_private_key_file'), + pipelining = ('ansible_ssh_pipelining', 'ansible_pipelining'), shell = ('ansible_shell_type',), become = ('ansible_become',), become_method = ('ansible_become_method',), @@ -133,6 +134,7 @@ class PlayContext(Base): _shell = FieldAttribute(isa='string') _ssh_extra_args = FieldAttribute(isa='string') _connection_lockfd= FieldAttribute(isa='int') + _pipelining = FieldAttribute(isa='bool', default=C.ANSIBLE_SSH_PIPELINING) # privilege escalation fields _become = FieldAttribute(isa='bool') @@ -427,7 +429,7 @@ class PlayContext(Base): ''' #FIXME: remove password? possibly add become/sudo settings - for special_var in ['ansible_connection', 'ansible_ssh_host', 'ansible_ssh_pass', 'ansible_ssh_port', 'ansible_ssh_user', 'ansible_ssh_private_key_file']: + for special_var in ['ansible_connection', 'ansible_ssh_host', 'ansible_ssh_pass', 'ansible_ssh_port', 'ansible_ssh_user', 'ansible_ssh_private_key_file', 'ansible_ssh_pipelining']: if special_var not in variables: for prop, varnames in MAGIC_VARIABLE_MAPPING.items(): if special_var in varnames: diff --git a/lib/ansible/plugins/action/__init__.py b/lib/ansible/plugins/action/__init__.py index d9ee141e0e..dc67432d7b 100644 --- a/lib/ansible/plugins/action/__init__.py +++ b/lib/ansible/plugins/action/__init__.py @@ -149,7 +149,7 @@ class ActionBase: if tmp and "tmp" in tmp: # tmp has already been created return False - if not self._connection.has_pipelining or not C.ANSIBLE_SSH_PIPELINING or C.DEFAULT_KEEP_REMOTE_FILES or self._play_context.become_method == 'su': + if not self._connection.has_pipelining or not self._play_context.pipelining or C.DEFAULT_KEEP_REMOTE_FILES or self._play_context.become_method == 'su': # tmp is necessary to store the module source code # or we want to keep the files on the target system return True @@ -367,7 +367,7 @@ class ActionBase: remote_module_path = self._connection._shell.join_path(tmp, module_name) # FIXME: async stuff here? - #if (module_style != 'new' or async_jid is not None or not self._connection._has_pipelining or not C.ANSIBLE_SSH_PIPELINING or C.DEFAULT_KEEP_REMOTE_FILES): + #if (module_style != 'new' or async_jid is not None or not self._connection._has_pipelining or not self._play_context.pipelining or C.DEFAULT_KEEP_REMOTE_FILES): if remote_module_path: self._display.debug("transferring module to remote") self._transfer_data(remote_module_path, module_data) @@ -385,7 +385,7 @@ class ActionBase: # FIXME: all of the old-module style and async stuff has been removed from here, and # might need to be re-added (unless we decide to drop support for old-style modules # at this point and rework things to support non-python modules specifically) - if self._connection.has_pipelining and C.ANSIBLE_SSH_PIPELINING and not C.DEFAULT_KEEP_REMOTE_FILES: + if self._connection.has_pipelining and self._play_context.pipelining and not C.DEFAULT_KEEP_REMOTE_FILES: in_data = module_data else: if remote_module_path: