Skip to content

Commit 91bc75c

Browse files
authored
Merge pull request #1891 from docker/3.0.0-release
3.0.0 release
2 parents 5bed7b8 + 9a87f80 commit 91bc75c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+2634
-2535
lines changed

.travis.yml

+13-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
sudo: false
22
language: python
3-
python:
4-
- "3.5"
5-
env:
6-
- TOX_ENV=py27
7-
# FIXME: default travis worker does not carry py33 anymore. Can this be configured?
8-
# - TOX_ENV=py33
9-
- TOX_ENV=py34
10-
- TOX_ENV=py35
11-
- TOX_ENV=flake8
3+
matrix:
4+
include:
5+
- python: 2.7
6+
env: TOXENV=py27
7+
- python: 3.4
8+
env: TOXENV=py34
9+
- python: 3.5
10+
env: TOXENV=py35
11+
- python: 3.6
12+
env: TOXENV=py36
13+
- env: TOXENV=flake8
14+
1215
install:
1316
- pip install tox
1417
script:
15-
- tox -e $TOX_ENV
18+
- tox

Dockerfile-py3

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM python:3.5
1+
FROM python:3.6
22

33
RUN mkdir /src
44
WORKDIR /src

Jenkinsfile

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ def imageNamePy2
55
def imageNamePy3
66
def images = [:]
77

8-
def dockerVersions = ["17.06.2-ce", "17.09.0-ce", "17.10.0-ce"]
8+
def dockerVersions = ["17.06.2-ce", "17.12.0-ce", "18.01.0-ce"]
99

1010
def buildImage = { name, buildargs, pyTag ->
1111
img = docker.image(name)
@@ -27,13 +27,13 @@ def buildImages = { ->
2727
imageNamePy3 = "${imageNameBase}:py3-${gitCommit()}"
2828

2929
buildImage(imageNamePy2, ".", "py2.7")
30-
buildImage(imageNamePy3, "-f Dockerfile-py3 .", "py3.5")
30+
buildImage(imageNamePy3, "-f Dockerfile-py3 .", "py3.6")
3131
}
3232
}
3333
}
3434

3535
def getAPIVersion = { engineVersion ->
36-
def versionMap = ['17.06': '1.30', '17.09': '1.32', '17.10': '1.33']
36+
def versionMap = ['17.06': '1.30', '17.12': '1.35', '18.01': '1.35']
3737
return versionMap[engineVersion.substring(0, 5)]
3838
}
3939

Makefile

+19-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ all: test
33

44
.PHONY: clean
55
clean:
6-
-docker rm -vf dpy-dind
6+
-docker rm -f dpy-dind-py2 dpy-dind-py3
77
find -name "__pycache__" | xargs rm -rf
88

99
.PHONY: build
@@ -41,19 +41,29 @@ integration-test: build
4141
integration-test-py3: build-py3
4242
docker run -t --rm -v /var/run/docker.sock:/var/run/docker.sock docker-sdk-python3 py.test tests/integration/${file}
4343

44-
TEST_API_VERSION ?= 1.33
45-
TEST_ENGINE_VERSION ?= 17.10.0-ce
44+
TEST_API_VERSION ?= 1.35
45+
TEST_ENGINE_VERSION ?= 17.12.0-ce
4646

4747
.PHONY: integration-dind
48-
integration-dind: build build-py3
49-
docker rm -vf dpy-dind || :
50-
docker run -d --name dpy-dind --privileged dockerswarm/dind:${TEST_ENGINE_VERSION} dockerd\
48+
integration-dind: integration-dind-py2 integration-dind-py3
49+
50+
.PHONY: integration-dind-py2
51+
integration-dind-py2: build
52+
docker rm -vf dpy-dind-py2 || :
53+
docker run -d --name dpy-dind-py2 --privileged dockerswarm/dind:${TEST_ENGINE_VERSION} dockerd\
5154
-H tcp://0.0.0.0:2375 --experimental
5255
docker run -t --rm --env="DOCKER_HOST=tcp://docker:2375" --env="DOCKER_TEST_API_VERSION=${TEST_API_VERSION}"\
53-
--link=dpy-dind:docker docker-sdk-python py.test tests/integration
56+
--link=dpy-dind-py2:docker docker-sdk-python py.test tests/integration
57+
docker rm -vf dpy-dind-py2
58+
59+
.PHONY: integration-dind-py3
60+
integration-dind-py3: build-py3
61+
docker rm -vf dpy-dind-py3 || :
62+
docker run -d --name dpy-dind-py3 --privileged dockerswarm/dind:${TEST_ENGINE_VERSION} dockerd\
63+
-H tcp://0.0.0.0:2375 --experimental
5464
docker run -t --rm --env="DOCKER_HOST=tcp://docker:2375" --env="DOCKER_TEST_API_VERSION=${TEST_API_VERSION}"\
55-
--link=dpy-dind:docker docker-sdk-python3 py.test tests/integration
56-
docker rm -vf dpy-dind
65+
--link=dpy-dind-py3:docker docker-sdk-python3 py.test tests/integration
66+
docker rm -vf dpy-dind-py3
5767

5868
.PHONY: integration-dind-ssl
5969
integration-dind-ssl: build-dind-certs build build-py3

appveyor.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ version: '{branch}-{build}'
33
install:
44
- "SET PATH=C:\\Python27-x64;C:\\Python27-x64\\Scripts;%PATH%"
55
- "python --version"
6-
- "pip install tox==2.7.0 virtualenv==15.1.0"
6+
- "pip install tox==2.9.1"
77

88
# Build the binary after tests
99
build: false

docker/api/build.py

+22-48
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import json
22
import logging
33
import os
4-
import re
54

65
from .. import auth
76
from .. import constants
@@ -14,12 +13,12 @@
1413

1514
class BuildApiMixin(object):
1615
def build(self, path=None, tag=None, quiet=False, fileobj=None,
17-
nocache=False, rm=False, stream=False, timeout=None,
16+
nocache=False, rm=False, timeout=None,
1817
custom_context=False, encoding=None, pull=False,
1918
forcerm=False, dockerfile=None, container_limits=None,
2019
decode=False, buildargs=None, gzip=False, shmsize=None,
2120
labels=None, cache_from=None, target=None, network_mode=None,
22-
squash=None, extra_hosts=None):
21+
squash=None, extra_hosts=None, platform=None):
2322
"""
2423
Similar to the ``docker build`` command. Either ``path`` or ``fileobj``
2524
needs to be set. ``path`` can be a local path (to a directory
@@ -67,9 +66,6 @@ def build(self, path=None, tag=None, quiet=False, fileobj=None,
6766
rm (bool): Remove intermediate containers. The ``docker build``
6867
command now defaults to ``--rm=true``, but we have kept the old
6968
default of `False` to preserve backward compatibility
70-
stream (bool): *Deprecated for API version > 1.8 (always True)*.
71-
Return a blocking generator you can iterate over to retrieve
72-
build output as it happens
7369
timeout (int): HTTP timeout
7470
custom_context (bool): Optional if using ``fileobj``
7571
encoding (str): The encoding for a stream. Set to ``gzip`` for
@@ -103,6 +99,7 @@ def build(self, path=None, tag=None, quiet=False, fileobj=None,
10399
single layer.
104100
extra_hosts (dict): Extra hosts to add to /etc/hosts in building
105101
containers, as a mapping of hostname to IP address.
102+
platform (str): Platform in the format ``os[/arch[/variant]]``
106103
107104
Returns:
108105
A generator for the build output.
@@ -145,23 +142,14 @@ def build(self, path=None, tag=None, quiet=False, fileobj=None,
145142
exclude = None
146143
if os.path.exists(dockerignore):
147144
with open(dockerignore, 'r') as f:
148-
exclude = list(filter(bool, f.read().splitlines()))
145+
exclude = list(filter(
146+
bool, [l.strip() for l in f.read().splitlines()]
147+
))
149148
context = utils.tar(
150149
path, exclude=exclude, dockerfile=dockerfile, gzip=gzip
151150
)
152151
encoding = 'gzip' if gzip else encoding
153152

154-
if utils.compare_version('1.8', self._version) >= 0:
155-
stream = True
156-
157-
if dockerfile and utils.compare_version('1.17', self._version) < 0:
158-
raise errors.InvalidVersion(
159-
'dockerfile was only introduced in API version 1.17'
160-
)
161-
162-
if utils.compare_version('1.19', self._version) < 0:
163-
pull = 1 if pull else 0
164-
165153
u = self._url('/build')
166154
params = {
167155
't': tag,
@@ -176,12 +164,7 @@ def build(self, path=None, tag=None, quiet=False, fileobj=None,
176164
params.update(container_limits)
177165

178166
if buildargs:
179-
if utils.version_gte(self._version, '1.21'):
180-
params.update({'buildargs': json.dumps(buildargs)})
181-
else:
182-
raise errors.InvalidVersion(
183-
'buildargs was only introduced in API version 1.21'
184-
)
167+
params.update({'buildargs': json.dumps(buildargs)})
185168

186169
if shmsize:
187170
if utils.version_gte(self._version, '1.22'):
@@ -241,35 +224,33 @@ def build(self, path=None, tag=None, quiet=False, fileobj=None,
241224
extra_hosts = utils.format_extra_hosts(extra_hosts)
242225
params.update({'extrahosts': extra_hosts})
243226

227+
if platform is not None:
228+
if utils.version_lt(self._version, '1.32'):
229+
raise errors.InvalidVersion(
230+
'platform was only introduced in API version 1.32'
231+
)
232+
params['platform'] = platform
233+
244234
if context is not None:
245235
headers = {'Content-Type': 'application/tar'}
246236
if encoding:
247237
headers['Content-Encoding'] = encoding
248238

249-
if utils.compare_version('1.9', self._version) >= 0:
250-
self._set_auth_headers(headers)
239+
self._set_auth_headers(headers)
251240

252241
response = self._post(
253242
u,
254243
data=context,
255244
params=params,
256245
headers=headers,
257-
stream=stream,
246+
stream=True,
258247
timeout=timeout,
259248
)
260249

261250
if context is not None and not custom_context:
262251
context.close()
263252

264-
if stream:
265-
return self._stream_helper(response, decode=decode)
266-
else:
267-
output = self._result(response)
268-
srch = r'Successfully built ([0-9a-f]+)'
269-
match = re.search(srch, output)
270-
if not match:
271-
return None, output
272-
return match.group(1), output
253+
return self._stream_helper(response, decode=decode)
273254

274255
def _set_auth_headers(self, headers):
275256
log.debug('Looking for auth config')
@@ -290,14 +271,12 @@ def _set_auth_headers(self, headers):
290271
# Matches CLI behavior: https://github.com/docker/docker/blob/
291272
# 67b85f9d26f1b0b2b240f2d794748fac0f45243c/cliconfig/
292273
# credentials/native_store.go#L68-L83
293-
for registry in self._auth_configs.keys():
294-
if registry == 'credsStore' or registry == 'HttpHeaders':
295-
continue
274+
for registry in self._auth_configs.get('auths', {}).keys():
296275
auth_data[registry] = auth.resolve_authconfig(
297276
self._auth_configs, registry
298277
)
299278
else:
300-
auth_data = self._auth_configs.copy()
279+
auth_data = self._auth_configs.get('auths', {}).copy()
301280
# See https://github.com/docker/docker-py/issues/1683
302281
if auth.INDEX_NAME in auth_data:
303282
auth_data[auth.INDEX_URL] = auth_data[auth.INDEX_NAME]
@@ -308,13 +287,8 @@ def _set_auth_headers(self, headers):
308287
)
309288
)
310289

311-
if utils.compare_version('1.19', self._version) >= 0:
312-
headers['X-Registry-Config'] = auth.encode_header(
313-
auth_data
314-
)
315-
else:
316-
headers['X-Registry-Config'] = auth.encode_header({
317-
'configs': auth_data
318-
})
290+
headers['X-Registry-Config'] = auth.encode_header(
291+
auth_data
292+
)
319293
else:
320294
log.debug('No auth config found')

docker/api/client.py

+11-24
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import json
22
import struct
3-
import warnings
43
from functools import partial
54

65
import requests
@@ -27,12 +26,12 @@
2726
MINIMUM_DOCKER_API_VERSION
2827
)
2928
from ..errors import (
30-
DockerException, TLSParameterError,
29+
DockerException, InvalidVersion, TLSParameterError,
3130
create_api_error_from_http_exception
3231
)
3332
from ..tls import TLSConfig
3433
from ..transport import SSLAdapter, UnixAdapter
35-
from ..utils import utils, check_resource, update_headers
34+
from ..utils import utils, check_resource, update_headers, config
3635
from ..utils.socket import frames_iter, socket_raw_iter
3736
from ..utils.json_stream import json_stream
3837
try:
@@ -87,6 +86,7 @@ class APIClient(
8786
"""
8887

8988
__attrs__ = requests.Session.__attrs__ + ['_auth_configs',
89+
'_general_configs',
9090
'_version',
9191
'base_url',
9292
'timeout']
@@ -105,7 +105,10 @@ def __init__(self, base_url=None, version=None,
105105
self.timeout = timeout
106106
self.headers['User-Agent'] = user_agent
107107

108-
self._auth_configs = auth.load_config()
108+
self._general_configs = config.load_general_config()
109+
self._auth_configs = auth.load_config(
110+
config_dict=self._general_configs
111+
)
109112

110113
base_url = utils.parse_host(
111114
base_url, IS_WINDOWS_PLATFORM, tls=bool(tls)
@@ -156,11 +159,9 @@ def __init__(self, base_url=None, version=None,
156159
)
157160
)
158161
if utils.version_lt(self._version, MINIMUM_DOCKER_API_VERSION):
159-
warnings.warn(
160-
'The minimum API version supported is {}, but you are using '
161-
'version {}. It is recommended you either upgrade Docker '
162-
'Engine or use an older version of Docker SDK for '
163-
'Python.'.format(MINIMUM_DOCKER_API_VERSION, self._version)
162+
raise InvalidVersion(
163+
'API versions below {} are no longer supported by this '
164+
'library.'.format(MINIMUM_DOCKER_API_VERSION)
164165
)
165166

166167
def _retrieve_server_version(self):
@@ -349,17 +350,8 @@ def _multiplexed_response_stream_helper(self, response):
349350
break
350351
yield data
351352

352-
def _stream_raw_result_old(self, response):
353-
''' Stream raw output for API versions below 1.6 '''
354-
self._raise_for_status(response)
355-
for line in response.iter_lines(chunk_size=1,
356-
decode_unicode=True):
357-
# filter out keep-alive new lines
358-
if line:
359-
yield line
360-
361353
def _stream_raw_result(self, response):
362-
''' Stream result for TTY-enabled container above API 1.6 '''
354+
''' Stream result for TTY-enabled container '''
363355
self._raise_for_status(response)
364356
for out in response.iter_content(chunk_size=1, decode_unicode=True):
365357
yield out
@@ -415,11 +407,6 @@ def _get_result(self, container, stream, res):
415407
return self._get_result_tty(stream, res, self._check_is_tty(container))
416408

417409
def _get_result_tty(self, stream, res, is_tty):
418-
# Stream multi-plexing was only introduced in API v1.6. Anything
419-
# before that needs old-style streaming.
420-
if utils.compare_version('1.6', self._version) < 0:
421-
return self._stream_raw_result_old(res)
422-
423410
# We should also use raw streaming (without keep-alives)
424411
# if we're dealing with a tty-enabled container.
425412
if is_tty:

0 commit comments

Comments
 (0)