summaryrefslogtreecommitdiff
path: root/lib/ansible/plugins
diff options
context:
space:
mode:
authorMatt Davis <nitzmahone@users.noreply.github.com>2017-06-26 22:57:59 -0700
committerGitHub <noreply@github.com>2017-06-26 22:57:59 -0700
commit6cca156fde59601e4411587b2752254454c601ad (patch)
tree8bc24862af9da7d1ee3e9aea52d48e1032cc803a /lib/ansible/plugins
parent940a78c5ba11285ff95314bc436d17fd3e0e5551 (diff)
downloadansible-6cca156fde59601e4411587b2752254454c601ad.tar.gz
re-enable non-pipelined mode for Powershell (#26124)
* fixes #23986 * fixes 3rd-party Windows connection plugins that don't support pipelining (eg awsrun) (cherry picked from commit 6677559c698f15c582fba80d866f46458848f974)
Diffstat (limited to 'lib/ansible/plugins')
-rw-r--r--lib/ansible/plugins/action/__init__.py30
-rw-r--r--lib/ansible/plugins/connection/winrm.py12
-rw-r--r--lib/ansible/plugins/shell/powershell.py32
3 files changed, 38 insertions, 36 deletions
diff --git a/lib/ansible/plugins/action/__init__.py b/lib/ansible/plugins/action/__init__.py
index c530cdee43..5690dabd44 100644
--- a/lib/ansible/plugins/action/__init__.py
+++ b/lib/ansible/plugins/action/__init__.py
@@ -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, AnsibleActionSkip, AnsibleActionFail
-from ansible.executor.module_common import modify_module, build_windows_module_payload
+from ansible.executor.module_common import modify_module
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
@@ -153,18 +153,15 @@ class ActionBase(with_metaclass(ABCMeta, object)):
"run 'git pull --rebase' to correct this problem." % (module_name))
# insert shared code and arguments into the module
+ final_environment = dict()
+ self._compute_environment_string(final_environment)
+
(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...
- final_environment = dict()
- self._compute_environment_string(final_environment)
- 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, environment=final_environment)
+ task_vars=task_vars, module_compression=self._play_context.module_compression,
+ async_timeout=self._task.async, become=self._play_context.become,
+ become_method=self._play_context.become_method, become_user=self._play_context.become_user,
+ become_password=self._play_context.become_pass,
+ environment=final_environment)
return (module_style, module_shebang, module_data, module_path)
@@ -184,7 +181,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
# block then task 'win' in precedence
environments.reverse()
for environment in environments:
- if environment is None:
+ if environment is None or len(environment) == 0:
continue
temp_environment = self._templar.template(environment)
if not isinstance(temp_environment, dict):
@@ -193,7 +190,8 @@ class ActionBase(with_metaclass(ABCMeta, object)):
# these environment settings should not need to merge sub-dicts
final_environment.update(temp_environment)
- final_environment = self._templar.template(final_environment)
+ if len(final_environment) > 0:
+ final_environment = self._templar.template(final_environment)
if isinstance(raw_environment_out, dict):
raw_environment_out.clear()
@@ -212,13 +210,11 @@ 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,
- self._play_context.pipelining,
+ self._play_context.pipelining or self._connection.always_pipeline_modules, # pipelining enabled for play or connection requires it (eg winrm)
module_style == "new", # old style modules do not support pipelining
not C.DEFAULT_KEEP_REMOTE_FILES, # user wants remote files
not wrap_async, # async does not support pipelining
diff --git a/lib/ansible/plugins/connection/winrm.py b/lib/ansible/plugins/connection/winrm.py
index d452be5afd..c97c9ccf6e 100644
--- a/lib/ansible/plugins/connection/winrm.py
+++ b/lib/ansible/plugins/connection/winrm.py
@@ -326,17 +326,17 @@ class Connection(ConnectionBase):
def exec_command(self, cmd, in_data=None, sudoable=True):
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
- cmd_parts = self._shell._encode_script(exec_wrapper, as_list=True, strict_mode=False, preserve_rc=False)
+ cmd_parts = self._shell._encode_script(cmd, as_list=True, strict_mode=False, preserve_rc=False)
# TODO: display something meaningful here
display.vvv("EXEC (via pipeline wrapper)")
- if not in_data:
- payload = self._create_raw_wrapper_payload(cmd)
- else:
- payload = in_data
+ stdin_iterator = None
+
+ if in_data:
+ stdin_iterator = self._wrapper_payload_stream(in_data)
- result = self._winrm_exec(cmd_parts[0], cmd_parts[1:], from_exec=True, stdin_iterator=self._wrapper_payload_stream(payload))
+ result = self._winrm_exec(cmd_parts[0], cmd_parts[1:], from_exec=True, stdin_iterator=stdin_iterator)
result.std_out = to_bytes(result.std_out)
result.std_err = to_bytes(result.std_err)
diff --git a/lib/ansible/plugins/shell/powershell.py b/lib/ansible/plugins/shell/powershell.py
index 9d9238e4d2..5ad6b86a4d 100644
--- a/lib/ansible/plugins/shell/powershell.py
+++ b/lib/ansible/plugins/shell/powershell.py
@@ -55,7 +55,8 @@ begin {
# stream JSON including become_pw, ps_module_payload, bin_module_payload, become_payload, write_payload_path, preserve directives
# exec runspace, capture output, cleanup, return module output
- $json_raw = ""
+ # NB: do not adjust the following line- it is replaced when doing non-streamed module output
+ $json_raw = ''
}
process {
$input_as_string = [string]$input
@@ -332,7 +333,6 @@ Function Run($payload) {
$username = $payload.become_user
$password = $payload.become_password
- Add-Type -TypeDefinition $helper_def
Add-Type -TypeDefinition $helper_def -Debug:$false
$exec_args = $null
@@ -726,7 +726,6 @@ Function Run($payload) {
[System.IO.Directory]::CreateDirectory([System.IO.Path]::GetDirectoryName($results_path)) | Out-Null
- Add-Type -TypeDefinition $native_process_util
Add-Type -TypeDefinition $native_process_util -Debug:$false
# FUTURE: create under new job to ensure all children die on exit?
@@ -1103,7 +1102,7 @@ class ShellModule(object):
def build_module_command(self, env_string, shebang, cmd, arg_path=None, rm_tmp=None):
# pipelining bypass
if cmd == '':
- return ''
+ return '-'
# non-pipelining
@@ -1192,15 +1191,22 @@ class ShellModule(object):
def _encode_script(self, script, as_list=False, strict_mode=True, preserve_rc=True):
'''Convert a PowerShell script to a single base64-encoded command.'''
script = to_text(script)
- if strict_mode:
- script = u'Set-StrictMode -Version Latest\r\n%s' % script
- # try to propagate exit code if present- won't work with begin/process/end-style scripts (ala put_file)
- # NB: the exit code returned may be incorrect in the case of a successful command followed by an invalid command
- if preserve_rc:
- script = u'%s\r\nIf (-not $?) { If (Get-Variable LASTEXITCODE -ErrorAction SilentlyContinue) { exit $LASTEXITCODE } Else { exit 1 } }\r\n' % script
- script = '\n'.join([x.strip() for x in script.splitlines() if x.strip()])
- encoded_script = base64.b64encode(script.encode('utf-16-le'))
- cmd_parts = _common_args + ['-EncodedCommand', encoded_script]
+
+ if script == u'-':
+ cmd_parts = _common_args + ['-']
+
+ else:
+ if strict_mode:
+ script = u'Set-StrictMode -Version Latest\r\n%s' % script
+ # try to propagate exit code if present- won't work with begin/process/end-style scripts (ala put_file)
+ # NB: the exit code returned may be incorrect in the case of a successful command followed by an invalid command
+ if preserve_rc:
+ script = u'%s\r\nIf (-not $?) { If (Get-Variable LASTEXITCODE -ErrorAction SilentlyContinue) { exit $LASTEXITCODE } Else { exit 1 } }\r\n'\
+ % script
+ script = '\n'.join([x.strip() for x in script.splitlines() if x.strip()])
+ encoded_script = base64.b64encode(script.encode('utf-16-le'))
+ cmd_parts = _common_args + ['-EncodedCommand', encoded_script]
+
if as_list:
return cmd_parts
return ' '.join(cmd_parts)