|
|
@ -89,15 +89,15 @@ class Play(object):
|
|
|
|
self.vars_files = ds.get('vars_files', [])
|
|
|
|
self.vars_files = ds.get('vars_files', [])
|
|
|
|
if not isinstance(self.vars_files, list):
|
|
|
|
if not isinstance(self.vars_files, list):
|
|
|
|
raise errors.AnsibleError('vars_files must be a list')
|
|
|
|
raise errors.AnsibleError('vars_files must be a list')
|
|
|
|
self._update_vars_files_for_host(None)
|
|
|
|
processed_vars_files = self._update_vars_files_for_host(None)
|
|
|
|
|
|
|
|
|
|
|
|
# now we load the roles into the datastructure
|
|
|
|
# now we load the roles into the datastructure
|
|
|
|
self.included_roles = []
|
|
|
|
self.included_roles = []
|
|
|
|
ds = self._load_roles(self.roles, ds)
|
|
|
|
ds = self._load_roles(self.roles, ds)
|
|
|
|
|
|
|
|
|
|
|
|
# and finally re-process the vars files as they may have
|
|
|
|
# and finally re-process the vars files as they may have been updated
|
|
|
|
# been updated by the included roles
|
|
|
|
# by the included roles, but exclude any which have been processed
|
|
|
|
self.vars_files = ds.get('vars_files', [])
|
|
|
|
self.vars_files = utils.list_difference(ds.get('vars_files', []), processed_vars_files)
|
|
|
|
if not isinstance(self.vars_files, list):
|
|
|
|
if not isinstance(self.vars_files, list):
|
|
|
|
raise errors.AnsibleError('vars_files must be a list')
|
|
|
|
raise errors.AnsibleError('vars_files must be a list')
|
|
|
|
|
|
|
|
|
|
|
@ -765,27 +765,37 @@ class Play(object):
|
|
|
|
|
|
|
|
|
|
|
|
""" Render the raw filename into 3 forms """
|
|
|
|
""" Render the raw filename into 3 forms """
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# filename2 is the templated version of the filename, which will
|
|
|
|
|
|
|
|
# be fully rendered if any variables contained within it are
|
|
|
|
|
|
|
|
# non-inventory related
|
|
|
|
filename2 = template(self.basedir, filename, self.vars)
|
|
|
|
filename2 = template(self.basedir, filename, self.vars)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# filename3 is the same as filename2, but when the host object is
|
|
|
|
|
|
|
|
# available, inventory variables will be expanded as well since the
|
|
|
|
|
|
|
|
# name is templated with the injected variables
|
|
|
|
filename3 = filename2
|
|
|
|
filename3 = filename2
|
|
|
|
if host is not None:
|
|
|
|
if host is not None:
|
|
|
|
filename3 = template(self.basedir, filename2, inject)
|
|
|
|
filename3 = template(self.basedir, filename2, inject)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# filename4 is the dwim'd path, but may also be mixed-scope, so we use
|
|
|
|
|
|
|
|
# both play scoped vars and host scoped vars to template the filepath
|
|
|
|
if self._has_vars_in(filename3) and host is not None:
|
|
|
|
if self._has_vars_in(filename3) and host is not None:
|
|
|
|
# allow play scoped vars and host scoped vars to template the filepath
|
|
|
|
|
|
|
|
inject.update(self.vars)
|
|
|
|
inject.update(self.vars)
|
|
|
|
filename4 = template(self.basedir, filename3, inject)
|
|
|
|
filename4 = template(self.basedir, filename3, inject)
|
|
|
|
filename4 = utils.path_dwim(self.basedir, filename4)
|
|
|
|
filename4 = utils.path_dwim(self.basedir, filename4)
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
filename4 = utils.path_dwim(self.basedir, filename3)
|
|
|
|
filename4 = utils.path_dwim(self.basedir, filename3)
|
|
|
|
|
|
|
|
|
|
|
|
return filename2, filename3, filename4
|
|
|
|
return filename2, filename3, filename4
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def update_vars_cache(host, inject, data, filename):
|
|
|
|
def update_vars_cache(host, data, target_filename=None):
|
|
|
|
|
|
|
|
|
|
|
|
""" update a host's varscache with new var data """
|
|
|
|
""" update a host's varscache with new var data """
|
|
|
|
|
|
|
|
|
|
|
|
data = utils.combine_vars(inject, data)
|
|
|
|
|
|
|
|
self.playbook.VARS_CACHE[host] = utils.combine_vars(self.playbook.VARS_CACHE.get(host, {}), data)
|
|
|
|
self.playbook.VARS_CACHE[host] = utils.combine_vars(self.playbook.VARS_CACHE.get(host, {}), data)
|
|
|
|
self.playbook.callbacks.on_import_for_host(host, filename4)
|
|
|
|
if target_filename:
|
|
|
|
|
|
|
|
self.playbook.callbacks.on_import_for_host(host, target_filename)
|
|
|
|
|
|
|
|
|
|
|
|
def process_files(filename, filename2, filename3, filename4, host=None):
|
|
|
|
def process_files(filename, filename2, filename3, filename4, host=None):
|
|
|
|
|
|
|
|
|
|
|
@ -796,21 +806,19 @@ class Play(object):
|
|
|
|
if type(data) != dict:
|
|
|
|
if type(data) != dict:
|
|
|
|
raise errors.AnsibleError("%s must be stored as a dictionary/hash" % filename4)
|
|
|
|
raise errors.AnsibleError("%s must be stored as a dictionary/hash" % filename4)
|
|
|
|
if host is not None:
|
|
|
|
if host is not None:
|
|
|
|
if self._has_vars_in(filename2) and not self._has_vars_in(filename3):
|
|
|
|
target_filename = None
|
|
|
|
# running a host specific pass and has host specific variables
|
|
|
|
if self._has_vars_in(filename2):
|
|
|
|
# load into setup cache
|
|
|
|
if not self._has_vars_in(filename3):
|
|
|
|
update_vars_cache(host, inject, data, filename4)
|
|
|
|
target_filename = filename3
|
|
|
|
elif self._has_vars_in(filename3) and not self._has_vars_in(filename4):
|
|
|
|
else:
|
|
|
|
# handle mixed scope variables in filepath
|
|
|
|
target_filename = filename4
|
|
|
|
update_vars_cache(host, inject, data, filename4)
|
|
|
|
update_vars_cache(host, data, target_filename=target_filename)
|
|
|
|
|
|
|
|
else:
|
|
|
|
elif not self._has_vars_in(filename4):
|
|
|
|
self.vars = utils.combine_vars(self.vars, data)
|
|
|
|
# found a non-host specific variable, load into vars and NOT
|
|
|
|
# we did process this file
|
|
|
|
# the setup cache
|
|
|
|
return True
|
|
|
|
if host is not None:
|
|
|
|
# we did not process this file
|
|
|
|
self.vars.update(data)
|
|
|
|
return False
|
|
|
|
else:
|
|
|
|
|
|
|
|
self.vars = utils.combine_vars(self.vars, data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Enforce that vars_files is always a list
|
|
|
|
# Enforce that vars_files is always a list
|
|
|
|
if type(self.vars_files) != list:
|
|
|
|
if type(self.vars_files) != list:
|
|
|
@ -825,6 +833,7 @@ class Play(object):
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
inject = None
|
|
|
|
inject = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
processed = []
|
|
|
|
for filename in self.vars_files:
|
|
|
|
for filename in self.vars_files:
|
|
|
|
if type(filename) == list:
|
|
|
|
if type(filename) == list:
|
|
|
|
# loop over all filenames, loading the first one, and failing if none found
|
|
|
|
# loop over all filenames, loading the first one, and failing if none found
|
|
|
@ -835,7 +844,8 @@ class Play(object):
|
|
|
|
sequence.append(filename4)
|
|
|
|
sequence.append(filename4)
|
|
|
|
if os.path.exists(filename4):
|
|
|
|
if os.path.exists(filename4):
|
|
|
|
found = True
|
|
|
|
found = True
|
|
|
|
process_files(filename, filename2, filename3, filename4, host=host)
|
|
|
|
if process_files(filename, filename2, filename3, filename4, host=host):
|
|
|
|
|
|
|
|
processed.append(filename)
|
|
|
|
elif host is not None:
|
|
|
|
elif host is not None:
|
|
|
|
self.playbook.callbacks.on_not_import_for_host(host, filename4)
|
|
|
|
self.playbook.callbacks.on_not_import_for_host(host, filename4)
|
|
|
|
if found:
|
|
|
|
if found:
|
|
|
@ -844,14 +854,12 @@ class Play(object):
|
|
|
|
raise errors.AnsibleError(
|
|
|
|
raise errors.AnsibleError(
|
|
|
|
"%s: FATAL, no files matched for vars_files import sequence: %s" % (host, sequence)
|
|
|
|
"%s: FATAL, no files matched for vars_files import sequence: %s" % (host, sequence)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
# just one filename supplied, load it!
|
|
|
|
# just one filename supplied, load it!
|
|
|
|
filename2, filename3, filename4 = generate_filenames(host, inject, filename)
|
|
|
|
filename2, filename3, filename4 = generate_filenames(host, inject, filename)
|
|
|
|
if self._has_vars_in(filename4):
|
|
|
|
if self._has_vars_in(filename4):
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
process_files(filename, filename2, filename3, filename4, host=host)
|
|
|
|
if process_files(filename, filename2, filename3, filename4, host=host):
|
|
|
|
|
|
|
|
processed.append(filename)
|
|
|
|
|
|
|
|
|
|
|
|
# finally, update the VARS_CACHE for the host, if it is set
|
|
|
|
return processed
|
|
|
|
if host is not None:
|
|
|
|
|
|
|
|
self.playbook.VARS_CACHE.setdefault(host, {}).update(self.playbook.extra_vars)
|
|
|
|
|
|
|
|