diff --git a/lib/ansible/plugins/action/__init__.py b/lib/ansible/plugins/action/__init__.py index 57e4c2fa408..5fa5af9884c 100644 --- a/lib/ansible/plugins/action/__init__.py +++ b/lib/ansible/plugins/action/__init__.py @@ -105,6 +105,7 @@ class ActionBase(with_metaclass(ABCMeta, object)): with open(module_path, 'rb') as f: start = f.read(1024) + return bool(start.translate(None, textchars)) def _configure_module(self, module_name, module_args, task_vars=None): ''' @@ -154,9 +155,9 @@ class ActionBase(with_metaclass(ABCMeta, object)): (module_data, module_style, module_shebang) = modify_module(module_name, module_path, module_args, task_vars=task_vars, module_compression=self._play_context.module_compression) if self._is_binary(module_path): - return ('non_native_want_json', None, module_path, True) + return ('non_native_want_json', None, None, module_path, True) - return (module_style, module_shebang, module_data, False) + return (module_style, module_shebang, module_data, module_path, False) def _compute_environment_string(self): ''' @@ -578,7 +579,7 @@ class ActionBase(with_metaclass(ABCMeta, object)): # let module know our verbosity module_args['_ansible_verbosity'] = display.verbosity - (module_style, shebang, module_data, is_binary) = self._configure_module(module_name=module_name, module_args=module_args, task_vars=task_vars) + (module_style, shebang, module_data, module_path, is_binary) = self._configure_module(module_name=module_name, module_args=module_args, task_vars=task_vars) if not shebang and not is_binary: raise AnsibleError("module (%s) is missing interpreter line" % module_name) @@ -590,7 +591,7 @@ class ActionBase(with_metaclass(ABCMeta, object)): tmp = self._make_tmp_path(remote_user) if tmp: - remote_module_filename = self._connection._shell.get_remote_filename(module_name) + remote_module_filename = self._connection._shell.get_remote_filename(module_path) remote_module_path = self._connection._shell.join_path(tmp, remote_module_filename) if module_style in ['old', 'non_native_want_json']: # we'll also need a temp file to hold our module arguments @@ -599,10 +600,9 @@ class ActionBase(with_metaclass(ABCMeta, object)): if remote_module_path or module_style != 'new': display.debug("transferring module to remote") if is_binary: - # If is_binary module_data is the path to the module to transfer - self._transfer_file(module_data, remote_module_path) + self._transfer_file(module_path, remote_module_path) else: - self._transfer_data(remote_module_path, module_data, is_path=is_binary) + self._transfer_data(remote_module_path, module_data) if module_style == 'old': # we need to dump the module args to a k=v string in a file on # the remote system, which can be read and parsed by the module diff --git a/lib/ansible/plugins/action/async.py b/lib/ansible/plugins/action/async.py index f6d1a24c81b..a9406421c25 100644 --- a/lib/ansible/plugins/action/async.py +++ b/lib/ansible/plugins/action/async.py @@ -54,14 +54,14 @@ class ActionModule(ActionBase): module_args['_ansible_no_log'] = True # configure, upload, and chmod the target module - (module_style, shebang, module_data, is_binary) = self._configure_module(module_name=module_name, module_args=module_args, task_vars=task_vars) + (module_style, shebang, module_data, module_path, is_binary) = self._configure_module(module_name=module_name, module_args=module_args, task_vars=task_vars) if is_binary: - self._transfer_file(module_data, remote_module_path) + self._transfer_file(module_path, remote_module_path) else: self._transfer_data(remote_module_path, module_data) # configure, upload, and chmod the async_wrapper module - (async_module_style, shebang, async_module_data, is_binary) = self._configure_module(module_name='async_wrapper', module_args=dict(), task_vars=task_vars) + (async_module_style, shebang, async_module_data, async_module_path, is_binary) = self._configure_module(module_name='async_wrapper', module_args=dict(), task_vars=task_vars) self._transfer_data(async_module_path, async_module_data) argsfile = None diff --git a/lib/ansible/plugins/connection/winrm.py b/lib/ansible/plugins/connection/winrm.py index f5023d7efc6..c5efd481f29 100644 --- a/lib/ansible/plugins/connection/winrm.py +++ b/lib/ansible/plugins/connection/winrm.py @@ -62,7 +62,7 @@ class Connection(ConnectionBase): '''WinRM connections over HTTP/HTTPS.''' transport = 'winrm' - module_implementation_preferences = ('.ps1', '') + module_implementation_preferences = ('.ps1', '.exe', '') become_methods = [] allow_executable = False diff --git a/lib/ansible/plugins/shell/powershell.py b/lib/ansible/plugins/shell/powershell.py index aa77cb5d365..dfbae1b4284 100644 --- a/lib/ansible/plugins/shell/powershell.py +++ b/lib/ansible/plugins/shell/powershell.py @@ -55,9 +55,11 @@ class ShellModule(object): return '\'%s\'' % path # powershell requires that script files end with .ps1 - def get_remote_filename(self, base_name): - if not base_name.strip().lower().endswith('.ps1'): - return base_name.strip() + '.ps1' + def get_remote_filename(self, pathname): + base_name = os.path.basename(pathname.strip()) + name, ext = os.path.splitext(base_name.strip()) + if ext.lower() not in ['.ps1', '.exe']: + return name + '.ps1' return base_name.strip() @@ -146,6 +148,10 @@ class ShellModule(object): cmd_parts.insert(0, '&') elif shebang and shebang.startswith('#!'): cmd_parts.insert(0, shebang[2:]) + elif not shebang: + # The module is assumed to be a binary + cmd_parts[0] = self._unquote(cmd_parts[0]) + cmd_parts.append(arg_path) script = ''' Try {