winrm - Handle task timeout (#82784)

When using winrm over HTTP with message encryption enabled and a task
has timed out the connection plugin will fail to cleanup the WinRM
command. This will change that exception into a warning as a timeout is
already an exception event and a failure to clean the operation should
not override the timeout error shown.
pull/82874/head
Jordan Borean 8 months ago committed by GitHub
parent c9086061ca
commit 8aecd1f9b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,2 @@
bugfixes:
- winrm - Do not raise another exception during cleanup when a task is timed out - https://github.com/ansible/ansible/issues/81095

@ -198,7 +198,7 @@ from ansible.utils.display import Display
try: try:
import winrm import winrm
from winrm.exceptions import WinRMError, WinRMOperationTimeoutError from winrm.exceptions import WinRMError, WinRMOperationTimeoutError, WinRMTransportError
from winrm.protocol import Protocol from winrm.protocol import Protocol
import requests.exceptions import requests.exceptions
HAS_WINRM = True HAS_WINRM = True
@ -683,7 +683,19 @@ class Connection(ConnectionBase):
raise AnsibleConnectionFailure('winrm connection error: %s' % to_native(exc)) raise AnsibleConnectionFailure('winrm connection error: %s' % to_native(exc))
finally: finally:
if command_id: if command_id:
# Due to a bug in how pywinrm works with message encryption we
# ignore a 400 error which can occur when a task timeout is
# set and the code tries to clean up the command. This happens
# as the cleanup msg is sent over a new socket but still uses
# the already encrypted payload bound to the other socket
# causing the server to reply with 400 Bad Request.
try:
self.protocol.cleanup_command(self.shell_id, command_id) self.protocol.cleanup_command(self.shell_id, command_id)
except WinRMTransportError as e:
if e.code != 400:
raise
display.warning("Failed to cleanup running WinRM command, resources might still be in use on the target server")
def _connect(self) -> Connection: def _connect(self) -> Connection:

@ -30,3 +30,15 @@
- win_ssh_async.rc == 0 - win_ssh_async.rc == 0
- win_ssh_async.stdout == "café\n" - win_ssh_async.stdout == "café\n"
- win_ssh_async.stderr == "" - win_ssh_async.stderr == ""
# Ensures the connection plugin can handle a timeout
# without raising another error.
- name: run command with timeout
win_shell: Start-Sleep -Seconds 10
timeout: 5
register: timeout_cmd
ignore_errors: true
- assert:
that:
- timeout_cmd.msg == 'The win_shell action failed to execute in the expected time frame (5) and was terminated'

@ -29,3 +29,15 @@
that: that:
- winrm_copy_empty is changed - winrm_copy_empty is changed
- winrm_copy_empty_actual.stat.size == 0 - winrm_copy_empty_actual.stat.size == 0
# Ensures the connection plugin can handle a timeout
# without raising another error.
- name: run command with timeout
win_shell: Start-Sleep -Seconds 10
timeout: 5
register: timeout_cmd
ignore_errors: true
- assert:
that:
- timeout_cmd.msg == 'The win_shell action failed to execute in the expected time frame (5) and was terminated'

Loading…
Cancel
Save