Repository: ansible/ansible

Issue:
traceback from script module with old style var (when used with include?)
Consider the following simple example:

main.yml:

```
- hosts: all
  vars:
    myvar: /home
  tasks:
    - include: included.yml
```

included.yml:

```
- script: myscript.sh $myvar
```

myscript.sh:

```
ls $1
```

Running main.yml raises an exception:

```
TASK: [script myscript.sh /home] ********************************************** 
fatal: [111.111.111.111] => Traceback (most recent call last):
  File "/Users/julien/.virtualenvs/myenv/lib/python2.6/site-packages/ansible/runner/__init__.py", line 382, in _executor
    exec_rc = self._executor_internal(host, new_stdin)
  File "/Users/julien/.virtualenvs/myenv/lib/python2.6/site-packages/ansible/runner/__init__.py", line 471, in _executor_internal
    return self._executor_internal_inner(host, self.module_name, self.module_args, inject, port, complex_args=complex_args)
  File "/Users/julien/.virtualenvs/myenv/lib/python2.6/site-packages/ansible/runner/__init__.py", line 654, in _executor_internal_inner
    result = handler.run(conn, tmp, module_name, module_args, inject, complex_args)
  File "/Users/julien/.virtualenvs/myenv/lib/python2.6/site-packages/ansible/runner/action_plugins/script.py", line 45, in run
    source = utils.path_dwim_relative(inject['_original_file'], 'files', source, self.runner.basedir)
  File "/Users/julien/.virtualenvs/myenv/lib/python2.6/site-packages/ansible/utils/__init__.py", line 259, in path_dwim_relative
    if os.path.exists(source2):
  File "/Users/julien/.virtualenvs/myenv/lib/python2.6/genericpath.py", line 18, in exists
    st = os.stat(path)
TypeError: stat() argument 1 must be encoded string without NULL bytes, not str
```

Also, this error is raised only if the script requires an argument. If no argument is used then the script runs fine without error.

Any idea why this is happening and how to fix it?



Discussion:
The variable should be specified as `{{ myvar }}`, not `$myvar`.

I don't think that's valid though... yes, we want people using new style variables, but even though that is the deprecated variable syntax it should definitely _work_

I've tried with the new-style variable and the same exception is still raised.

It is the script's name (`myscript.sh`) that causes the exception to be raised by `os.stat(path)` as it is of `str` type. 


Resolving patch:
diff --git a/lib/ansible/runner/action_plugins/script.py b/lib/ansible/runner/action_plugins/script.py
--- a/lib/ansible/runner/action_plugins/script.py
+++ b/lib/ansible/runner/action_plugins/script.py
@@ -36,7 +36,11 @@ def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **
             # in check mode, always skip this module
             return ReturnData(conn=conn, comm_ok=True, result=dict(skipped=True, msg='check mode not supported for this module'))
 
-        tokens  = shlex.split(module_args)
+        # Decode the result of shlex.split() to UTF8 to get around a bug in that's been fixed in Python 2.7 but not Python 2.6.
+        # See: http://bugs.python.org/issue6988
+        tokens  = shlex.split(module_args.encode('utf8'))
+        tokens = [s.decode('utf8') for s in tokens]
+
         source  = tokens[0]
         # FIXME: error handling
         args    = " ".join(tokens[1:])


Test patch: