winrm - Handle task timeout (#82784) (#82863)

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.

(cherry picked from commit 8aecd1f9b2)
pull/83044/head
Jordan Borean 8 months ago committed by GitHub
parent 2324b6852c
commit 8e07b46bde
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

@ -197,7 +197,7 @@ from ansible.utils.display import Display
try:
import winrm
from winrm.exceptions import WinRMError, WinRMOperationTimeoutError
from winrm.exceptions import WinRMError, WinRMOperationTimeoutError, WinRMTransportError
from winrm.protocol import Protocol
import requests.exceptions
HAS_WINRM = True
@ -664,7 +664,19 @@ class Connection(ConnectionBase):
raise AnsibleConnectionFailure('winrm connection error: %s' % to_native(exc))
finally:
if command_id:
self.protocol.cleanup_command(self.shell_id, 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)
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):

@ -30,3 +30,15 @@
- win_ssh_async.rc == 0
- win_ssh_async.stdout == "café\n"
- 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:
- winrm_copy_empty is changed
- 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