Do not optimize with_items loop if the items are not strings
The code isn't sophisticated enough to understand lists and dicts yet. This mirrors how 1.9.x handled non-string items so its not a regression. One portion of a fix for #12976
This commit is contained in:
parent
da3087ffc4
commit
9e758d3d97
2 changed files with 30 additions and 17 deletions
|
@ -190,6 +190,12 @@ DEFAULT_BECOME_ASK_PASS = get_config(p, 'privilege_escalation', 'become_ask_pa
|
||||||
|
|
||||||
|
|
||||||
# PLUGINS
|
# PLUGINS
|
||||||
|
|
||||||
|
# Modules that can optimize with_items loops into a single call. Currently
|
||||||
|
# these modules must (1) take a "name" or "pkg" parameter that is a list. If
|
||||||
|
# the module takes both, bad things could happen.
|
||||||
|
# In the future we should probably generalize this even further
|
||||||
|
# (mapping of param: squash field)
|
||||||
DEFAULT_SQUASH_ACTIONS = get_config(p, DEFAULTS, 'squash_actions', 'ANSIBLE_SQUASH_ACTIONS', "apt, yum, pkgng, zypper, dnf", islist=True)
|
DEFAULT_SQUASH_ACTIONS = get_config(p, DEFAULTS, 'squash_actions', 'ANSIBLE_SQUASH_ACTIONS', "apt, yum, pkgng, zypper, dnf", islist=True)
|
||||||
# paths
|
# paths
|
||||||
DEFAULT_ACTION_PLUGIN_PATH = get_config(p, DEFAULTS, 'action_plugins', 'ANSIBLE_ACTION_PLUGINS', '~/.ansible/plugins/action:/usr/share/ansible/plugins/action', ispath=True)
|
DEFAULT_ACTION_PLUGIN_PATH = get_config(p, DEFAULTS, 'action_plugins', 'ANSIBLE_ACTION_PLUGINS', '~/.ansible/plugins/action:/usr/share/ansible/plugins/action', ispath=True)
|
||||||
|
|
|
@ -25,7 +25,7 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from ansible.compat.six import iteritems
|
from ansible.compat.six import iteritems, string_types
|
||||||
|
|
||||||
from ansible import constants as C
|
from ansible import constants as C
|
||||||
from ansible.errors import AnsibleError, AnsibleParserError, AnsibleUndefinedVariable, AnsibleConnectionFailure
|
from ansible.errors import AnsibleError, AnsibleParserError, AnsibleUndefinedVariable, AnsibleConnectionFailure
|
||||||
|
@ -230,22 +230,29 @@ class TaskExecutor:
|
||||||
(typically package management modules).
|
(typically package management modules).
|
||||||
'''
|
'''
|
||||||
if len(items) > 0 and self._task.action in self.SQUASH_ACTIONS:
|
if len(items) > 0 and self._task.action in self.SQUASH_ACTIONS:
|
||||||
final_items = []
|
if all(isinstance(o, string_types) for o in items):
|
||||||
name = self._task.args.pop('name', None) or self._task.args.pop('pkg', None)
|
final_items = []
|
||||||
for item in items:
|
name = self._task.args.pop('name', None) or self._task.args.pop('pkg', None)
|
||||||
variables['item'] = item
|
for item in items:
|
||||||
templar = Templar(loader=self._loader, shared_loader_obj=self._shared_loader_obj, variables=variables)
|
variables['item'] = item
|
||||||
if self._task.evaluate_conditional(templar, variables):
|
templar = Templar(loader=self._loader, shared_loader_obj=self._shared_loader_obj, variables=variables)
|
||||||
if templar._contains_vars(name):
|
if self._task.evaluate_conditional(templar, variables):
|
||||||
new_item = templar.template(name)
|
if templar._contains_vars(name):
|
||||||
final_items.append(new_item)
|
new_item = templar.template(name)
|
||||||
else:
|
final_items.append(new_item)
|
||||||
final_items.append(item)
|
else:
|
||||||
joined_items = ",".join(final_items)
|
final_items.append(item)
|
||||||
self._task.args['name'] = joined_items
|
self._task.args['name'] = final_items
|
||||||
return [joined_items]
|
return [final_items]
|
||||||
else:
|
# Right now we only optimize single entries. In the future we
|
||||||
return items
|
# could optimize more types:
|
||||||
|
# * lists can be squashed together
|
||||||
|
# * dicts could squash entries that match in all cases except the
|
||||||
|
# name or pkg field.
|
||||||
|
# Note: we really should be checking that the name or pkg field
|
||||||
|
# contains a template that expands with our with_items values.
|
||||||
|
# If it doesn't then we may break things
|
||||||
|
return items
|
||||||
|
|
||||||
def _execute(self, variables=None):
|
def _execute(self, variables=None):
|
||||||
'''
|
'''
|
||||||
|
|
Loading…
Reference in a new issue