diff --git a/lib/ansible/module_common.py b/lib/ansible/module_common.py
index 2f6452aa12..cc1b078b27 100644
--- a/lib/ansible/module_common.py
+++ b/lib/ansible/module_common.py
@@ -16,11 +16,14 @@
# along with Ansible. If not, see .
REPLACER = "#<>"
+REPLACER_ARGS = "<>"
MODULE_COMMON = """
# == BEGIN DYNAMICALLY INSERTED CODE ==
+MODULE_ARGS = "<>"
+
# ansible modules can be written in any language. To simplify
# development of Python modules, the functions available here
# can be inserted in any module source automatically by including
@@ -32,6 +35,7 @@ try:
import json
except ImportError:
import simplejson as json
+import base64
import os
import re
import shlex
@@ -109,11 +113,7 @@ class AnsibleModule(object):
def _load_params(self):
''' read the input and return a dictionary and the arguments string '''
- if len(sys.argv) == 2 and os.path.exists(sys.argv[1]):
- argfile = sys.argv[1]
- args = open(argfile, 'r').read()
- else:
- args = ' '.join(sys.argv[1:])
+ args = base64.b64decode(MODULE_ARGS)
items = shlex.split(args)
params = {}
for x in items:
diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py
index 30583a8750..8966f451f3 100644
--- a/lib/ansible/runner/__init__.py
+++ b/lib/ansible/runner/__init__.py
@@ -182,12 +182,12 @@ class Runner(object):
# *****************************************************
- def _transfer_module(self, conn, tmp, module, inject):
- ''' transfers a module file to the remote side to execute it, but does not execute it yet '''
-
- outpath = self._copy_module(conn, tmp, module, inject)
- self._low_level_exec_command(conn, "chmod +x %s" % outpath, tmp)
- return outpath
+ #def _transfer_module(self, conn, tmp, module, inject):
+ # ''' transfers a module file to the remote side to execute it, but does not execute it yet '''
+ #
+ # outpath = self._copy_module(conn, tmp, module, inject)
+ # self._low_level_exec_command(conn, "chmod +x %s" % outpath, tmp)
+ # return outpath
# *****************************************************
@@ -212,7 +212,7 @@ class Runner(object):
# *****************************************************
- def _execute_module(self, conn, tmp, remote_module_path, args,
+ def _execute_module(self, conn, tmp, module_name, args,
async_jid=None, async_module=None, async_limit=None, inject=None):
''' runs a module that has already been transferred '''
@@ -220,13 +220,22 @@ class Runner(object):
if type(args) == dict:
args = utils.jsonify(args,format=True)
- args = utils.template(args, inject)
+ (remote_module_path, is_new_style) = self._copy_module(conn, tmp, module_name, inject)
+ self._low_level_exec_command(conn, "chmod +x %s" % remote_module_path, tmp)
- argsfile = self._transfer_str(conn, tmp, 'arguments', args)
- if async_jid is None:
- cmd = "%s %s" % (remote_module_path, argsfile)
+ cmd = ""
+ if not is_new_style:
+ args = utils.template(args, inject)
+ argsfile = self._transfer_str(conn, tmp, 'arguments', args)
+ if async_jid is None:
+ cmd = "%s %s" % (remote_module_path, argsfile)
+ else:
+ cmd = " ".join([str(x) for x in [remote_module_path, async_jid, async_limit, async_module, argsfile]])
else:
- cmd = " ".join([str(x) for x in [remote_module_path, async_jid, async_limit, async_module, argsfile]])
+ if async_jid is None:
+ cmd = "%s" % (remote_module_path)
+ else:
+ cmd = " ".join([str(x) for x in [remote_module_path, async_jid, async_limit, async_module]])
res = self._low_level_exec_command(conn, cmd, tmp, sudoable=True)
return ReturnData(host=conn.host, result=res)
@@ -249,8 +258,7 @@ class Runner(object):
module_name = 'command'
self.module_args += " #USE_SHELL"
- module = self._transfer_module(conn, tmp, module_name, inject)
- exec_rc = self._execute_module(conn, tmp, module, self.module_args, inject=inject)
+ exec_rc = self._execute_module(conn, tmp, module_name, self.module_args, inject=inject)
if exec_rc.is_successful():
self.setup_cache[conn.host].update(exec_rc.result.get('ansible_facts', {}))
return exec_rc
@@ -266,11 +274,8 @@ class Runner(object):
module_name = 'command'
module_args += " #USE_SHELL"
- async = self._transfer_module(conn, tmp, 'async_wrapper', inject)
- module = self._transfer_module(conn, tmp, module_name, inject)
-
- return self._execute_module(conn, tmp, async, module_args,
- async_module=module,
+ return self._execute_module(conn, tmp, 'async', module_args,
+ async_module=module_name,
async_jid=self.generated_jid,
async_limit=self.background,
inject=inject
@@ -319,13 +324,9 @@ class Runner(object):
tmp_src = tmp + source.split('/')[-1]
conn.put_file(source, tmp_src)
- # install the copy module
- self.module_name = 'copy'
- module = self._transfer_module(conn, tmp, 'copy', inject)
-
# run the copy module
args = "src=%s dest=%s" % (tmp_src, dest)
- return self._execute_module(conn, tmp, module, args, inject=inject).daisychain('file')
+ return self._execute_module(conn, tmp, 'copy', args, inject=inject).daisychain('file')
else:
# no need to transfer the file, already correct md5
@@ -421,9 +422,6 @@ class Runner(object):
source = utils.template(source, inject)
- # install the template module
- copy_module = self._transfer_module(conn, tmp, 'copy', inject)
-
# template the source data locally & transfer
try:
resultant = utils.template_from_file(self.basedir, source, inject)
@@ -434,17 +432,20 @@ class Runner(object):
# run the copy module, queue the file module
args = "src=%s dest=%s" % (xfered, dest)
- return self._execute_module(conn, tmp, copy_module, args, inject=inject).daisychain('file')
+ return self._execute_module(conn, tmp, 'copy', args, inject=inject).daisychain('file')
# *****************************************************
def _execute_assemble(self, conn, tmp, inject=None):
''' handler for assemble operations '''
+ # FIXME: once assemble is ported over to the use the new common logic, this method
+ # will be unneccessary as it can decide to daisychain via it's own module returns.
+ # and this function can be deleted.
+
module_name = 'assemble'
options = utils.parse_kv(self.module_args)
- module = self._transfer_module(conn, tmp, module_name, inject)
- return self._execute_module(conn, tmp, module, self.module_args, inject=inject).daisychain('file')
+ return self._execute_module(conn, tmp, 'inject', self.module_args, inject=inject).daisychain('file')
# *****************************************************
@@ -670,10 +671,15 @@ class Runner(object):
out_path = os.path.join(tmp, module)
module_data = ""
+ is_new_style=False
with open(in_path) as f:
module_data = f.read()
+ 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 = base64.b64encode(self.module_args)
+ module_data = module_data.replace(module_common.REPLACER_ARGS, encoded_args)
+
# use the correct python interpreter for the host
if 'ansible_python_interpreter' in inject:
interpreter = inject['ansible_python_interpreter']
@@ -683,7 +689,7 @@ class Runner(object):
module_data = "\n".join(module_lines)
self._transfer_str(conn, tmp, module, module_data)
- return out_path
+ return (out_path, is_new_style)
# *****************************************************
diff --git a/library/ping b/library/ping
index ccc7cc722c..34d097864d 100755
--- a/library/ping
+++ b/library/ping
@@ -17,15 +17,15 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see .
-try:
- import json
-except ImportError:
- import simplejson as json
+import base64
-import os
-import syslog
+def main():
+ module = AnsibleModule(
+ argument_spec = dict()
+ )
+ module.exit_json(ping='pong')
-syslog.openlog('ansible-%s' % os.path.basename(__file__))
-syslog.syslog(syslog.LOG_NOTICE, 'Invoked as-is')
+# this is magic, see lib/ansible/module_common.py
+#<>
+main()
-print json.dumps({ "ping" : "pong" })