From e3009ab365203b63174251d5f5c2f90f64fd395e Mon Sep 17 00:00:00 2001 From: Alex Oughton Date: Thu, 18 Aug 2016 15:20:40 -0500 Subject: [PATCH] Disables TCP_KEEPCNT when using Windows Subsystem for Linux The Windows Subsystem for Linux is not a complete implementation of the Linux APIs, and setting TCP_KEEPCNT is currently unimplmenented. Attempting to use this option will cause HTTP connections to fail. This change checks if we are running under WSL, and disables changing TCP_KEEPCNT parameters if so. Change-Id: Ic8b41dea2a75660d9adbce88a00a0fe703a4d120 Closes-Bug: #1614688 --- keystoneauth1/_utils.py | 8 ++++++++ keystoneauth1/session.py | 4 +++- keystoneauth1/tests/unit/test_session.py | 18 ++++++++++++++++++ .../notes/bug-1614688-c4a1bd54f4ba5644.yaml | 9 +++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/bug-1614688-c4a1bd54f4ba5644.yaml diff --git a/keystoneauth1/_utils.py b/keystoneauth1/_utils.py index cbc1b0e2..2d6f0aef 100644 --- a/keystoneauth1/_utils.py +++ b/keystoneauth1/_utils.py @@ -73,3 +73,11 @@ def before_utcnow(**timedelta_kwargs): now = datetime.datetime.utcnow() delta = datetime.timedelta(**timedelta_kwargs) return now - delta + + +# Detect if running on the Windows Subsystem for Linux +try: + with open('/proc/version', 'r') as f: + is_windows_linux_subsystem = 'microsoft' in f.read().lower() +except IOError: + is_windows_linux_subsystem = False diff --git a/keystoneauth1/session.py b/keystoneauth1/session.py index a790a3d4..d1fe3697 100644 --- a/keystoneauth1/session.py +++ b/keystoneauth1/session.py @@ -893,7 +893,9 @@ class TCPKeepAliveAdapter(requests.adapters.HTTPAdapter): (socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 60) ] - if hasattr(socket, 'TCP_KEEPCNT'): + # Windows subsystem for Linux does not support this feature + if (hasattr(socket, 'TCP_KEEPCNT') and + not utils.is_windows_linux_subsystem): socket_options += [ # Set the maximum number of keep-alive probes (socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 4), diff --git a/keystoneauth1/tests/unit/test_session.py b/keystoneauth1/tests/unit/test_session.py index 4a083472..3a43abb9 100644 --- a/keystoneauth1/tests/unit/test_session.py +++ b/keystoneauth1/tests/unit/test_session.py @@ -1060,6 +1060,7 @@ class TCPKeepAliveAdapterTest(utils.TestCase): def test_init_poolmanager_with_tcp_keepcnt(self): self.patch(client_session, 'REQUESTS_VERSION', (2, 4, 1)) + self.patch(client_session.utils, 'is_windows_linux_subsystem', False) socket = self.patch_socket_with_options( ['IPPROTO_TCP', 'TCP_NODELAY', 'SOL_SOCKET', 'SO_KEEPALIVE', 'TCP_KEEPCNT']) @@ -1075,6 +1076,23 @@ class TCPKeepAliveAdapterTest(utils.TestCase): (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1), (socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 4)]) + def test_init_poolmanager_with_tcp_keepcnt_on_windows(self): + self.patch(client_session, 'REQUESTS_VERSION', (2, 4, 1)) + self.patch(client_session.utils, 'is_windows_linux_subsystem', True) + socket = self.patch_socket_with_options( + ['IPPROTO_TCP', 'TCP_NODELAY', 'SOL_SOCKET', 'SO_KEEPALIVE', + 'TCP_KEEPCNT']) + given_adapter = client_session.TCPKeepAliveAdapter() + + # when pool manager is initialized + given_adapter.init_poolmanager(1, 2, 3) + + # then socket_options are given + self.init_poolmanager.assert_called_once_with( + 1, 2, 3, socket_options=[ + (socket.IPPROTO_TCP, socket.TCP_NODELAY, 1), + (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)]) + def test_init_poolmanager_with_tcp_keepintvl(self): self.patch(client_session, 'REQUESTS_VERSION', (2, 4, 1)) socket = self.patch_socket_with_options( diff --git a/releasenotes/notes/bug-1614688-c4a1bd54f4ba5644.yaml b/releasenotes/notes/bug-1614688-c4a1bd54f4ba5644.yaml new file mode 100644 index 00000000..2883c699 --- /dev/null +++ b/releasenotes/notes/bug-1614688-c4a1bd54f4ba5644.yaml @@ -0,0 +1,9 @@ +--- +prelude: > + HTTP connections work under Windows Subsystem for Linux +fixes: + - > + [`bug 1614688 `_] + HTTP connections were failing under Windows subsystem for Linux because + TCP_KEEPCNT was being set and that environment does not support such + override yet.