Fixes a dev branch glitch where a conditional could be applied to multiple tasks. Also improves the errors on parsing bad conditionals to make them less confusing to users.

This commit is contained in:
Michael DeHaan 2013-10-12 17:39:28 -04:00
parent a20d5462b6
commit 9ea54fcaaf
3 changed files with 24 additions and 6 deletions

View file

@ -401,15 +401,29 @@ class Play(object):
# ************************************************* # *************************************************
def _load_tasks(self, tasks, vars={}, default_vars={}, sudo_vars={}, additional_conditions=[], original_file=None, role_name=None): def _load_tasks(self, tasks, vars=None, default_vars=None, sudo_vars=None, additional_conditions=None, original_file=None, role_name=None):
''' handle task and handler include statements ''' ''' handle task and handler include statements '''
results = [] results = []
if tasks is None: if tasks is None:
# support empty handler files, and the like. # support empty handler files, and the like.
tasks = [] tasks = []
if additional_conditions is None:
additional_conditions = []
if vars is None:
vars = {}
if default_vars is None:
default_vars = {}
if sudo_vars is None:
sudo_vars = {}
old_conditions = list(additional_conditions)
for x in tasks: for x in tasks:
# prevent assigning the same conditions to each task on an include
included_additional_conditions = list(old_conditions)
if not isinstance(x, dict): if not isinstance(x, dict):
raise errors.AnsibleError("expecting dict; got: %s" % x) raise errors.AnsibleError("expecting dict; got: %s" % x)
@ -490,9 +504,11 @@ class Play(object):
for x in data: for x in data:
if 'include' in x: if 'include' in x:
x['role_name'] = new_role x['role_name'] = new_role
results += self._load_tasks(data, mv, default_vars, included_sudo_vars, included_additional_conditions, original_file=include_filename, role_name=new_role) loaded = self._load_tasks(data, mv, default_vars, included_sudo_vars, list(included_additional_conditions), original_file=include_filename, role_name=new_role)
results += loaded
elif type(x) == dict: elif type(x) == dict:
results.append(Task(self,x,module_vars=task_vars,default_vars=default_vars,additional_conditions=additional_conditions,role_name=role_name)) task = Task(self,x,module_vars=task_vars,default_vars=default_vars,additional_conditions=list(additional_conditions),role_name=role_name)
results.append(task)
else: else:
raise Exception("unexpected task type") raise Exception("unexpected task type")

View file

@ -165,6 +165,7 @@ def is_changed(result):
def check_conditional(conditional, basedir, inject, fail_on_undefined=False, jinja2=False): def check_conditional(conditional, basedir, inject, fail_on_undefined=False, jinja2=False):
if jinja2: if jinja2:
conditional = "jinja2_compare %s" % conditional conditional = "jinja2_compare %s" % conditional
@ -174,6 +175,7 @@ def check_conditional(conditional, basedir, inject, fail_on_undefined=False, jin
if conditional in inject and str(inject[conditional]).find('-') == -1: if conditional in inject and str(inject[conditional]).find('-') == -1:
conditional = inject[conditional] conditional = inject[conditional]
conditional = template.template(basedir, conditional, inject, fail_on_undefined=fail_on_undefined) conditional = template.template(basedir, conditional, inject, fail_on_undefined=fail_on_undefined)
original = conditional.replace("jinja2_compare ","")
# a Jinja2 evaluation that results in something Python can eval! # a Jinja2 evaluation that results in something Python can eval!
presented = "{%% if %s %%} True {%% else %%} False {%% endif %%}" % conditional presented = "{%% if %s %%} True {%% else %%} False {%% endif %%}" % conditional
conditional = template.template(basedir, presented, inject) conditional = template.template(basedir, presented, inject)
@ -188,13 +190,13 @@ def check_conditional(conditional, basedir, inject, fail_on_undefined=False, jin
elif conditional.find("is defined") != -1: elif conditional.find("is defined") != -1:
return False return False
else: else:
raise errors.AnsibleError("error while evaluating conditional: %s" % conditional) raise errors.AnsibleError("error while evaluating conditional: %s" % original)
elif val == "True": elif val == "True":
return True return True
elif val == "False": elif val == "False":
return False return False
else: else:
raise errors.AnsibleError("unable to evaluate conditional: %s" % conditional) raise errors.AnsibleError("unable to evaluate conditional: %s" % original)
if not isinstance(conditional, basestring): if not isinstance(conditional, basestring):
return conditional return conditional