Complete streamlining of vars handling in playbooks and how those are templated to avoid

repeat template calls at playbook intialization time.
This commit is contained in:
Michael DeHaan 2013-04-06 10:45:09 -04:00
parent 1dfe60a6ea
commit 95f30f0def
3 changed files with 20 additions and 9 deletions

View file

@ -56,6 +56,9 @@ class Play(object):
self.vars_prompt = ds.get('vars_prompt', {}) self.vars_prompt = ds.get('vars_prompt', {})
self.playbook = playbook self.playbook = playbook
self.vars = self._get_vars() self.vars = self._get_vars()
self.vars_files = ds.get('vars_files', [])
self.basedir = basedir
self._update_vars_files_for_host(None)
self._ds = ds = utils.template(basedir, ds, self.vars) self._ds = ds = utils.template(basedir, ds, self.vars)
hosts = ds.get('hosts') hosts = ds.get('hosts')
@ -65,9 +68,7 @@ class Play(object):
hosts = ';'.join(hosts) hosts = ';'.join(hosts)
self.serial = int(ds.get('serial', 0)) self.serial = int(ds.get('serial', 0))
self.basedir = basedir
self.hosts = hosts self.hosts = hosts
self.vars_files = ds.get('vars_files', [])
self.name = ds.get('name', self.hosts) self.name = ds.get('name', self.hosts)
self._tasks = ds.get('tasks', []) self._tasks = ds.get('tasks', [])
self._handlers = ds.get('handlers', []) self._handlers = ds.get('handlers', [])
@ -83,7 +84,6 @@ class Play(object):
self.any_errors_fatal = ds.get('any_errors_fatal', False) self.any_errors_fatal = ds.get('any_errors_fatal', False)
self.roles = ds.get('roles', None) self.roles = ds.get('roles', None)
self._update_vars_files_for_host(None)
load_vars = {} load_vars = {}
if self.playbook.inventory.basedir() is not None: if self.playbook.inventory.basedir() is not None:

View file

@ -138,7 +138,6 @@ class Runner(object):
self.inventory = utils.default(inventory, lambda: ansible.inventory.Inventory(host_list)) self.inventory = utils.default(inventory, lambda: ansible.inventory.Inventory(host_list))
self.module_vars = utils.default(module_vars, lambda: {}) self.module_vars = utils.default(module_vars, lambda: {})
self.sudo_user = sudo_user
self.connector = connection.Connection(self) self.connector = connection.Connection(self)
self.conditional = conditional self.conditional = conditional
self.module_name = module_name self.module_name = module_name
@ -152,6 +151,7 @@ class Runner(object):
self.private_key_file = private_key_file self.private_key_file = private_key_file
self.background = background self.background = background
self.sudo = sudo self.sudo = sudo
self.sudo_user = sudo_user
self.sudo_pass = sudo_pass self.sudo_pass = sudo_pass
self.is_playbook = is_playbook self.is_playbook = is_playbook
self.environment = environment self.environment = environment
@ -175,7 +175,7 @@ class Runner(object):
# ensure we are using unique tmp paths # ensure we are using unique tmp paths
random.seed() random.seed()
# ***************************************************** # *****************************************************
def _complex_args_hack(self, complex_args, module_args): def _complex_args_hack(self, complex_args, module_args):

View file

@ -19,6 +19,7 @@ import os
import re import re
import codecs import codecs
import jinja2 import jinja2
import jinja2.meta as jinja2_meta
import yaml import yaml
import json import json
from ansible import errors from ansible import errors
@ -233,7 +234,8 @@ def template(basedir, varname, vars, lookup_fatal=True, depth=0, expand_lists=Tr
if isinstance(varname, basestring): if isinstance(varname, basestring):
if '{{' in varname or '{%' in varname: if '{{' in varname or '{%' in varname:
return template_from_string(basedir, varname, vars) res = template_from_string(basedir, varname, vars)
return res
m = _varFind(basedir, varname, vars, lookup_fatal, depth, expand_lists) m = _varFind(basedir, varname, vars, lookup_fatal, depth, expand_lists)
if not m: if not m:
return varname return varname
@ -409,11 +411,19 @@ def template_from_string(basedir, data, vars):
try: try:
if type(data) == str: if type(data) == str:
data = unicode(data, 'utf-8') data = unicode(data, 'utf-8')
environment = jinja2.Environment(trim_blocks=True) # undefined=J2Undefined) environment = jinja2.Environment(trim_blocks=True)
environment.filters.update(_get_filter_plugins()) environment.filters.update(_get_filter_plugins())
environment.template_class = J2Template
# perhaps a nicer way to do this
ast = environment.parse(data)
undeclared = jinja2_meta.find_undeclared_variables(ast)
for x in undeclared:
if x not in vars:
return data
# TODO: may need some way of using lookup plugins here seeing we aren't calling # TODO: may need some way of using lookup plugins here seeing we aren't calling
# the legacy engine, lookup() as a function, perhaps? # the legacy engine, lookup() as a function, perhaps?
environment.template_class = J2Template
try: try:
t = environment.from_string(data) t = environment.from_string(data)
@ -421,10 +431,11 @@ def template_from_string(basedir, data, vars):
if 'recursion' in str(re): if 'recursion' in str(re):
raise errors.AnsibleError("recursive loop detected in template string: %s" % data) raise errors.AnsibleError("recursive loop detected in template string: %s" % data)
else: else:
raise ree return data
res = jinja2.utils.concat(t.root_render_func(t.new_context(_jinja2_vars(basedir, vars, t.globals), shared=True))) res = jinja2.utils.concat(t.root_render_func(t.new_context(_jinja2_vars(basedir, vars, t.globals), shared=True)))
return res return res
except jinja2.exceptions.UndefinedError: except jinja2.exceptions.UndefinedError:
# this shouldn't happen due to undeclared check above
return data return data