From 34f7e6ffa010fe40992c1694647cfdbc9156106c Mon Sep 17 00:00:00 2001 From: Daniel Hokka Zakrisson Date: Fri, 21 Sep 2012 10:42:27 +0200 Subject: [PATCH] Pass module arguments as argument instead of keeping it in runner --- lib/ansible/runner/__init__.py | 68 +++++++------------ lib/ansible/runner/action_plugins/assemble.py | 4 +- lib/ansible/runner/action_plugins/async.py | 5 +- lib/ansible/runner/action_plugins/copy.py | 10 +-- lib/ansible/runner/action_plugins/fetch.py | 4 +- lib/ansible/runner/action_plugins/normal.py | 8 +-- lib/ansible/runner/action_plugins/raw.py | 4 +- lib/ansible/runner/action_plugins/template.py | 8 +-- lib/ansible/runner/return_data.py | 3 +- 9 files changed, 48 insertions(+), 66 deletions(-) diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py index 1c3977e86b..efa6e2386f 100644 --- a/lib/ansible/runner/__init__.py +++ b/lib/ansible/runner/__init__.py @@ -188,10 +188,7 @@ class Runner(object): ''' runs a module that has already been transferred ''' - if type(args) == dict: - args = utils.jsonify(args,format=True) - - (remote_module_path, is_new_style) = self._copy_module(conn, tmp, module_name, inject) + (remote_module_path, is_new_style) = self._copy_module(conn, tmp, module_name, args, inject) cmd = "chmod u+x %s" % remote_module_path if self.sudo and self.sudo_user != 'root': # 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 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: # executing using with_items, so make multiple calls # TODO: refactor @@ -279,14 +276,9 @@ class Runner(object): all_changed = False all_failed = False 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: - self.module_name = module_name - self.module_args = module_args 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) if result.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 ''' - # 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: # 'groups' variable is a list of host name in each group # 'hostvars' variable contains variables for each host name # ... and is set elsewhere # 'inventory_hostname' is also set elsewhere inject['groups'] = self.inventory.groups_list() + # allow module args to work as a dictionary # though it is usually a string new_args = "" - if type(self.module_args) == dict: - for (k,v) in self.module_args.iteritems(): + if type(module_args) == dict: + for (k,v) in module_args.iteritems(): new_args = new_args + "%s='%s' " % (k,v) - self.module_args = new_args - self.module_args = utils.template(self.basedir, self.module_args, inject) + module_args = new_args def _check_conditional(conditional): def is_set(var): @@ -355,31 +343,25 @@ class Runner(object): result = dict(failed=True, msg="FAILED: %s" % str(e)) 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 = '' if self.module_name != 'raw': tmp = self._make_tmp_path(conn) result = None - handler = self.action_plugins.get(self.module_name, None) + handler = self.action_plugins.get(module_name, None) if handler: - result = handler.run(conn, tmp, module_name, inject) + result = handler.run(conn, tmp, module_name, module_args, inject) else: 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: - 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: - self.module_name = result.result['daisychain'] - 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 + result2 = self._executor_internal_inner(host, result.result['daisychain'], result.result.get('daisychain_args', {}), inject, port, is_chained=True) 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['invocation'] = dict( - module_args=self.module_args, - module_name=self.module_name + module_args=module_args, + module_name=module_name ) 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 ''' - if module.startswith("/"): - raise errors.AnsibleFileNotFound("%s is not a module" % module) + if module_name.startswith("/"): + raise errors.AnsibleFileNotFound("%s is not a module" % module_name) # Search module path(s) for named module. 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): break 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 = "" is_new_style=False @@ -502,7 +484,7 @@ class Runner(object): if module_common.REPLACER in module_data: is_new_style=True 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) # use the correct python interpreter for the host @@ -513,7 +495,7 @@ class Runner(object): module_lines[0] = "#!%s" % interpreter 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) # ***************************************************** diff --git a/lib/ansible/runner/action_plugins/assemble.py b/lib/ansible/runner/action_plugins/assemble.py index d529caf4df..f0e26ad487 100644 --- a/lib/ansible/runner/action_plugins/assemble.py +++ b/lib/ansible/runner/action_plugins/assemble.py @@ -32,12 +32,12 @@ class ActionModule(object): def __init__(self, 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 ''' # 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. # 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) diff --git a/lib/ansible/runner/action_plugins/async.py b/lib/ansible/runner/action_plugins/async.py index 19a5a186fd..d1bf6ab76c 100644 --- a/lib/ansible/runner/action_plugins/async.py +++ b/lib/ansible/runner/action_plugins/async.py @@ -32,16 +32,15 @@ class ActionModule(object): def __init__(self, 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 ''' # shell and command module are the same - module_args = self.runner.module_args if module_name == 'shell': module_name = 'command' 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) return self.runner._execute_module(conn, tmp, 'async_wrapper', module_args, diff --git a/lib/ansible/runner/action_plugins/copy.py b/lib/ansible/runner/action_plugins/copy.py index 812a2484c8..c85de1442e 100644 --- a/lib/ansible/runner/action_plugins/copy.py +++ b/lib/ansible/runner/action_plugins/copy.py @@ -32,11 +32,11 @@ class ActionModule(object): def __init__(self, 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 ''' # load up options - options = utils.parse_kv(self.runner.module_args) + options = utils.parse_kv(module_args) source = options.get('src', None) dest = options.get('dest', 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) # run the copy module - self.runner.module_args = "%s src=%s" % (self.runner.module_args, tmp_src) - return self.runner._execute_module(conn, tmp, 'copy', self.runner.module_args, inject=inject).daisychain('file') + module_args = "%s src=%s" % (module_args, tmp_src) + return self.runner._execute_module(conn, tmp, 'copy', module_args, inject=inject).daisychain('file', module_args) else: # no need to transfer the file, already correct md5 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) diff --git a/lib/ansible/runner/action_plugins/fetch.py b/lib/ansible/runner/action_plugins/fetch.py index b0c8161451..48de294959 100644 --- a/lib/ansible/runner/action_plugins/fetch.py +++ b/lib/ansible/runner/action_plugins/fetch.py @@ -32,11 +32,11 @@ class ActionModule(object): def __init__(self, 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 ''' # load up options - options = utils.parse_kv(self.runner.module_args) + options = utils.parse_kv(module_args) source = options.get('src', None) dest = options.get('dest', None) if source is None or dest is None: diff --git a/lib/ansible/runner/action_plugins/normal.py b/lib/ansible/runner/action_plugins/normal.py index b5130a3d55..a93553b20b 100644 --- a/lib/ansible/runner/action_plugins/normal.py +++ b/lib/ansible/runner/action_plugins/normal.py @@ -33,15 +33,15 @@ class ActionModule(object): def __init__(self, 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' ''' # shell and command are the same module if module_name == 'shell': 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) - return self.runner._execute_module(conn, tmp, module_name, self.runner.module_args, inject=inject) + vv("REMOTE_MODULE %s %s" % (module_name, module_args), host=conn.host) + return self.runner._execute_module(conn, tmp, module_name, module_args, inject=inject) diff --git a/lib/ansible/runner/action_plugins/raw.py b/lib/ansible/runner/action_plugins/raw.py index ba52809e17..64eaefdaa2 100644 --- a/lib/ansible/runner/action_plugins/raw.py +++ b/lib/ansible/runner/action_plugins/raw.py @@ -32,8 +32,8 @@ class ActionModule(object): def __init__(self, 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( - 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) )) diff --git a/lib/ansible/runner/action_plugins/template.py b/lib/ansible/runner/action_plugins/template.py index 91a50bdede..60fcba3f5a 100644 --- a/lib/ansible/runner/action_plugins/template.py +++ b/lib/ansible/runner/action_plugins/template.py @@ -32,14 +32,14 @@ class ActionModule(object): def __init__(self, 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 ''' if not self.runner.is_playbook: raise errors.AnsibleError("in current versions of ansible, templates are only usable in playbooks") # load up options - options = utils.parse_kv(self.runner.module_args) + options = utils.parse_kv(module_args) source = options.get('src', None) dest = options.get('dest', 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, tmp) # run the copy module, queue the file module - self.runner.module_args = "%s src=%s dest=%s" % (self.runner.module_args, xfered, dest) - return self.runner._execute_module(conn, tmp, 'copy', self.runner.module_args, inject=inject).daisychain('file') + module_args = "%s src=%s dest=%s" % (module_args, xfered, dest) + return self.runner._execute_module(conn, tmp, 'copy', module_args, inject=inject).daisychain('file', module_args) diff --git a/lib/ansible/runner/return_data.py b/lib/ansible/runner/return_data.py index 0dcdb4aeb8..9fdc77b967 100644 --- a/lib/ansible/runner/return_data.py +++ b/lib/ansible/runner/return_data.py @@ -51,9 +51,10 @@ class ReturnData(object): def is_successful(self): 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 ''' if self.is_successful(): self.result['daisychain'] = module_name + self.result['daisychain_args'] = module_args return self