Change the way we do with_items to make them happen next to each other in runner, which eliminates the problem of with_items and vars_files sometimes not playing nice with each other.
(Also a fix for the user module error handling when the user is not present at the time of the return. This can only really be caused by multiple ansible executions).pull/4420/head
parent
6c84ec72c6
commit
64c51ade1e
|
@ -104,17 +104,15 @@ class Play(object):
|
|||
for y in data:
|
||||
items = y.get('with_items',None)
|
||||
if items is None:
|
||||
items = [ '' ]
|
||||
items = [ ]
|
||||
elif isinstance(items, basestring):
|
||||
items = utils.varLookup(items, task_vars)
|
||||
for item in items:
|
||||
item = utils.template(item, task_vars)
|
||||
if self._has_vars_in(item):
|
||||
raise errors.AnsibleError("parse error: unbound variable in with_items: %s" % item)
|
||||
|
||||
mv = task_vars.copy()
|
||||
mv['item'] = item
|
||||
results.append(Task(self,y,module_vars=mv))
|
||||
#items = utils.varLookup(items, task_vars)
|
||||
if type(items) != list:
|
||||
raise errors.AnsibleError("with_items must be a list, got: %s" % items)
|
||||
# items = [ utils.template(item, task_vars) for item in items]
|
||||
mv = task_vars.copy()
|
||||
mv['items'] = items
|
||||
results.append(Task(self,y,module_vars=mv))
|
||||
|
||||
for x in results:
|
||||
if self.tags is not None:
|
||||
|
@ -245,6 +243,8 @@ class Play(object):
|
|||
if host is not None:
|
||||
filename3 = utils.template(filename2, self.playbook.SETUP_CACHE[host])
|
||||
filename4 = utils.path_dwim(self.playbook.basedir, filename3)
|
||||
if self._has_vars_in(filename4):
|
||||
return
|
||||
new_vars = utils.parse_yaml_from_file(filename4)
|
||||
if new_vars:
|
||||
if type(new_vars) != dict:
|
||||
|
|
|
@ -71,13 +71,12 @@ def _executor_hook(job_queue, result_queue):
|
|||
|
||||
class ReturnData(object):
|
||||
|
||||
__slots__ = [ 'result', 'comm_ok', 'executed_str', 'host' ]
|
||||
__slots__ = [ 'result', 'comm_ok', 'host' ]
|
||||
|
||||
def __init__(self, host=None, result=None, comm_ok=True, executed_str=''):
|
||||
def __init__(self, host=None, result=None, comm_ok=True):
|
||||
self.host = host
|
||||
self.result = result
|
||||
self.comm_ok = comm_ok
|
||||
self.executed_str = executed_str
|
||||
|
||||
if type(self.result) in [ str, unicode ]:
|
||||
self.result = utils.parse_json(self.result)
|
||||
|
@ -135,7 +134,7 @@ class Runner(object):
|
|||
conditional : only execute if this string, evaluated, is True
|
||||
callbacks : output callback class
|
||||
sudo : log in as remote user and immediately sudo to root
|
||||
module_vars : provides additional variables to a template. FIXME: factor this out
|
||||
module_vars : provides additional variables to a template.
|
||||
is_playbook : indicates Runner is being used by a playbook. affects behavior in various ways.
|
||||
inventory : inventory object, if host_list is not provided
|
||||
"""
|
||||
|
@ -279,10 +278,59 @@ class Runner(object):
|
|||
return args
|
||||
|
||||
# *****************************************************
|
||||
|
||||
|
||||
def _execute_module(self, conn, tmp, remote_module_path, args,
|
||||
async_jid=None, async_module=None, async_limit=None):
|
||||
|
||||
items = self.module_vars.get('items', None)
|
||||
if items is None or len(items) == 0:
|
||||
# executing a single item
|
||||
return self._execute_module_internal(
|
||||
conn, tmp, remote_module_path, args,
|
||||
async_jid=async_jid, async_module=async_module, async_limit=async_limit
|
||||
)
|
||||
else:
|
||||
# executing using with_items, so make multiple calls
|
||||
# TODO: refactor
|
||||
aggregrate = {}
|
||||
all_comm_ok = True
|
||||
all_changed = False
|
||||
all_failed = False
|
||||
results = []
|
||||
for x in items:
|
||||
self.module_vars['item'] = x
|
||||
result = self._execute_module_internal(
|
||||
conn, tmp, remote_module_path, args,
|
||||
async_jid=async_jid, async_module=async_module, async_limit=async_limit
|
||||
)
|
||||
results.append(result.result)
|
||||
if result.comm_ok == False:
|
||||
all_comm_ok = False
|
||||
break
|
||||
for x in results:
|
||||
if x.get('changed') == True:
|
||||
all_changed = True
|
||||
if (x.get('failed') == True) or (('rc' in x) and (x['rc'] != 0)):
|
||||
all_failed = True
|
||||
break
|
||||
msg = 'All items succeeded'
|
||||
if all_failed:
|
||||
msg = "One or more items failed."
|
||||
rd_result = dict(
|
||||
failed = all_failed,
|
||||
changed = all_changed,
|
||||
results = results,
|
||||
msg = msg
|
||||
)
|
||||
if not all_failed:
|
||||
del rd_result['failed']
|
||||
return ReturnData(host=conn.host, comm_ok=all_comm_ok, result=rd_result)
|
||||
|
||||
# *****************************************************
|
||||
|
||||
def _execute_module_internal(self, conn, tmp, remote_module_path, args,
|
||||
async_jid=None, async_module=None, async_limit=None):
|
||||
|
||||
''' runs a module that has already been transferred '''
|
||||
|
||||
inject = self.setup_cache.get(conn.host,{}).copy()
|
||||
|
@ -304,6 +352,7 @@ class Runner(object):
|
|||
|
||||
if type(args) == dict:
|
||||
args = utils.bigjson(args)
|
||||
|
||||
args = utils.template(args, inject, self.setup_cache)
|
||||
|
||||
module_name_tail = remote_module_path.split("/")[-1]
|
||||
|
@ -316,9 +365,7 @@ class Runner(object):
|
|||
|
||||
res = self._low_level_exec_command(conn, cmd, tmp, sudoable=True)
|
||||
|
||||
executed_str = "%s %s" % (module_name_tail, args.strip())
|
||||
|
||||
return ReturnData(host=conn.host, result=res, executed_str=executed_str)
|
||||
return ReturnData(host=conn.host, result=res)
|
||||
|
||||
# *****************************************************
|
||||
|
||||
|
@ -597,7 +644,6 @@ class Runner(object):
|
|||
|
||||
# modify file attribs if needed
|
||||
if exec_rc.comm_ok:
|
||||
exec_rc.executed_str = exec_rc.executed_str.replace("copy","template",1)
|
||||
return self._chain_file_module(conn, tmp, exec_rc, options)
|
||||
else:
|
||||
return exec_rc
|
||||
|
|
|
@ -54,6 +54,13 @@ def add_user_info(kwargs):
|
|||
if user_exists(name):
|
||||
kwargs['state'] = 'present'
|
||||
info = user_info(name)
|
||||
if info == False:
|
||||
if 'failed' in kwargs:
|
||||
kwargs['notice'] = "failed to look up user name: %s" % name
|
||||
else:
|
||||
kwargs['msg'] = "failed to look up user name: %s" % name
|
||||
kwargs['failed'] = True
|
||||
return kwargs
|
||||
kwargs['uid'] = info[2]
|
||||
kwargs['group'] = info[3]
|
||||
kwargs['comment'] = info[4]
|
||||
|
|
Loading…
Reference in New Issue