Skip to content

Commit 39f2e9b

Browse files
authored
Make compatible with requests 2.29.0 and urllib3 2.0 (ansible-collections#613)
* Make compatible with requests 2.29.0. * This fix should also work with urllib3 2.0 according to urllib3 maintainer. * Add changelog fragment. * We still need the constraint for CI until Docker SDK for Python has a new release with a fix. * Make modifications to response_class as small as possible. * Revert "We still need the constraint for CI until Docker SDK for Python has a new release with a fix." This reverts commit 698d544. * The pip coming with the ansible-core 2.11 alpine3 image seems to be too old.
1 parent 5a26eee commit 39f2e9b

File tree

10 files changed

+36
-38
lines changed

10 files changed

+36
-38
lines changed

.github/workflows/ansible-test.yml

+8
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ jobs:
101101
- ''
102102
target:
103103
- ''
104+
extra-constraints:
105+
# Specifying this other than '' likely destroys change detection, but at least it will make
106+
# CI pass when necessary...
107+
- ''
104108
exclude:
105109
- ansible: ''
106110
include:
@@ -117,6 +121,7 @@ jobs:
117121
docker: alpine3
118122
python: ''
119123
target: azp/4/
124+
extra-constraints: urllib3 < 2.0.0
120125
- ansible: '2.11'
121126
docker: alpine3
122127
python: ''
@@ -144,6 +149,9 @@ jobs:
144149
git clone --depth=1 --single-branch https://github.com/ansible-collections/community.crypto.git ../../community/crypto
145150
;
146151
git clone --depth=1 --single-branch https://github.com/ansible-collections/community.general.git ../../community/general
152+
${{ matrix.extra-constraints && format('; echo ''{0}'' >> tests/utils/constraints.txt', matrix.extra-constraints) || '' }}
153+
;
154+
cat tests/utils/constraints.txt
147155
pull-request-change-detection: 'true'
148156
target: ${{ matrix.target }}
149157
target-python-version: ${{ matrix.python }}

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Some modules and plugins require Docker CLI, or other external, programs. Some r
2626

2727
Installing the Docker SDK for Python also installs the requirements for the modules and plugins that use `requests`. If you want to directly install the Python libraries instead of the SDK, you need the following ones:
2828

29-
- [requests](https://pypi.org/project/requests/) (versions before 2.29.0);
29+
- [requests](https://pypi.org/project/requests/);
3030
- [pywin32](https://pypi.org/project/pywin32/) when using named pipes on Windows with the Windows 32 API;
3131
- [paramiko](https://pypi.org/project/paramiko/) when using SSH to connect to the Docker daemon with `use_ssh_client=false`;
3232
- [pyOpenSSL](https://pypi.org/project/pyOpenSSL/) when using TLS to connect to the Docker daemon;

changelogs/fragments/613-requests.yml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
bugfixes:
2+
- "Make vendored Docker SDK for Python code compatible with requests 2.29.0 and urllib3 2.0 (https://github.com/ansible-collections/community.docker/pull/613)."

meta/ee-requirements.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
# SPDX-License-Identifier: GPL-3.0-or-later
44

55
docker
6-
urllib3 < 2.0 # TODO see https://github.com/ansible-collections/community.docker/issues/611
7-
requests < 2.29 # TODO see https://github.com/ansible-collections/community.docker/issues/611
6+
urllib3
7+
requests
88
paramiko
99

1010
# We assume that EEs are not based on Windows, and have Python >= 3.5.

plugins/doc_fragments/docker.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ class ModuleDocFragment(object):
289289
communicate with the Docker daemon. It uses code derived from the Docker SDK or Python that is included in this
290290
collection.
291291
requirements:
292-
- requests < 2.29.0 (see U(https://github.com/ansible-collections/community.docker/issues/611))
292+
- requests
293293
- pywin32 (when using named pipes on Windows 32)
294294
- paramiko (when using SSH with I(use_ssh_client=false))
295295
- pyOpenSSL (when using TLS)

plugins/module_utils/_api/_import_helper.py

+10
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,20 @@ class InvalidSchema(Exception):
4242

4343
try:
4444
from requests.packages import urllib3
45+
from requests.packages.urllib3 import connection as urllib3_connection # pylint: disable=unused-import
4546
except ImportError:
4647
try:
4748
import urllib3
49+
from urllib3 import connection as urllib3_connection # pylint: disable=unused-import
4850
except ImportError:
4951
URLLIB3_IMPORT_ERROR = traceback.format_exc()
5052

5153
class _HTTPConnectionPool(object):
5254
pass
5355

56+
class _HTTPConnection(object):
57+
pass
58+
5459
class FakeURLLIB3(object):
5560
def __init__(self):
5661
self._collections = self
@@ -63,7 +68,12 @@ def __init__(self):
6368
self.match_hostname = object()
6469
self.HTTPConnectionPool = _HTTPConnectionPool
6570

71+
class FakeURLLIB3Connection(object):
72+
def __init__(self):
73+
self.HTTPConnection = _HTTPConnection
74+
6675
urllib3 = FakeURLLIB3()
76+
urllib3_connection = FakeURLLIB3Connection()
6777

6878

6979
# Monkey-patching match_hostname with a version that supports

plugins/module_utils/_api/transport/npipeconn.py

+2-8
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,18 @@
1010
from __future__ import (absolute_import, division, print_function)
1111
__metaclass__ = type
1212

13-
from ansible.module_utils.six import PY3
1413
from ansible.module_utils.six.moves.queue import Empty
1514

1615
from .. import constants
17-
from .._import_helper import HTTPAdapter, urllib3
16+
from .._import_helper import HTTPAdapter, urllib3, urllib3_connection
1817

1918
from .basehttpadapter import BaseHTTPAdapter
2019
from .npipesocket import NpipeSocket
2120

22-
if PY3:
23-
import http.client as httplib
24-
else:
25-
import httplib
26-
2721
RecentlyUsedContainer = urllib3._collections.RecentlyUsedContainer
2822

2923

30-
class NpipeHTTPConnection(httplib.HTTPConnection, object):
24+
class NpipeHTTPConnection(urllib3_connection.HTTPConnection, object):
3125
def __init__(self, npipe_path, timeout=60):
3226
super(NpipeHTTPConnection, self).__init__(
3327
'localhost', timeout=timeout

plugins/module_utils/_api/transport/sshconn.py

+2-7
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,7 @@
2424
from .basehttpadapter import BaseHTTPAdapter
2525
from .. import constants
2626

27-
if PY3:
28-
import http.client as httplib
29-
else:
30-
import httplib
31-
32-
from .._import_helper import HTTPAdapter, urllib3
27+
from .._import_helper import HTTPAdapter, urllib3, urllib3_connection
3328

3429
PARAMIKO_IMPORT_ERROR = None
3530
try:
@@ -120,7 +115,7 @@ def close(self):
120115
self.proc.terminate()
121116

122117

123-
class SSHConnection(httplib.HTTPConnection, object):
118+
class SSHConnection(urllib3_connection.HTTPConnection, object):
124119
def __init__(self, ssh_transport=None, timeout=60, host=None):
125120
super(SSHConnection, self).__init__(
126121
'localhost', timeout=timeout

plugins/module_utils/_api/transport/unixconn.py

+8-17
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,17 @@
1313
import socket
1414

1515
from ansible.module_utils.six import PY2
16-
from ansible.module_utils.six.moves import http_client as httplib
1716

1817
from .basehttpadapter import BaseHTTPAdapter
1918
from .. import constants
2019

21-
from .._import_helper import HTTPAdapter, urllib3
20+
from .._import_helper import HTTPAdapter, urllib3, urllib3_connection
2221

2322

2423
RecentlyUsedContainer = urllib3._collections.RecentlyUsedContainer
2524

2625

27-
class UnixHTTPResponse(httplib.HTTPResponse, object):
28-
def __init__(self, sock, *args, **kwargs):
29-
disable_buffering = kwargs.pop('disable_buffering', False)
30-
if PY2:
31-
# FIXME: We may need to disable buffering on Py3 as well,
32-
# but there's no clear way to do it at the moment. See:
33-
# https://github.com/docker/docker-py/issues/1799
34-
kwargs['buffering'] = not disable_buffering
35-
super(UnixHTTPResponse, self).__init__(sock, *args, **kwargs)
36-
37-
38-
class UnixHTTPConnection(httplib.HTTPConnection, object):
26+
class UnixHTTPConnection(urllib3_connection.HTTPConnection, object):
3927

4028
def __init__(self, base_url, unix_socket, timeout=60):
4129
super(UnixHTTPConnection, self).__init__(
@@ -58,10 +46,13 @@ def putheader(self, header, *values):
5846
self.disable_buffering = True
5947

6048
def response_class(self, sock, *args, **kwargs):
61-
if self.disable_buffering:
62-
kwargs['disable_buffering'] = True
49+
if PY2:
50+
# FIXME: We may need to disable buffering on Py3 as well,
51+
# but there's no clear way to do it at the moment. See:
52+
# https://github.com/docker/docker-py/issues/1799
53+
kwargs['buffering'] = not self.disable_buffering
6354

64-
return UnixHTTPResponse(sock, *args, **kwargs)
55+
return super(UnixHTTPConnection, self).response_class(sock, *args, **kwargs)
6556

6657

6758
class UnixHTTPConnectionPool(urllib3.connectionpool.HTTPConnectionPool):

tests/utils/constraints.txt

-2
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,11 @@ coverage >= 4.5.4, < 5.0.0 ; python_version > '3.7' # coverage had a bug in < 4.
1010
cryptography >= 1.3.0, < 2.2 ; python_version < '2.7' # cryptography 2.2 drops support for python 2.6
1111
cryptography >= 1.3.0, < 3.4 ; python_version < '3.6' # cryptography 3.4 drops support for python 2.7
1212
urllib3 < 1.24 ; python_version < '2.7' # urllib3 1.24 and later require python 2.7 or later
13-
urllib3 < 2.0.0 # TODO see https://github.com/ansible-collections/community.docker/issues/611
1413
wheel < 0.30.0 ; python_version < '2.7' # wheel 0.30.0 and later require python 2.7 or later
1514
paramiko < 2.4.0 ; python_version < '2.7' # paramiko 2.4.0 drops support for python 2.6
1615
paramiko < 3.0.0 ; python_version < '3.7' # paramiko 3.0.0 forces installation of a too new cryptography
1716
requests < 2.20.0 ; python_version < '2.7' # requests 2.20.0 drops support for python 2.6
1817
requests < 2.28 ; python_version < '3.7' # requests 2.28.0 drops support for python < 3.7
19-
requests < 2.29 # TODO see https://github.com/ansible-collections/community.docker/issues/611
2018
virtualenv < 16.0.0 ; python_version < '2.7' # virtualenv 16.0.0 and later require python 2.7 or later
2119
pyopenssl < 18.0.0 ; python_version < '2.7' # pyOpenSSL 18.0.0 and later require python 2.7 or later
2220
setuptools < 45 ; python_version <= '2.7' # setuptools 45 and later require python 3.5 or later

0 commit comments

Comments
 (0)