1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Merge pull request #14168 from ansible/safer-squashing

Squashing was occuring even though pkgs didn't have a template that would be affected by squash
This commit is contained in:
Toshio Kuratomi 2016-01-28 10:57:43 -08:00
commit 605fb08487
2 changed files with 49 additions and 11 deletions

View file

@ -269,28 +269,39 @@ class TaskExecutor:
if all(isinstance(o, string_types) for o in items): if all(isinstance(o, string_types) for o in items):
final_items = [] final_items = []
name = self._task.args.pop('name', None) or self._task.args.pop('pkg', None) name = self._task.args.pop('name', None) or self._task.args.pop('pkg', None)
# The user is doing an upgrade or some other operation
# that doesn't take name or pkg. # This gets the information to check whether the name field
if name: # contains a template that we can squash for
template_no_item = template_with_item = None
if templar._contains_vars(name):
variables['item'] = '\0$'
template_no_item = templar.template(name, variables, cache=False)
variables['item'] = '\0@'
template_with_item = templar.template(name, variables, cache=False)
del variables['item']
# Check if the user is doing some operation that doesn't take
# name/pkg or the name/pkg field doesn't have any variables
# and thus the items can't be squashed
if name and (template_no_item != template_with_item):
for item in items: for item in items:
variables['item'] = item variables['item'] = item
if self._task.evaluate_conditional(templar, variables): if self._task.evaluate_conditional(templar, variables):
if templar._contains_vars(name):
new_item = templar.template(name, cache=False) new_item = templar.template(name, cache=False)
final_items.append(new_item) final_items.append(new_item)
else:
final_items.append(item)
self._task.args['name'] = final_items self._task.args['name'] = final_items
# Wrap this in a list so that the calling function loop
# executes exactly once
return [final_items] return [final_items]
else:
# Restore the name parameter
self._task.args['name'] = name
#elif: #elif:
# Right now we only optimize single entries. In the future we # Right now we only optimize single entries. In the future we
# could optimize more types: # could optimize more types:
# * lists can be squashed together # * lists can be squashed together
# * dicts could squash entries that match in all cases except the # * dicts could squash entries that match in all cases except the
# name or pkg field. # 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 return items
def _execute(self, variables=None): def _execute(self, variables=None):

View file

@ -198,21 +198,47 @@ class TestTaskExecutor(unittest.TestCase):
shared_loader_obj = mock_shared_loader, shared_loader_obj = mock_shared_loader,
) )
#
# No replacement
#
mock_task.action = 'yum'
new_items = te._squash_items(items=items, variables=job_vars)
self.assertEqual(new_items, ['a', 'b', 'c'])
mock_task.action = 'foo' mock_task.action = 'foo'
mock_task.args={'name': '{{item}}'}
new_items = te._squash_items(items=items, variables=job_vars) new_items = te._squash_items(items=items, variables=job_vars)
self.assertEqual(new_items, ['a', 'b', 'c']) self.assertEqual(new_items, ['a', 'b', 'c'])
mock_task.action = 'yum' mock_task.action = 'yum'
mock_task.args={'name': 'static'}
new_items = te._squash_items(items=items, variables=job_vars)
self.assertEqual(new_items, ['a', 'b', 'c'])
mock_task.action = 'yum'
mock_task.args={'name': '{{pkg_mgr}}'}
new_items = te._squash_items(items=items, variables=job_vars)
self.assertEqual(new_items, ['a', 'b', 'c'])
#
# Replaces
#
mock_task.action = 'yum'
mock_task.args={'name': '{{item}}'}
new_items = te._squash_items(items=items, variables=job_vars) new_items = te._squash_items(items=items, variables=job_vars)
self.assertEqual(new_items, [['a','c']]) self.assertEqual(new_items, [['a','c']])
mock_task.action = '{{pkg_mgr}}' mock_task.action = '{{pkg_mgr}}'
mock_task.args={'name': '{{item}}'}
new_items = te._squash_items(items=items, variables=job_vars) new_items = te._squash_items(items=items, variables=job_vars)
self.assertEqual(new_items, [['a', 'c']]) self.assertEqual(new_items, [['a', 'c']])
#
# Smoketests -- these won't optimize but make sure that they don't # Smoketests -- these won't optimize but make sure that they don't
# traceback either # traceback either
#
mock_task.action = '{{unknown}}' mock_task.action = '{{unknown}}'
mock_task.args={'name': '{{item}}'}
new_items = te._squash_items(items=items, variables=job_vars) new_items = te._squash_items(items=items, variables=job_vars)
self.assertEqual(new_items, ['a', 'b', 'c']) self.assertEqual(new_items, ['a', 'b', 'c'])
@ -220,6 +246,7 @@ class TestTaskExecutor(unittest.TestCase):
dict(name='b', state='present'), dict(name='b', state='present'),
dict(name='c', state='present')] dict(name='c', state='present')]
mock_task.action = 'yum' mock_task.action = 'yum'
mock_task.args={'name': '{{item}}'}
new_items = te._squash_items(items=items, variables=job_vars) new_items = te._squash_items(items=items, variables=job_vars)
self.assertEqual(new_items, items) self.assertEqual(new_items, items)