From 402b095841d901b012f20e9473bdee6b0f43a398 Mon Sep 17 00:00:00 2001 From: sethp-nr <30441101+sethp-nr@users.noreply.github.com> Date: Thu, 12 Oct 2017 08:37:20 -0700 Subject: [PATCH] wait_for: treat broken connections as "unready" (#28839) * wait_for: treat broken connections as "unready" We have observed the following condition while waiting for hosts: ``` Traceback (most recent call last): File "/var/folders/f8/23xp00654plcv2b2tcc028680000gn/T/ansible_8hxm4_/ansible_module_wait_for.py", line 585, in main() File "/var/folders/f8/23xp00654plcv2b2tcc028680000gn/T/ansible_8hxm4_/ansible_module_wait_for.py", line 535, in main s.shutdown(socket.SHUT_RDWR) File "/usr/local/opt/python/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 228, in meth return getattr(self._sock,name)(*args) socket.error: [Errno 57] Socket is not connected ``` This appears to happen while the host is still starting; we believe something is accepting our connection but immediately resetting it. In these cases, we'd prefer to continue waiting instead of immediately failing the play. This patch has been applied locally for some time, and we have seen no adverse effects. * wait_for: fixup change We were missing an import and a space after the `#` --- .../modules/utilities/logic/wait_for.py | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/ansible/modules/utilities/logic/wait_for.py b/lib/ansible/modules/utilities/logic/wait_for.py index 2366239e94..879b09ad46 100644 --- a/lib/ansible/modules/utilities/logic/wait_for.py +++ b/lib/ansible/modules/utilities/logic/wait_for.py @@ -168,6 +168,7 @@ EXAMPLES = r''' import binascii import datetime +import errno import math import os import re @@ -558,15 +559,27 @@ def main(): break # Shutdown the client socket - s.shutdown(socket.SHUT_RDWR) - s.close() + try: + s.shutdown(socket.SHUT_RDWR) + except socket.error as e: + if e.errno != errno.ENOTCONN: + raise + # else, the server broke the connection on its end, assume it's not ready + else: + s.close() if matched: # Found our string, success! break else: # Connection established, success! - s.shutdown(socket.SHUT_RDWR) - s.close() + try: + s.shutdown(socket.SHUT_RDWR) + except socket.error as e: + if e.errno != errno.ENOTCONN: + raise + # else, the server broke the connection on its end, assume it's not ready + else: + s.close() break # Conditions not yet met, wait and try again