From 8c3eb7ae4ac902b045620cef911059f0816ddbfb Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Thu, 11 Jun 2020 16:17:58 -0400 Subject: [PATCH] fix configurable pipelining (#69920) * fix configurable pipelining Co-authored-by: Sloane Hertel --- .../fragments/configurable_pipelining.yml | 2 ++ lib/ansible/plugins/action/__init__.py | 36 ++++++++++++------- lib/ansible/plugins/connection/ssh.py | 6 ++-- 3 files changed, 28 insertions(+), 16 deletions(-) create mode 100644 changelogs/fragments/configurable_pipelining.yml diff --git a/changelogs/fragments/configurable_pipelining.yml b/changelogs/fragments/configurable_pipelining.yml new file mode 100644 index 00000000000..d3430337bfa --- /dev/null +++ b/changelogs/fragments/configurable_pipelining.yml @@ -0,0 +1,2 @@ +bugfixes: + - match docs for ssh and ensure pipelining is configurable per connection plugin. diff --git a/lib/ansible/plugins/action/__init__.py b/lib/ansible/plugins/action/__init__.py index fc5cf9021d1..0a1f60dd69e 100644 --- a/lib/ansible/plugins/action/__init__.py +++ b/lib/ansible/plugins/action/__init__.py @@ -300,20 +300,30 @@ class ActionBase(with_metaclass(ABCMeta, object)): Determines if we are required and can do pipelining ''' - # any of these require a true - for condition in [ - self._connection.has_pipelining, - self._play_context.pipelining or self._connection.always_pipeline_modules, # pipelining enabled for play or connection requires it (eg winrm) - module_style == "new", # old style modules do not support pipelining - not C.DEFAULT_KEEP_REMOTE_FILES, # user wants remote files - not wrap_async or self._connection.always_pipeline_modules, # async does not normally support pipelining unless it does (eg winrm) - (self._connection.become.name if self._connection.become else '') != 'su', # su does not work with pipelining, - # FIXME: we might need to make become_method exclusion a configurable list - ]: - if not condition: - return False + try: + is_enabled = self._connection.get_option('pipelining') + except (KeyError, AttributeError, ValueError): + is_enabled = self._play_context.pipelining - return True + # winrm supports async pipeline + # TODO: make other class property 'has_async_pipelining' to separate cases + always_pipeline = self._connection.always_pipeline_modules + + # su does not work with pipelining + # TODO: add has_pipelining class prop to become plugins + become_exception = (self._connection.become.name if self._connection.become else '') != 'su' + + # any of these require a true + conditions = [ + self._connection.has_pipelining, # connection class supports it + is_enabled or always_pipeline, # enabled via config or forced via connection (eg winrm) + module_style == "new", # old style modules do not support pipelining + not C.DEFAULT_KEEP_REMOTE_FILES, # user wants remote files + not wrap_async or always_pipeline, # async does not normally support pipelining unless it does (eg winrm) + become_exception, + ] + + return all(conditions) def _get_admin_users(self): ''' diff --git a/lib/ansible/plugins/connection/ssh.py b/lib/ansible/plugins/connection/ssh.py index d7789bac2d0..222703d7009 100644 --- a/lib/ansible/plugins/connection/ssh.py +++ b/lib/ansible/plugins/connection/ssh.py @@ -200,12 +200,12 @@ DOCUMENTATION = ''' which is why this feature is disabled by default. env: - name: ANSIBLE_PIPELINING - #- name: ANSIBLE_SSH_PIPELINING + - name: ANSIBLE_SSH_PIPELINING ini: - section: defaults key: pipelining - #- section: ssh_connection - # key: pipelining + - section: ssh_connection + key: pipelining type: boolean vars: - name: ansible_pipelining