Fixing more v2 issues with integration tests

This commit is contained in:
James Cammarata 2015-01-26 23:41:02 -06:00
parent 6f5d18a20e
commit bbd08cd0e2
7 changed files with 58 additions and 25 deletions

View file

@ -70,7 +70,10 @@ class PlaybookExecutor:
for batch in self._get_serialized_batches(new_play):
if len(batch) == 0:
raise AnsibleError("No hosts matched the list specified in the play", obj=play._ds)
self._tqm._callback.playbook_on_play_start(new_play.name)
self._tqm._callback.playbook_on_no_hosts_matched()
result = 0
break
# restrict the inventory to the hosts in the serialized batch
self._inventory.restrict_to_hosts(batch)
# and run it...

View file

@ -66,6 +66,7 @@ class DataLoader():
a JSON or YAML string.
'''
#print("in load, data is: %s (%s)" % (data, type(data)))
try:
# we first try to load this data as JSON
return json.loads(data)
@ -108,6 +109,8 @@ class DataLoader():
def _safe_load(self, stream, file_name=None):
''' Implements yaml.safe_load(), except using our custom loader class. '''
#print("stream is: %s" % stream)
#print("file name is: %s" % file_name)
loader = AnsibleLoader(stream, file_name)
try:
return loader.get_single_data()

View file

@ -39,8 +39,20 @@ from ansible.plugins import module_loader
from ansible.utils.vars import combine_vars
__all__ = ['Role', 'ROLE_CACHE']
__all__ = ['Role', 'ROLE_CACHE', 'hash_params']
# FIXME: this should be a utility function, but can't be a member of
# the role due to the fact that it would require the use of self
# in a static method. This is also used in the base class for
# strategies (ansible/plugins/strategies/__init__.py)
def hash_params(params):
s = set()
for k,v in params.iteritems():
if isinstance(v, dict):
s.update((k, hash_params(v)))
else:
s.update((k, v))
return frozenset(s)
# The role cache is used to prevent re-loading roles, which
# may already exist. Keys into this cache are the SHA1 hash
@ -84,7 +96,8 @@ class Role(Base, Conditional, Taggable):
# specified for a role as the key and the Role() object itself.
# We use frozenset to make the dictionary hashable.
hashed_params = frozenset(role_include.get_role_params().iteritems())
#hashed_params = frozenset(role_include.get_role_params().iteritems())
hashed_params = hash_params(role_include.get_role_params())
if role_include.role in ROLE_CACHE:
for (entry, role_obj) in ROLE_CACHE[role_include.role].iteritems():
if hashed_params == entry:

View file

@ -57,7 +57,7 @@ class CallbackModule(CallbackBase):
msg = "ok: [%s]" % result._host.get_name()
color = 'green'
if self._display._verbosity > 0 or 'verbose_always' in result._result:
if (self._display._verbosity > 0 or 'verbose_always' in result._result) and result._task.action != 'setup':
indent = None
if 'verbose_always' in result._result:
indent = 4
@ -97,7 +97,7 @@ class CallbackModule(CallbackBase):
pass
def playbook_on_no_hosts_matched(self):
pass
self._display.display("skipping: no hosts matched", color='cyan')
def playbook_on_no_hosts_remaining(self):
self._print_banner("NO MORE HOSTS LEFT")

View file

@ -28,7 +28,7 @@ from ansible.inventory.host import Host
from ansible.inventory.group import Group
from ansible.playbook.helpers import compile_block_list
from ansible.playbook.role import ROLE_CACHE
from ansible.playbook.role import ROLE_CACHE, hash_params
from ansible.plugins import module_loader
from ansible.utils.debug import debug
@ -149,7 +149,8 @@ class StrategyBase:
# lookup the role in the ROLE_CACHE to make sure we're dealing
# with the correct object and mark it as executed
for (entry, role_obj) in ROLE_CACHE[task_result._task._role._role_name].iteritems():
hashed_entry = frozenset(task_result._task._role._role_params.iteritems())
#hashed_entry = frozenset(task_result._task._role._role_params.iteritems())
hashed_entry = hash_params(task_result._task._role._role_params)
if entry == hashed_entry :
role_obj._had_task_run = True

View file

@ -28,6 +28,7 @@ try:
except ImportError:
from sha import sha as sha1
from ansible import constants as C
from ansible.parsing import DataLoader
from ansible.plugins.cache import FactCache
from ansible.template import Templar
@ -77,6 +78,20 @@ class VariableManager:
def set_inventory(self, inventory):
self._inventory = inventory
def _combine_vars(self, a, b):
'''
Combines dictionaries of variables, based on the hash behavior
'''
# FIXME: do we need this from utils, or should it just
# be merged into this definition?
#_validate_both_dicts(a, b)
if C.DEFAULT_HASH_BEHAVIOUR == "merge":
return self._merge_dicts(a, b)
else:
return dict(a.items() + b.items())
def _merge_dicts(self, a, b):
'''
Recursively merges dict b into a, so that keys
@ -135,7 +150,7 @@ class VariableManager:
# first we compile any vars specified in defaults/main.yml
# for all roles within the specified play
for role in play.get_roles():
all_vars = self._merge_dicts(all_vars, role.get_default_vars())
all_vars = self._combine_vars(all_vars, role.get_default_vars())
if host:
# next, if a host is specified, we load any vars from group_vars
@ -144,49 +159,49 @@ class VariableManager:
# we merge in the special 'all' group_vars first, if they exist
if 'all' in self._group_vars_files:
all_vars = self._merge_dicts(all_vars, self._group_vars_files['all'])
all_vars = self._combine_vars(all_vars, self._group_vars_files['all'])
for group in host.get_groups():
group_name = group.get_name()
all_vars = self._merge_dicts(all_vars, group.get_vars())
all_vars = self._combine_vars(all_vars, group.get_vars())
if group_name in self._group_vars_files and group_name != 'all':
all_vars = self._merge_dicts(all_vars, self._group_vars_files[group_name])
all_vars = self._combine_vars(all_vars, self._group_vars_files[group_name])
host_name = host.get_name()
if host_name in self._host_vars_files:
all_vars = self._merge_dicts(all_vars, self._host_vars_files[host_name])
all_vars = self._combine_vars(all_vars, self._host_vars_files[host_name])
# then we merge in vars specified for this host
all_vars = self._merge_dicts(all_vars, host.get_vars())
all_vars = self._combine_vars(all_vars, host.get_vars())
# next comes the facts cache and the vars cache, respectively
all_vars = self._merge_dicts(all_vars, self._fact_cache.get(host.get_name(), dict()))
all_vars = self._combine_vars(all_vars, self._fact_cache.get(host.get_name(), dict()))
if play:
all_vars = self._merge_dicts(all_vars, play.get_vars())
all_vars = self._combine_vars(all_vars, play.get_vars())
templar = Templar(loader=loader, variables=all_vars)
for vars_file in play.get_vars_files():
try:
vars_file = templar.template(vars_file)
data = loader.load_from_file(vars_file)
all_vars = self._merge_dicts(all_vars, data)
all_vars = self._combine_vars(all_vars, data)
except:
# FIXME: get_vars should probably be taking a flag to determine
# whether or not vars files errors should be fatal at this
# stage, or just base it on whether a host was specified?
pass
for role in play.get_roles():
all_vars = self._merge_dicts(all_vars, role.get_vars())
all_vars = self._combine_vars(all_vars, role.get_vars())
if host:
all_vars = self._merge_dicts(all_vars, self._vars_cache.get(host.get_name(), dict()))
all_vars = self._combine_vars(all_vars, self._vars_cache.get(host.get_name(), dict()))
if task:
if task._role:
all_vars = self._merge_dicts(all_vars, task._role.get_vars())
all_vars = self._merge_dicts(all_vars, task.get_vars())
all_vars = self._combine_vars(all_vars, task._role.get_vars())
all_vars = self._combine_vars(all_vars, task.get_vars())
all_vars = self._merge_dicts(all_vars, self._extra_vars)
all_vars = self._combine_vars(all_vars, self._extra_vars)
# FIXME: make sure all special vars are here
# Finally, we create special vars

View file

@ -108,15 +108,13 @@ def main(args):
if extra_vars_opt.startswith("@"):
# Argument is a YAML file (JSON is a subset of YAML)
data = loader.load_from_file(extra_vars_opt[1:])
extra_vars = combine_vars(extra_vars, data)
elif extra_vars_opt and extra_vars_opt[0] in '[{':
# Arguments as YAML
data = loader.load(extra_vars)
extra_vars = combine_vars(extra_vars, data)
data = loader.load(extra_vars_opt)
else:
# Arguments as Key-value
data = parse_kv(extra_vars_opt)
extra_vars = combine_vars(extra_vars, data)
extra_vars = combine_vars(extra_vars, data)
# FIXME: this should be moved inside the playbook executor code
only_tags = options.tags.split(",")