mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-05-07 13:52:54 +00:00
Complete rewrite of Windows exec wrapper (#21510)
* supports pipelining for faster execution * supports become (runas), creates interactive subsession under WinRM batch logon * supports usage of arbitrary module_utils files * modular exec wrapper payload supports easier extension * integrates async wrapper behavior for pipelined/become'd async * module_utils are loaded as true Powershell modules, no more runtime modifications to module code
This commit is contained in:
@@ -33,7 +33,7 @@ from ansible import constants as C
|
||||
from ansible.compat.six import binary_type, string_types, text_type, iteritems, with_metaclass
|
||||
from ansible.compat.six.moves import shlex_quote
|
||||
from ansible.errors import AnsibleError, AnsibleConnectionFailure
|
||||
from ansible.executor.module_common import modify_module
|
||||
from ansible.executor.module_common import modify_module, build_windows_module_payload
|
||||
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.json_utils import _filter_non_json_lines
|
||||
from ansible.parsing.utils.jsonify import jsonify
|
||||
@@ -159,6 +159,14 @@ 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)
|
||||
|
||||
# FUTURE: we'll have to get fancier about this to support powershell over SSH on Windows...
|
||||
if self._connection.transport == "winrm":
|
||||
# WinRM always pipelines, so we need to build up a fancier module payload...
|
||||
module_data = build_windows_module_payload(module_name=module_name, module_path=module_path,
|
||||
b_module_data=module_data, module_args=module_args,
|
||||
task_vars=task_vars, task=self._task,
|
||||
play_context=self._play_context)
|
||||
|
||||
return (module_style, module_shebang, module_data, module_path)
|
||||
|
||||
def _compute_environment_string(self):
|
||||
@@ -200,6 +208,9 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||
'''
|
||||
Determines if we are required and can do pipelining
|
||||
'''
|
||||
if self._connection.always_pipeline_modules:
|
||||
return True #eg, winrm
|
||||
|
||||
# any of these require a true
|
||||
for condition in [
|
||||
self._connection.has_pipelining,
|
||||
@@ -610,6 +621,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||
|
||||
self._update_module_args(module_name, module_args, task_vars)
|
||||
|
||||
# FUTURE: refactor this along with module build process to better encapsulate "smart wrapper" functionality
|
||||
(module_style, shebang, module_data, module_path) = self._configure_module(module_name=module_name, module_args=module_args, task_vars=task_vars)
|
||||
display.vvv("Using module file %s" % module_path)
|
||||
if not shebang and module_style != 'binary':
|
||||
@@ -834,10 +846,10 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||
'''
|
||||
|
||||
display.debug("_low_level_execute_command(): starting")
|
||||
if not cmd:
|
||||
# this can happen with powershell modules when there is no analog to a Windows command (like chmod)
|
||||
display.debug("_low_level_execute_command(): no command, exiting")
|
||||
return dict(stdout='', stderr='', rc=254)
|
||||
# if not cmd:
|
||||
# # this can happen with powershell modules when there is no analog to a Windows command (like chmod)
|
||||
# display.debug("_low_level_execute_command(): no command, exiting")
|
||||
# return dict(stdout='', stderr='', rc=254)
|
||||
|
||||
allow_same_user = C.BECOME_ALLOW_SAME_USER
|
||||
same_user = self._play_context.become_user == self._play_context.remote_user
|
||||
|
||||
@@ -38,8 +38,11 @@ class ActionModule(ActionBase):
|
||||
# should not be set anymore but here for backwards compatibility
|
||||
del results['invocation']['module_args']
|
||||
|
||||
# FUTURE: better to let _execute_module calculate this internally?
|
||||
wrap_async = self._task.async and not self._connection.has_native_async
|
||||
|
||||
# do work!
|
||||
results = merge_hash(results, self._execute_module(tmp=tmp, task_vars=task_vars, wrap_async=self._task.async))
|
||||
results = merge_hash(results, self._execute_module(tmp=tmp, task_vars=task_vars, wrap_async=wrap_async))
|
||||
|
||||
# hack to keep --verbose from showing all the setup module results
|
||||
# moved from setup module as now we filter out all _ansible_ from results
|
||||
|
||||
@@ -83,6 +83,7 @@ class ActionModule(ActionBase):
|
||||
# add preparation steps to one ssh roundtrip executing the script
|
||||
env_string = self._compute_environment_string()
|
||||
script_cmd = ' '.join([env_string, tmp_src, args])
|
||||
script_cmd = self._connection._shell.wrap_for_exec(script_cmd)
|
||||
|
||||
result.update(self._low_level_execute_command(cmd=script_cmd, sudoable=True))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user