Fix the way host and group vars are loaded

* In the VariableManager, we were not properly tracking if a file
  had already been loaded, so we continuously append data to the end
  of the list there for host and group vars, meaning large sets of data
  are duplicated multiple times
* In the inventory, we were merging the host/group vars with the vars
  local to the host needlessly, as the VariableManager already handles that.
  This leads to needless duplication of the data and makes combining the
  vars in VariableManager take even longer.
This commit is contained in:
James Cammarata 2016-06-02 16:08:52 -04:00
parent 7287effb5c
commit 0ba9a6a875
2 changed files with 41 additions and 25 deletions

View file

@ -578,9 +578,6 @@ class Inventory(object):
if self.parser is not None:
vars = combine_vars(vars, self.parser.get_host_variables(host))
# Read host_vars/ files
vars = combine_vars(vars, self.get_host_vars(host))
return vars
def add_group(self, group):
@ -702,16 +699,14 @@ class Inventory(object):
if found_group_vars:
self._group_vars_files = self._group_vars_files.union(found_group_vars)
for group in self.groups.values():
#group.vars = combine_vars(group.vars, self.get_group_vars(group, new_pb_basedir=True))
group.vars = combine_vars(group.vars, self.get_group_vars(group))
self.get_group_vars(group)
found_host_vars = self._find_host_vars_files(self._playbook_basedir)
if found_host_vars:
self._host_vars_files = self._find_host_vars_files(self._playbook_basedir)
# get host vars from host_vars/ files
for host in self.get_hosts():
#host.vars = combine_vars(host.vars, self.get_host_vars(host, new_pb_basedir=True))
host.vars = combine_vars(host.vars, self.get_host_vars(host))
self.get_host_vars(host)
# invalidate cache
self._vars_per_host = {}
self._vars_per_group = {}
@ -783,11 +778,11 @@ class Inventory(object):
if host is None and any(map(lambda ext: group.name + ext in self._group_vars_files, C.YAML_FILENAME_EXTENSIONS)):
# load vars in dir/group_vars/name_of_group
base_path = to_unicode(os.path.abspath(os.path.join(to_bytes(basedir), b"group_vars/" + to_bytes(group.name))), errors='strict')
results = combine_vars(results, self._variable_manager.add_group_vars_file(base_path, self._loader))
self._variable_manager.add_group_vars_file(base_path, self._loader)
elif group is None and any(map(lambda ext: host.name + ext in self._host_vars_files, C.YAML_FILENAME_EXTENSIONS)):
# same for hostvars in dir/host_vars/name_of_host
base_path = to_unicode(os.path.abspath(os.path.join(to_bytes(basedir), b"host_vars/" + to_bytes(host.name))), errors='strict')
results = combine_vars(results, self._variable_manager.add_host_vars_file(base_path, self._loader))
self._variable_manager.add_host_vars_file(base_path, self._loader)
# all done, results is a dictionary of variables for this particular host.
return results

View file

@ -53,6 +53,11 @@ except ImportError:
VARIABLE_CACHE = dict()
HOSTVARS_CACHE = dict()
class AnsibleInventoryVarsData(dict):
def __init__(self, *args, **kwargs):
super(AnsibleInventoryVarsData, self).__init__(*args, **kwargs)
self.path = None
def preprocess_vars(a):
'''
Ensures that vars contained in the parameter passed in are
@ -549,8 +554,11 @@ class VariableManager:
if loader.path_exists(path):
data = loader.load_from_file(path)
name = self._get_inventory_basename(path)
return (name, data)
rval = AnsibleInventoryVarsData()
rval.path = path
if data is not None:
rval.update(data)
return rval
def add_host_vars_file(self, path, loader):
'''
@ -559,14 +567,21 @@ class VariableManager:
the extension, for matching against a given inventory host name
'''
(name, data) = self._load_inventory_file(path, loader)
if data:
if name not in self._host_vars_files:
self._host_vars_files[name] = []
self._host_vars_files[name].append(data)
return data
name = self._get_inventory_basename(path)
if name not in self._host_vars_files:
self._host_vars_files[name] = []
for entry in self._host_vars_files[name]:
if entry.path == path:
data = entry
break
else:
return dict()
data = self._load_inventory_file(path, loader)
if data:
self._host_vars_files[name].append(data)
return data
def add_group_vars_file(self, path, loader):
'''
@ -575,14 +590,20 @@ class VariableManager:
the extension, for matching against a given inventory host name
'''
(name, data) = self._load_inventory_file(path, loader)
if data:
if name not in self._group_vars_files:
self._group_vars_files[name] = []
self._group_vars_files[name].append(data)
return data
name = self._get_inventory_basename(path)
if name not in self._group_vars_files:
self._group_vars_files[name] = []
for entry in self._group_vars_files[name]:
if entry.path == path:
data = entry
break
else:
return dict()
data = self._load_inventory_file(path, loader)
if data:
self._group_vars_files[name].append(data)
return data
def clear_facts(self, hostname):
'''