Merge branch 'module_args-argument' of git://github.com/dhozac/ansible into devel
This commit is contained in:
commit
9778eaf4f9
9 changed files with 48 additions and 66 deletions
|
@ -188,10 +188,7 @@ class Runner(object):
|
||||||
|
|
||||||
''' runs a module that has already been transferred '''
|
''' runs a module that has already been transferred '''
|
||||||
|
|
||||||
if type(args) == dict:
|
(remote_module_path, is_new_style) = self._copy_module(conn, tmp, module_name, args, inject)
|
||||||
args = utils.jsonify(args,format=True)
|
|
||||||
|
|
||||||
(remote_module_path, is_new_style) = self._copy_module(conn, tmp, module_name, inject)
|
|
||||||
cmd = "chmod u+x %s" % remote_module_path
|
cmd = "chmod u+x %s" % remote_module_path
|
||||||
if self.sudo and self.sudo_user != 'root':
|
if self.sudo and self.sudo_user != 'root':
|
||||||
# deal with possible umask issues once sudo'ed to other user
|
# deal with possible umask issues once sudo'ed to other user
|
||||||
|
@ -270,7 +267,7 @@ class Runner(object):
|
||||||
# logic to decide how to run things depends on whether with_items is used
|
# logic to decide how to run things depends on whether with_items is used
|
||||||
|
|
||||||
if len(items) == 0:
|
if len(items) == 0:
|
||||||
return self._executor_internal_inner(host, inject, port)
|
return self._executor_internal_inner(host, self.module_name, self.module_args, inject, port)
|
||||||
else:
|
else:
|
||||||
# executing using with_items, so make multiple calls
|
# executing using with_items, so make multiple calls
|
||||||
# TODO: refactor
|
# TODO: refactor
|
||||||
|
@ -279,14 +276,9 @@ class Runner(object):
|
||||||
all_changed = False
|
all_changed = False
|
||||||
all_failed = False
|
all_failed = False
|
||||||
results = []
|
results = []
|
||||||
# Save module name and args since daisy-chaining can overwrite them
|
|
||||||
module_name = self.module_name
|
|
||||||
module_args = self.module_args
|
|
||||||
for x in items:
|
for x in items:
|
||||||
self.module_name = module_name
|
|
||||||
self.module_args = module_args
|
|
||||||
inject['item'] = x
|
inject['item'] = x
|
||||||
result = self._executor_internal_inner(host, inject, port)
|
result = self._executor_internal_inner(host, self.module_name, self.module_args, inject, port)
|
||||||
results.append(result.result)
|
results.append(result.result)
|
||||||
if result.comm_ok == False:
|
if result.comm_ok == False:
|
||||||
all_comm_ok = False
|
all_comm_ok = False
|
||||||
|
@ -307,27 +299,23 @@ class Runner(object):
|
||||||
|
|
||||||
# *****************************************************
|
# *****************************************************
|
||||||
|
|
||||||
def _executor_internal_inner(self, host, inject, port, is_chained=False):
|
def _executor_internal_inner(self, host, module_name, module_args, inject, port, is_chained=False):
|
||||||
''' decides how to invoke a module '''
|
''' decides how to invoke a module '''
|
||||||
|
|
||||||
# FIXME: temporary, need to refactor to pass as parameters versus reassigning
|
|
||||||
prev_module_name = self.module_name
|
|
||||||
prev_module_args = self.module_args
|
|
||||||
|
|
||||||
# special non-user/non-fact variables:
|
# special non-user/non-fact variables:
|
||||||
# 'groups' variable is a list of host name in each group
|
# 'groups' variable is a list of host name in each group
|
||||||
# 'hostvars' variable contains variables for each host name
|
# 'hostvars' variable contains variables for each host name
|
||||||
# ... and is set elsewhere
|
# ... and is set elsewhere
|
||||||
# 'inventory_hostname' is also set elsewhere
|
# 'inventory_hostname' is also set elsewhere
|
||||||
inject['groups'] = self.inventory.groups_list()
|
inject['groups'] = self.inventory.groups_list()
|
||||||
|
|
||||||
# allow module args to work as a dictionary
|
# allow module args to work as a dictionary
|
||||||
# though it is usually a string
|
# though it is usually a string
|
||||||
new_args = ""
|
new_args = ""
|
||||||
if type(self.module_args) == dict:
|
if type(module_args) == dict:
|
||||||
for (k,v) in self.module_args.iteritems():
|
for (k,v) in module_args.iteritems():
|
||||||
new_args = new_args + "%s='%s' " % (k,v)
|
new_args = new_args + "%s='%s' " % (k,v)
|
||||||
self.module_args = new_args
|
module_args = new_args
|
||||||
self.module_args = utils.template(self.basedir, self.module_args, inject)
|
|
||||||
|
|
||||||
def _check_conditional(conditional):
|
def _check_conditional(conditional):
|
||||||
def is_set(var):
|
def is_set(var):
|
||||||
|
@ -355,31 +343,25 @@ class Runner(object):
|
||||||
result = dict(failed=True, msg="FAILED: %s" % str(e))
|
result = dict(failed=True, msg="FAILED: %s" % str(e))
|
||||||
return ReturnData(host=host, comm_ok=False, result=result)
|
return ReturnData(host=host, comm_ok=False, result=result)
|
||||||
|
|
||||||
module_name = utils.template(self.basedir, self.module_name, inject)
|
module_name = utils.template(self.basedir, module_name, inject)
|
||||||
|
module_args = utils.template(self.basedir, module_args, inject)
|
||||||
|
|
||||||
tmp = ''
|
tmp = ''
|
||||||
if self.module_name != 'raw':
|
if self.module_name != 'raw':
|
||||||
tmp = self._make_tmp_path(conn)
|
tmp = self._make_tmp_path(conn)
|
||||||
result = None
|
result = None
|
||||||
|
|
||||||
handler = self.action_plugins.get(self.module_name, None)
|
handler = self.action_plugins.get(module_name, None)
|
||||||
if handler:
|
if handler:
|
||||||
result = handler.run(conn, tmp, module_name, inject)
|
result = handler.run(conn, tmp, module_name, module_args, inject)
|
||||||
else:
|
else:
|
||||||
if self.background == 0:
|
if self.background == 0:
|
||||||
result = self.action_plugins['normal'].run(conn, tmp, module_name, inject)
|
result = self.action_plugins['normal'].run(conn, tmp, module_name, module_args, inject)
|
||||||
else:
|
else:
|
||||||
result = self.action_plugins['async'].run(conn, tmp, module_name, inject)
|
result = self.action_plugins['async'].run(conn, tmp, module_name, module_args, inject)
|
||||||
|
|
||||||
if result.is_successful() and 'daisychain' in result.result:
|
if result.is_successful() and 'daisychain' in result.result:
|
||||||
self.module_name = result.result['daisychain']
|
result2 = self._executor_internal_inner(host, result.result['daisychain'], result.result.get('daisychain_args', {}), inject, port, is_chained=True)
|
||||||
if 'daisychain_args' in result.result:
|
|
||||||
self.module_args = result.result['daisychain_args']
|
|
||||||
result2 = self._executor_internal_inner(host, inject, port, is_chained=True)
|
|
||||||
|
|
||||||
# FIXME: remove this hack
|
|
||||||
self.module_name = prev_module_name
|
|
||||||
self.module_args = prev_module_args
|
|
||||||
|
|
||||||
changed = False
|
changed = False
|
||||||
if result.result.get('changed',False) or result2.result.get('changed',False):
|
if result.result.get('changed',False) or result2.result.get('changed',False):
|
||||||
|
@ -402,8 +384,8 @@ class Runner(object):
|
||||||
result.result['item'] = inject['item']
|
result.result['item'] = inject['item']
|
||||||
|
|
||||||
result.result['invocation'] = dict(
|
result.result['invocation'] = dict(
|
||||||
module_args=self.module_args,
|
module_args=module_args,
|
||||||
module_name=self.module_name
|
module_name=module_name
|
||||||
)
|
)
|
||||||
|
|
||||||
if is_chained:
|
if is_chained:
|
||||||
|
@ -478,21 +460,21 @@ class Runner(object):
|
||||||
|
|
||||||
# *****************************************************
|
# *****************************************************
|
||||||
|
|
||||||
def _copy_module(self, conn, tmp, module, inject):
|
def _copy_module(self, conn, tmp, module_name, module_args, inject):
|
||||||
''' transfer a module over SFTP, does not run it '''
|
''' transfer a module over SFTP, does not run it '''
|
||||||
|
|
||||||
if module.startswith("/"):
|
if module_name.startswith("/"):
|
||||||
raise errors.AnsibleFileNotFound("%s is not a module" % module)
|
raise errors.AnsibleFileNotFound("%s is not a module" % module_name)
|
||||||
|
|
||||||
# Search module path(s) for named module.
|
# Search module path(s) for named module.
|
||||||
for module_path in self.module_path.split(os.pathsep):
|
for module_path in self.module_path.split(os.pathsep):
|
||||||
in_path = os.path.expanduser(os.path.join(module_path, module))
|
in_path = os.path.expanduser(os.path.join(module_path, module_name))
|
||||||
if os.path.exists(in_path):
|
if os.path.exists(in_path):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise errors.AnsibleFileNotFound("module %s not found in %s" % (module, self.module_path))
|
raise errors.AnsibleFileNotFound("module %s not found in %s" % (module_name, self.module_path))
|
||||||
|
|
||||||
out_path = os.path.join(tmp, module)
|
out_path = os.path.join(tmp, module_name)
|
||||||
|
|
||||||
module_data = ""
|
module_data = ""
|
||||||
is_new_style=False
|
is_new_style=False
|
||||||
|
@ -502,7 +484,7 @@ class Runner(object):
|
||||||
if module_common.REPLACER in module_data:
|
if module_common.REPLACER in module_data:
|
||||||
is_new_style=True
|
is_new_style=True
|
||||||
module_data = module_data.replace(module_common.REPLACER, module_common.MODULE_COMMON)
|
module_data = module_data.replace(module_common.REPLACER, module_common.MODULE_COMMON)
|
||||||
encoded_args = "\"\"\"%s\"\"\"" % utils.template(self.basedir, self.module_args, inject).replace("\"","\\\"")
|
encoded_args = "\"\"\"%s\"\"\"" % module_args.replace("\"","\\\"")
|
||||||
module_data = module_data.replace(module_common.REPLACER_ARGS, encoded_args)
|
module_data = module_data.replace(module_common.REPLACER_ARGS, encoded_args)
|
||||||
|
|
||||||
# use the correct python interpreter for the host
|
# use the correct python interpreter for the host
|
||||||
|
@ -513,7 +495,7 @@ class Runner(object):
|
||||||
module_lines[0] = "#!%s" % interpreter
|
module_lines[0] = "#!%s" % interpreter
|
||||||
module_data = "\n".join(module_lines)
|
module_data = "\n".join(module_lines)
|
||||||
|
|
||||||
self._transfer_str(conn, tmp, module, module_data)
|
self._transfer_str(conn, tmp, module_name, module_data)
|
||||||
return (out_path, is_new_style)
|
return (out_path, is_new_style)
|
||||||
|
|
||||||
# *****************************************************
|
# *****************************************************
|
||||||
|
|
|
@ -32,12 +32,12 @@ class ActionModule(object):
|
||||||
def __init__(self, runner):
|
def __init__(self, runner):
|
||||||
self.runner = runner
|
self.runner = runner
|
||||||
|
|
||||||
def run(self, conn, tmp, module_name, inject=None):
|
def run(self, conn, tmp, module_name, module_args, inject=None):
|
||||||
''' handler for assemble operations '''
|
''' handler for assemble operations '''
|
||||||
|
|
||||||
# FIXME: since assemble is ported over to the use the new common logic, this method
|
# FIXME: since assemble is ported over to the use the new common logic, this method
|
||||||
# is actually unneccessary as it can decide to daisychain via it's own module returns.
|
# is actually unneccessary as it can decide to daisychain via it's own module returns.
|
||||||
# make assemble return daisychain_args and this will go away.
|
# make assemble return daisychain_args and this will go away.
|
||||||
|
|
||||||
return self.runner._execute_module(conn, tmp, 'assemble', self.runner.module_args, inject=inject).daisychain('file')
|
return self.runner._execute_module(conn, tmp, 'assemble', module_args, inject=inject).daisychain('file', module_args)
|
||||||
|
|
||||||
|
|
|
@ -32,16 +32,15 @@ class ActionModule(object):
|
||||||
def __init__(self, runner):
|
def __init__(self, runner):
|
||||||
self.runner = runner
|
self.runner = runner
|
||||||
|
|
||||||
def run(self, conn, tmp, module_name, inject):
|
def run(self, conn, tmp, module_name, module_args, inject):
|
||||||
''' transfer the given module name, plus the async module, then run it '''
|
''' transfer the given module name, plus the async module, then run it '''
|
||||||
|
|
||||||
# shell and command module are the same
|
# shell and command module are the same
|
||||||
module_args = self.runner.module_args
|
|
||||||
if module_name == 'shell':
|
if module_name == 'shell':
|
||||||
module_name = 'command'
|
module_name = 'command'
|
||||||
module_args += " #USE_SHELL"
|
module_args += " #USE_SHELL"
|
||||||
|
|
||||||
(module_path, is_new_style) = self.runner._copy_module(conn, tmp, module_name, inject)
|
(module_path, is_new_style) = self.runner._copy_module(conn, tmp, module_name, module_args, inject)
|
||||||
self.runner._low_level_exec_command(conn, "chmod a+rx %s" % module_path, tmp)
|
self.runner._low_level_exec_command(conn, "chmod a+rx %s" % module_path, tmp)
|
||||||
|
|
||||||
return self.runner._execute_module(conn, tmp, 'async_wrapper', module_args,
|
return self.runner._execute_module(conn, tmp, 'async_wrapper', module_args,
|
||||||
|
|
|
@ -32,11 +32,11 @@ class ActionModule(object):
|
||||||
def __init__(self, runner):
|
def __init__(self, runner):
|
||||||
self.runner = runner
|
self.runner = runner
|
||||||
|
|
||||||
def run(self, conn, tmp, module_name, inject):
|
def run(self, conn, tmp, module_name, module_args, inject):
|
||||||
''' handler for file transfer operations '''
|
''' handler for file transfer operations '''
|
||||||
|
|
||||||
# load up options
|
# load up options
|
||||||
options = utils.parse_kv(self.runner.module_args)
|
options = utils.parse_kv(module_args)
|
||||||
source = options.get('src', None)
|
source = options.get('src', None)
|
||||||
dest = options.get('dest', None)
|
dest = options.get('dest', None)
|
||||||
if (source is None and not 'first_available_file' in inject) or dest is None:
|
if (source is None and not 'first_available_file' in inject) or dest is None:
|
||||||
|
@ -77,11 +77,11 @@ class ActionModule(object):
|
||||||
self.runner._low_level_exec_command(conn, "chmod a+r %s" % tmp_src, tmp)
|
self.runner._low_level_exec_command(conn, "chmod a+r %s" % tmp_src, tmp)
|
||||||
|
|
||||||
# run the copy module
|
# run the copy module
|
||||||
self.runner.module_args = "%s src=%s" % (self.runner.module_args, tmp_src)
|
module_args = "%s src=%s" % (module_args, tmp_src)
|
||||||
return self.runner._execute_module(conn, tmp, 'copy', self.runner.module_args, inject=inject).daisychain('file')
|
return self.runner._execute_module(conn, tmp, 'copy', module_args, inject=inject).daisychain('file', module_args)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# no need to transfer the file, already correct md5
|
# no need to transfer the file, already correct md5
|
||||||
result = dict(changed=False, md5sum=remote_md5, transferred=False)
|
result = dict(changed=False, md5sum=remote_md5, transferred=False)
|
||||||
return ReturnData(conn=conn, result=result).daisychain('file')
|
return ReturnData(conn=conn, result=result).daisychain('file', module_args)
|
||||||
|
|
||||||
|
|
|
@ -32,11 +32,11 @@ class ActionModule(object):
|
||||||
def __init__(self, runner):
|
def __init__(self, runner):
|
||||||
self.runner = runner
|
self.runner = runner
|
||||||
|
|
||||||
def run(self, conn, tmp, module_name, inject):
|
def run(self, conn, tmp, module_name, module_args, inject):
|
||||||
''' handler for fetch operations '''
|
''' handler for fetch operations '''
|
||||||
|
|
||||||
# load up options
|
# load up options
|
||||||
options = utils.parse_kv(self.runner.module_args)
|
options = utils.parse_kv(module_args)
|
||||||
source = options.get('src', None)
|
source = options.get('src', None)
|
||||||
dest = options.get('dest', None)
|
dest = options.get('dest', None)
|
||||||
if source is None or dest is None:
|
if source is None or dest is None:
|
||||||
|
|
|
@ -33,15 +33,15 @@ class ActionModule(object):
|
||||||
def __init__(self, runner):
|
def __init__(self, runner):
|
||||||
self.runner = runner
|
self.runner = runner
|
||||||
|
|
||||||
def run(self, conn, tmp, module_name, inject):
|
def run(self, conn, tmp, module_name, module_args, inject):
|
||||||
''' transfer & execute a module that is not 'copy' or 'template' '''
|
''' transfer & execute a module that is not 'copy' or 'template' '''
|
||||||
|
|
||||||
# shell and command are the same module
|
# shell and command are the same module
|
||||||
if module_name == 'shell':
|
if module_name == 'shell':
|
||||||
module_name = 'command'
|
module_name = 'command'
|
||||||
self.runner.module_args += " #USE_SHELL"
|
module_args += " #USE_SHELL"
|
||||||
|
|
||||||
vv("REMOTE_MODULE %s %s" % (module_name, self.runner.module_args), host=conn.host)
|
vv("REMOTE_MODULE %s %s" % (module_name, module_args), host=conn.host)
|
||||||
return self.runner._execute_module(conn, tmp, module_name, self.runner.module_args, inject=inject)
|
return self.runner._execute_module(conn, tmp, module_name, module_args, inject=inject)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,8 @@ class ActionModule(object):
|
||||||
def __init__(self, runner):
|
def __init__(self, runner):
|
||||||
self.runner = runner
|
self.runner = runner
|
||||||
|
|
||||||
def run(self, conn, tmp, module_name, inject):
|
def run(self, conn, tmp, module_name, module_args, inject):
|
||||||
return ReturnData(conn=conn, result=dict(
|
return ReturnData(conn=conn, result=dict(
|
||||||
stdout=self.runner._low_level_exec_command(conn, self.runner.module_args.encode('utf-8'), tmp, sudoable=True)
|
stdout=self.runner._low_level_exec_command(conn, module_args.encode('utf-8'), tmp, sudoable=True)
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
|
@ -32,14 +32,14 @@ class ActionModule(object):
|
||||||
def __init__(self, runner):
|
def __init__(self, runner):
|
||||||
self.runner = runner
|
self.runner = runner
|
||||||
|
|
||||||
def run(self, conn, tmp, module_name, inject):
|
def run(self, conn, tmp, module_name, module_args, inject):
|
||||||
''' handler for template operations '''
|
''' handler for template operations '''
|
||||||
|
|
||||||
if not self.runner.is_playbook:
|
if not self.runner.is_playbook:
|
||||||
raise errors.AnsibleError("in current versions of ansible, templates are only usable in playbooks")
|
raise errors.AnsibleError("in current versions of ansible, templates are only usable in playbooks")
|
||||||
|
|
||||||
# load up options
|
# load up options
|
||||||
options = utils.parse_kv(self.runner.module_args)
|
options = utils.parse_kv(module_args)
|
||||||
source = options.get('src', None)
|
source = options.get('src', None)
|
||||||
dest = options.get('dest', None)
|
dest = options.get('dest', None)
|
||||||
if (source is None and 'first_available_file' not in inject) or dest is None:
|
if (source is None and 'first_available_file' not in inject) or dest is None:
|
||||||
|
@ -75,7 +75,7 @@ class ActionModule(object):
|
||||||
self.runner._low_level_exec_command(conn, "chmod a+r %s" % xfered,
|
self.runner._low_level_exec_command(conn, "chmod a+r %s" % xfered,
|
||||||
tmp)
|
tmp)
|
||||||
# run the copy module, queue the file module
|
# run the copy module, queue the file module
|
||||||
self.runner.module_args = "%s src=%s dest=%s" % (self.runner.module_args, xfered, dest)
|
module_args = "%s src=%s dest=%s" % (module_args, xfered, dest)
|
||||||
return self.runner._execute_module(conn, tmp, 'copy', self.runner.module_args, inject=inject).daisychain('file')
|
return self.runner._execute_module(conn, tmp, 'copy', module_args, inject=inject).daisychain('file', module_args)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -51,9 +51,10 @@ class ReturnData(object):
|
||||||
def is_successful(self):
|
def is_successful(self):
|
||||||
return self.comm_ok and ('failed' not in self.result) and (self.result.get('rc',0) == 0)
|
return self.comm_ok and ('failed' not in self.result) and (self.result.get('rc',0) == 0)
|
||||||
|
|
||||||
def daisychain(self, module_name):
|
def daisychain(self, module_name, module_args):
|
||||||
''' request a module call follow this one '''
|
''' request a module call follow this one '''
|
||||||
if self.is_successful():
|
if self.is_successful():
|
||||||
self.result['daisychain'] = module_name
|
self.result['daisychain'] = module_name
|
||||||
|
self.result['daisychain_args'] = module_args
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue