diff --git a/lib/ansible/runner.py b/lib/ansible/runner.py index 063dd8a413..bbfc49fcfd 100755 --- a/lib/ansible/runner.py +++ b/lib/ansible/runner.py @@ -308,6 +308,12 @@ class Runner(object): because those require extra work. ''' + # hack to make the 'shell' module keyword really be executed + # by the command module + if self.module_name == 'shell': + self.module_name = 'command' + self.module_args.append("#USE_SHELL") + module = self._transfer_module(conn, tmp, self.module_name) result = self._execute_module(conn, tmp, module, self.module_args) diff --git a/lib/ansible/utils.py b/lib/ansible/utils.py index 6d485489c0..1d46f5f006 100755 --- a/lib/ansible/utils.py +++ b/lib/ansible/utils.py @@ -120,7 +120,7 @@ def host_report_msg(hostname, module_name, result, oneline): ''' summarize the JSON results for a particular host ''' buf = '' failed = is_failed(result) - if module_name == 'command': + if module_name in [ 'command', 'shell' ]: if not failed: buf = command_success_msg(hostname, result, oneline) else: diff --git a/library/command b/library/command index 06f5d65636..90b6b09d7d 100755 --- a/library/command +++ b/library/command @@ -32,18 +32,27 @@ import os argfile = sys.argv[1] args = open(argfile, 'r').read() -args = shlex.split(args) + +shell = False + +if args.find("#USE_SHELL") != -1: + args = args.replace("#USE_SHELL", "") + shell = True + +if not shell: + args = shlex.split(args) startd = datetime.datetime.now() try: - cmd = subprocess.Popen(args, shell=False, + cmd = subprocess.Popen(args, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = cmd.communicate() except (OSError, IOError), e: print json.dumps({ - "failed": 1, - "msg": str(e), + "cmd" : args, + "failed" : 1, + "msg" : str(e), }) sys.exit(1) except: @@ -62,6 +71,7 @@ if err is None: err = '' result = { + "cmd" : args, "stdout" : out.strip(), "stderr" : err.strip(), "rc" : cmd.returncode, diff --git a/test/TestRunner.py b/test/TestRunner.py index 96201a7089..074e230b17 100644 --- a/test/TestRunner.py +++ b/test/TestRunner.py @@ -127,6 +127,7 @@ class TestRunner(unittest.TestCase): assert result['changed'] == False def test_command(self): + # test command module, change trigger, etc result = self._run('command', [ "/bin/echo", "hi" ]) assert "failed" not in result @@ -134,14 +135,22 @@ class TestRunner(unittest.TestCase): assert result['rc'] == 0 assert result['stdout'] == 'hi' assert result['stderr'] == '' + result = self._run('command', [ "/bin/false" ]) assert result['rc'] == 1 assert 'failed' not in result + result = self._run('command', [ "/usr/bin/this_does_not_exist", "splat" ]) assert 'msg' in result assert 'failed' in result assert 'rc' not in result + result = self._run('shell', [ "/bin/echo", "$HOME" ]) + assert 'failed' not in result + assert result['rc'] == 0 + raise Exception(result['stdout']) + + def test_setup(self): output = self._get_stage_file('output.json') result = self._run('setup', [ "metadata=%s" % output, "a=2", "b=3", "c=4" ])