From 6c778acd91d08c465b6236d3ca9b1b2192153409 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Mon, 22 Apr 2013 22:03:39 -0400 Subject: [PATCH] Smush the braces in various places (hey, that rhymes) to avoid undo key=value splitting surprises in new template system. --- lib/ansible/playbook/__init__.py | 14 +++++++------- lib/ansible/playbook/play.py | 20 ++++++++++---------- lib/ansible/playbook/task.py | 4 ++++ lib/ansible/utils/template.py | 9 +++++---- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/lib/ansible/playbook/__init__.py b/lib/ansible/playbook/__init__.py index 8dbc3998f78..53898f7b9c6 100644 --- a/lib/ansible/playbook/__init__.py +++ b/lib/ansible/playbook/__init__.py @@ -18,7 +18,7 @@ import ansible.inventory import ansible.constants as C import ansible.runner -from ansible.utils import template +from ansible.utils.template import template, smush_braces from ansible import utils from ansible import errors import ansible.callbacks @@ -159,7 +159,7 @@ class PlayBook(object): # a playbook (list of plays) decided to include some other list of plays # from another file. The result is a flat list of plays in the end. - tokens = shlex.split(play['include']) + tokens = shlex.split(smush_braces(play['include'])) incvars = vars.copy() if 'vars' in play: @@ -175,9 +175,9 @@ class PlayBook(object): for t in tokens[1:]: (k,v) = t.split("=", 1) - incvars[k] = template.template(basedir, v, incvars) + incvars[k] = template(basedir, v, incvars) - included_path = utils.path_dwim(basedir, template.template(basedir, tokens[0], incvars)) + included_path = utils.path_dwim(basedir, template(basedir, tokens[0], incvars)) (plays, basedirs) = self._load_playbook_from_file(included_path, incvars) for p in plays: # support for parameterized play includes works by passing @@ -323,7 +323,7 @@ class PlayBook(object): ansible.callbacks.set_task(self.callbacks, task) ansible.callbacks.set_task(self.runner_callbacks, task) - self.callbacks.on_task_start(template.template(play.basedir, task.name, task.module_vars, lookup_fatal=False), is_handler) + self.callbacks.on_task_start(template(play.basedir, task.name, task.module_vars, lookup_fatal=False), is_handler) if hasattr(self.callbacks, 'skip_task') and self.callbacks.skip_task: return True @@ -366,7 +366,7 @@ class PlayBook(object): for host, results in results.get('contacted',{}).iteritems(): if results.get('changed', False): for handler_name in task.notify: - self._flag_handler(play, template.template(play.basedir, handler_name, task.module_vars), host) + self._flag_handler(play, template(play.basedir, handler_name, task.module_vars), host) return hosts_remaining @@ -381,7 +381,7 @@ class PlayBook(object): found = False for x in play.handlers(): - if handler_name == template.template(play.basedir, x.name, x.module_vars): + if handler_name == template(play.basedir, x.name, x.module_vars): found = True self.callbacks.on_notify(host, x.name) x.notified_by.append(host) diff --git a/lib/ansible/playbook/play.py b/lib/ansible/playbook/play.py index 6fae3fda3cc..b3a42a54be2 100644 --- a/lib/ansible/playbook/play.py +++ b/lib/ansible/playbook/play.py @@ -17,7 +17,7 @@ ############################################# -from ansible.utils import template +from ansible.utils.template import template, smush_braces from ansible import utils from ansible import errors from ansible.playbook.task import Task @@ -69,7 +69,7 @@ class Play(object): # tasks/handlers as they may have inventory scope overrides _tasks = ds.pop('tasks', []) _handlers = ds.pop('handlers', []) - ds = template.template(basedir, ds, self.vars) + ds = template(basedir, ds, self.vars) ds['tasks'] = _tasks ds['handlers'] = _handlers @@ -239,7 +239,7 @@ class Play(object): task_vars['_original_file'] = original_file if 'include' in x: - tokens = shlex.split(str(x['include'])) + tokens = shlex.split(smush_braces(str(x['include']))) items = [''] included_additional_conditions = list(additional_conditions) for k in x: @@ -247,7 +247,7 @@ class Play(object): plugin_name = k[5:] if plugin_name not in utils.plugins.lookup_loader: raise errors.AnsibleError("cannot find lookup plugin named %s for usage in with_%s" % (plugin_name, plugin_name)) - terms = template.template(self.basedir, x[k], task_vars) + terms = template(self.basedir, x[k], task_vars) items = utils.plugins.lookup_loader.get(plugin_name, basedir=self.basedir, runner=None).run(terms, inject=task_vars) elif k.startswith("when_"): included_additional_conditions.append(utils.compile_when_to_only_if("%s %s" % (k[5:], x[k]))) @@ -268,11 +268,11 @@ class Play(object): mv['item'] = item for t in tokens[1:]: (k,v) = t.split("=", 1) - mv[k] = template.template(self.basedir, v, mv) + mv[k] = template(self.basedir, v, mv) dirname = self.basedir if original_file: dirname = os.path.dirname(original_file) - include_file = template.template(dirname, tokens[0], mv) + include_file = template(dirname, tokens[0], mv) include_filename = utils.path_dwim(dirname, include_file) data = utils.parse_yaml_from_file(include_filename) results += self._load_tasks(data, mv, included_additional_conditions, original_file=include_filename) @@ -415,10 +415,10 @@ class Play(object): found = False sequence = [] for real_filename in filename: - filename2 = template.template(self.basedir, real_filename, self.vars) + filename2 = template(self.basedir, real_filename, self.vars) filename3 = filename2 if host is not None: - filename3 = template.template(self.basedir, filename2, inject) + filename3 = template(self.basedir, filename2, inject) filename4 = utils.path_dwim(self.basedir, filename3) sequence.append(filename4) if os.path.exists(filename4): @@ -448,10 +448,10 @@ class Play(object): else: # just one filename supplied, load it! - filename2 = template.template(self.basedir, filename, self.vars) + filename2 = template(self.basedir, filename, self.vars) filename3 = filename2 if host is not None: - filename3 = template.template(self.basedir, filename2, inject) + filename3 = template(self.basedir, filename2, inject) filename4 = utils.path_dwim(self.basedir, filename3) if self._has_vars_in(filename4): continue diff --git a/lib/ansible/playbook/task.py b/lib/ansible/playbook/task.py index 03e2ff00443..e4e001553d5 100644 --- a/lib/ansible/playbook/task.py +++ b/lib/ansible/playbook/task.py @@ -57,6 +57,10 @@ class Task(object): # code to allow for saying "modulename: args" versus "action: modulename args" if x in utils.plugins.module_finder: + + if 'include' in ds and isinstance(ds, basestring): + ds['include'] = template.smush_braces(ds['include']) + if 'action' in ds: raise errors.AnsibleError("multiple actions specified in task %s" % (ds.get('name', ds['action']))) if isinstance(ds[x], dict): diff --git a/lib/ansible/utils/template.py b/lib/ansible/utils/template.py index 54fb6313863..0e14d802b2c 100644 --- a/lib/ansible/utils/template.py +++ b/lib/ansible/utils/template.py @@ -437,7 +437,7 @@ def template_from_file(basedir, path, vars): res = res + '\n' return template(basedir, res, vars) -def _smush_braces(data): +def smush_braces(data): ''' smush Jinaj2 braces so unresolved templates like {{ foo }} don't get parsed weird by key=value code ''' while data.find('{{ ') != -1: data = data.replace('{{ ', '{{') @@ -448,7 +448,7 @@ def _smush_braces(data): def template_from_string(basedir, data, vars): ''' run a file through the (Jinja2) templating engine ''' - data = _smush_braces(data) + data = smush_braces(data) try: if type(data) == str: @@ -462,8 +462,9 @@ def template_from_string(basedir, data, vars): try: t = environment.from_string(data) - except RuntimeError, re: - if 'recursion' in str(re): + except Exception, e: + print "DEBUG: data = %s" % data + if 'recursion' in str(e): raise errors.AnsibleError("recursive loop detected in template string: %s" % data) else: return data