Skip to content

Commit 20be7d5

Browse files
authored
Merge pull request #1259 from docker/1.10.4-release
1.10.4 release
2 parents 5b44771 + 413832f commit 20be7d5

20 files changed

+255
-122
lines changed

docker/client.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def __init__(self, base_url=None, version=None,
8686
tls.configure_client(self)
8787
elif tls:
8888
self._custom_adapter = ssladapter.SSLAdapter(
89-
num_pools=num_pools
89+
pool_connections=num_pools
9090
)
9191
self.mount('https://', self._custom_adapter)
9292
self.base_url = base_url
@@ -218,7 +218,9 @@ def _create_websocket_connection(self, url):
218218

219219
def _get_raw_response_socket(self, response):
220220
self._raise_for_status(response)
221-
if six.PY3:
221+
if self.base_url == "http+docker://localnpipe":
222+
sock = response.raw._fp.fp.raw.sock
223+
elif six.PY3:
222224
sock = response.raw._fp.fp.raw
223225
if self.base_url.startswith("https://"):
224226
sock = sock._sock

docker/transport/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
from .unixconn import UnixAdapter
33
try:
44
from .npipeconn import NpipeAdapter
5+
from .npipesocket import NpipeSocket
56
except ImportError:
67
pass

docker/transport/npipeconn.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
except ImportError:
1515
import urllib3
1616

17-
1817
RecentlyUsedContainer = urllib3._collections.RecentlyUsedContainer
1918

2019

@@ -46,6 +45,28 @@ def _new_conn(self):
4645
self.npipe_path, self.timeout
4746
)
4847

48+
# When re-using connections, urllib3 tries to call select() on our
49+
# NpipeSocket instance, causing a crash. To circumvent this, we override
50+
# _get_conn, where that check happens.
51+
def _get_conn(self, timeout):
52+
conn = None
53+
try:
54+
conn = self.pool.get(block=self.block, timeout=timeout)
55+
56+
except AttributeError: # self.pool is None
57+
raise urllib3.exceptions.ClosedPoolError(self, "Pool is closed.")
58+
59+
except six.moves.queue.Empty:
60+
if self.block:
61+
raise urllib3.exceptions.EmptyPoolError(
62+
self,
63+
"Pool reached maximum size and no more "
64+
"connections are allowed."
65+
)
66+
pass # Oh well, we'll create a new connection then
67+
68+
return conn or self._new_conn()
69+
4970

5071
class NpipeAdapter(requests.adapters.HTTPAdapter):
5172
def __init__(self, base_url, timeout=60,

docker/transport/npipesocket.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import functools
22
import io
33

4+
import six
45
import win32file
56
import win32pipe
67

@@ -94,7 +95,7 @@ def makefile(self, mode=None, bufsize=None):
9495
if mode.strip('b') != 'r':
9596
raise NotImplementedError()
9697
rawio = NpipeFileIOBase(self)
97-
if bufsize is None or bufsize < 0:
98+
if bufsize is None or bufsize <= 0:
9899
bufsize = io.DEFAULT_BUFFER_SIZE
99100
return io.BufferedReader(rawio, buffer_size=bufsize)
100101

@@ -114,6 +115,9 @@ def recvfrom_into(self, buf, nbytes=0, flags=0):
114115

115116
@check_closed
116117
def recv_into(self, buf, nbytes=0):
118+
if six.PY2:
119+
return self._recv_into_py2(buf, nbytes)
120+
117121
readbuf = buf
118122
if not isinstance(buf, memoryview):
119123
readbuf = memoryview(buf)
@@ -124,6 +128,12 @@ def recv_into(self, buf, nbytes=0):
124128
)
125129
return len(data)
126130

131+
def _recv_into_py2(self, buf, nbytes):
132+
err, data = win32file.ReadFile(self._handle, nbytes or len(buf))
133+
n = len(data)
134+
buf[:n] = data
135+
return n
136+
127137
@check_closed
128138
def send(self, string, flags=0):
129139
err, nbytes = win32file.WriteFile(self._handle, string)

docker/types/services.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def __init__(self, parallelism=0, delay=None, failure_action='continue'):
152152
class RestartConditionTypesEnum(object):
153153
_values = (
154154
'none',
155-
'on_failure',
155+
'on-failure',
156156
'any',
157157
)
158158
NONE, ON_FAILURE, ANY = _values

docker/utils/socket.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55

66
import six
77

8+
try:
9+
from ..transport import NpipeSocket
10+
except ImportError:
11+
NpipeSocket = type(None)
12+
813

914
class SocketError(Exception):
1015
pass
@@ -14,10 +19,12 @@ def read(socket, n=4096):
1419
"""
1520
Reads at most n bytes from socket
1621
"""
22+
1723
recoverable_errors = (errno.EINTR, errno.EDEADLK, errno.EWOULDBLOCK)
1824

1925
# wait for data to become available
20-
select.select([socket], [], [])
26+
if not isinstance(socket, NpipeSocket):
27+
select.select([socket], [], [])
2128

2229
try:
2330
if hasattr(socket, 'recv'):

docker/utils/utils.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,8 @@ def match_path(path, pattern):
194194
if pattern:
195195
pattern = os.path.relpath(pattern)
196196

197-
pattern_components = pattern.split('/')
198-
path_components = path.split('/')[:len(pattern_components)]
197+
pattern_components = pattern.split(os.path.sep)
198+
path_components = path.split(os.path.sep)[:len(pattern_components)]
199199
return fnmatch('/'.join(path_components), pattern)
200200

201201

@@ -438,8 +438,8 @@ def parse_host(addr, is_win32=False, tls=False):
438438
"Bind address needs a port: {0}".format(addr))
439439

440440
if proto == "http+unix" or proto == 'npipe':
441-
return "{0}://{1}".format(proto, host)
442-
return "{0}://{1}:{2}{3}".format(proto, host, port, path)
441+
return "{0}://{1}".format(proto, host).rstrip('/')
442+
return "{0}://{1}:{2}{3}".format(proto, host, port, path).rstrip('/')
443443

444444

445445
def parse_devices(devices):
@@ -986,6 +986,9 @@ def format_environment(environment):
986986
def format_env(key, value):
987987
if value is None:
988988
return key
989+
if isinstance(value, six.binary_type):
990+
value = value.decode('utf-8')
991+
989992
return u'{key}={value}'.format(key=key, value=value)
990993
return [format_env(*var) for var in six.iteritems(environment)]
991994

docker/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
version = "1.10.3"
1+
version = "1.10.4"
22
version_info = tuple([int(d) for d in version.split("-")[0].split(".")])

docs/change_log.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,31 @@
11
Change Log
22
==========
33

4+
1.10.4
5+
------
6+
7+
[List of PRs / issues for this release](https://github.com/docker/docker-py/milestone/24?closed=1)
8+
9+
### Bugfixes
10+
11+
* Fixed an issue where `RestartPolicy.condition_types.ON_FAILURE` would yield
12+
an invalid value.
13+
* Fixed an issue where the SSL connection adapter would receive an invalid
14+
argument.
15+
* Fixed an issue that caused the Client to fail to reach API endpoints when
16+
the provided `base_url` had a trailing slash.
17+
* Fixed a bug where some `environment` values in `create_container`
18+
containing unicode characters would raise an encoding error.
19+
* Fixed a number of issues tied with named pipe transport on Windows.
20+
* Fixed a bug where inclusion patterns in `.dockerignore` would cause some
21+
excluded files to appear in the build context on Windows.
22+
23+
### Miscellaneous
24+
25+
* Adjusted version requirements for the `requests` library.
26+
* It is now possible to run the docker-py test suite on Windows.
27+
28+
429
1.10.3
530
------
631

requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
requests==2.5.3
1+
requests==2.11.1
22
six>=1.4.0
33
websocket-client==0.32.0
44
backports.ssl_match_hostname>=3.5 ; python_version < '3.5'
55
ipaddress==1.0.16 ; python_version < '3.3'
6-
docker-pycreds==0.2.1
6+
docker-pycreds==0.2.1

0 commit comments

Comments
 (0)