Skip to content

Commit

Permalink
Merge pull request #1891 from docker/3.0.0-release
Browse files Browse the repository at this point in the history
3.0.0 release
  • Loading branch information
shin- authored Feb 1, 2018
2 parents 5bed7b8 + 9a87f80 commit 91bc75c
Show file tree
Hide file tree
Showing 69 changed files with 2,634 additions and 2,535 deletions.
23 changes: 13 additions & 10 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
sudo: false
language: python
python:
- "3.5"
env:
- TOX_ENV=py27
# FIXME: default travis worker does not carry py33 anymore. Can this be configured?
# - TOX_ENV=py33
- TOX_ENV=py34
- TOX_ENV=py35
- TOX_ENV=flake8
matrix:
include:
- python: 2.7
env: TOXENV=py27
- python: 3.4
env: TOXENV=py34
- python: 3.5
env: TOXENV=py35
- python: 3.6
env: TOXENV=py36
- env: TOXENV=flake8

install:
- pip install tox
script:
- tox -e $TOX_ENV
- tox
2 changes: 1 addition & 1 deletion Dockerfile-py3
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.5
FROM python:3.6

RUN mkdir /src
WORKDIR /src
Expand Down
6 changes: 3 additions & 3 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ def imageNamePy2
def imageNamePy3
def images = [:]

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

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

buildImage(imageNamePy2, ".", "py2.7")
buildImage(imageNamePy3, "-f Dockerfile-py3 .", "py3.5")
buildImage(imageNamePy3, "-f Dockerfile-py3 .", "py3.6")
}
}
}

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

Expand Down
28 changes: 19 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ all: test

.PHONY: clean
clean:
-docker rm -vf dpy-dind
-docker rm -f dpy-dind-py2 dpy-dind-py3
find -name "__pycache__" | xargs rm -rf

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

TEST_API_VERSION ?= 1.33
TEST_ENGINE_VERSION ?= 17.10.0-ce
TEST_API_VERSION ?= 1.35
TEST_ENGINE_VERSION ?= 17.12.0-ce

.PHONY: integration-dind
integration-dind: build build-py3
docker rm -vf dpy-dind || :
docker run -d --name dpy-dind --privileged dockerswarm/dind:${TEST_ENGINE_VERSION} dockerd\
integration-dind: integration-dind-py2 integration-dind-py3

.PHONY: integration-dind-py2
integration-dind-py2: build
docker rm -vf dpy-dind-py2 || :
docker run -d --name dpy-dind-py2 --privileged dockerswarm/dind:${TEST_ENGINE_VERSION} dockerd\
-H tcp://0.0.0.0:2375 --experimental
docker run -t --rm --env="DOCKER_HOST=tcp://docker:2375" --env="DOCKER_TEST_API_VERSION=${TEST_API_VERSION}"\
--link=dpy-dind:docker docker-sdk-python py.test tests/integration
--link=dpy-dind-py2:docker docker-sdk-python py.test tests/integration
docker rm -vf dpy-dind-py2

.PHONY: integration-dind-py3
integration-dind-py3: build-py3
docker rm -vf dpy-dind-py3 || :
docker run -d --name dpy-dind-py3 --privileged dockerswarm/dind:${TEST_ENGINE_VERSION} dockerd\
-H tcp://0.0.0.0:2375 --experimental
docker run -t --rm --env="DOCKER_HOST=tcp://docker:2375" --env="DOCKER_TEST_API_VERSION=${TEST_API_VERSION}"\
--link=dpy-dind:docker docker-sdk-python3 py.test tests/integration
docker rm -vf dpy-dind
--link=dpy-dind-py3:docker docker-sdk-python3 py.test tests/integration
docker rm -vf dpy-dind-py3

.PHONY: integration-dind-ssl
integration-dind-ssl: build-dind-certs build build-py3
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: '{branch}-{build}'
install:
- "SET PATH=C:\\Python27-x64;C:\\Python27-x64\\Scripts;%PATH%"
- "python --version"
- "pip install tox==2.7.0 virtualenv==15.1.0"
- "pip install tox==2.9.1"

# Build the binary after tests
build: false
Expand Down
70 changes: 22 additions & 48 deletions docker/api/build.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import json
import logging
import os
import re

from .. import auth
from .. import constants
Expand All @@ -14,12 +13,12 @@

class BuildApiMixin(object):
def build(self, path=None, tag=None, quiet=False, fileobj=None,
nocache=False, rm=False, stream=False, timeout=None,
nocache=False, rm=False, timeout=None,
custom_context=False, encoding=None, pull=False,
forcerm=False, dockerfile=None, container_limits=None,
decode=False, buildargs=None, gzip=False, shmsize=None,
labels=None, cache_from=None, target=None, network_mode=None,
squash=None, extra_hosts=None):
squash=None, extra_hosts=None, platform=None):
"""
Similar to the ``docker build`` command. Either ``path`` or ``fileobj``
needs to be set. ``path`` can be a local path (to a directory
Expand Down Expand Up @@ -67,9 +66,6 @@ def build(self, path=None, tag=None, quiet=False, fileobj=None,
rm (bool): Remove intermediate containers. The ``docker build``
command now defaults to ``--rm=true``, but we have kept the old
default of `False` to preserve backward compatibility
stream (bool): *Deprecated for API version > 1.8 (always True)*.
Return a blocking generator you can iterate over to retrieve
build output as it happens
timeout (int): HTTP timeout
custom_context (bool): Optional if using ``fileobj``
encoding (str): The encoding for a stream. Set to ``gzip`` for
Expand Down Expand Up @@ -103,6 +99,7 @@ def build(self, path=None, tag=None, quiet=False, fileobj=None,
single layer.
extra_hosts (dict): Extra hosts to add to /etc/hosts in building
containers, as a mapping of hostname to IP address.
platform (str): Platform in the format ``os[/arch[/variant]]``
Returns:
A generator for the build output.
Expand Down Expand Up @@ -145,23 +142,14 @@ def build(self, path=None, tag=None, quiet=False, fileobj=None,
exclude = None
if os.path.exists(dockerignore):
with open(dockerignore, 'r') as f:
exclude = list(filter(bool, f.read().splitlines()))
exclude = list(filter(
bool, [l.strip() for l in f.read().splitlines()]
))
context = utils.tar(
path, exclude=exclude, dockerfile=dockerfile, gzip=gzip
)
encoding = 'gzip' if gzip else encoding

if utils.compare_version('1.8', self._version) >= 0:
stream = True

if dockerfile and utils.compare_version('1.17', self._version) < 0:
raise errors.InvalidVersion(
'dockerfile was only introduced in API version 1.17'
)

if utils.compare_version('1.19', self._version) < 0:
pull = 1 if pull else 0

u = self._url('/build')
params = {
't': tag,
Expand All @@ -176,12 +164,7 @@ def build(self, path=None, tag=None, quiet=False, fileobj=None,
params.update(container_limits)

if buildargs:
if utils.version_gte(self._version, '1.21'):
params.update({'buildargs': json.dumps(buildargs)})
else:
raise errors.InvalidVersion(
'buildargs was only introduced in API version 1.21'
)
params.update({'buildargs': json.dumps(buildargs)})

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

if platform is not None:
if utils.version_lt(self._version, '1.32'):
raise errors.InvalidVersion(
'platform was only introduced in API version 1.32'
)
params['platform'] = platform

if context is not None:
headers = {'Content-Type': 'application/tar'}
if encoding:
headers['Content-Encoding'] = encoding

if utils.compare_version('1.9', self._version) >= 0:
self._set_auth_headers(headers)
self._set_auth_headers(headers)

response = self._post(
u,
data=context,
params=params,
headers=headers,
stream=stream,
stream=True,
timeout=timeout,
)

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

if stream:
return self._stream_helper(response, decode=decode)
else:
output = self._result(response)
srch = r'Successfully built ([0-9a-f]+)'
match = re.search(srch, output)
if not match:
return None, output
return match.group(1), output
return self._stream_helper(response, decode=decode)

def _set_auth_headers(self, headers):
log.debug('Looking for auth config')
Expand All @@ -290,14 +271,12 @@ def _set_auth_headers(self, headers):
# Matches CLI behavior: https://github.com/docker/docker/blob/
# 67b85f9d26f1b0b2b240f2d794748fac0f45243c/cliconfig/
# credentials/native_store.go#L68-L83
for registry in self._auth_configs.keys():
if registry == 'credsStore' or registry == 'HttpHeaders':
continue
for registry in self._auth_configs.get('auths', {}).keys():
auth_data[registry] = auth.resolve_authconfig(
self._auth_configs, registry
)
else:
auth_data = self._auth_configs.copy()
auth_data = self._auth_configs.get('auths', {}).copy()
# See https://github.com/docker/docker-py/issues/1683
if auth.INDEX_NAME in auth_data:
auth_data[auth.INDEX_URL] = auth_data[auth.INDEX_NAME]
Expand All @@ -308,13 +287,8 @@ def _set_auth_headers(self, headers):
)
)

if utils.compare_version('1.19', self._version) >= 0:
headers['X-Registry-Config'] = auth.encode_header(
auth_data
)
else:
headers['X-Registry-Config'] = auth.encode_header({
'configs': auth_data
})
headers['X-Registry-Config'] = auth.encode_header(
auth_data
)
else:
log.debug('No auth config found')
35 changes: 11 additions & 24 deletions docker/api/client.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import json
import struct
import warnings
from functools import partial

import requests
Expand All @@ -27,12 +26,12 @@
MINIMUM_DOCKER_API_VERSION
)
from ..errors import (
DockerException, TLSParameterError,
DockerException, InvalidVersion, TLSParameterError,
create_api_error_from_http_exception
)
from ..tls import TLSConfig
from ..transport import SSLAdapter, UnixAdapter
from ..utils import utils, check_resource, update_headers
from ..utils import utils, check_resource, update_headers, config
from ..utils.socket import frames_iter, socket_raw_iter
from ..utils.json_stream import json_stream
try:
Expand Down Expand Up @@ -87,6 +86,7 @@ class APIClient(
"""

__attrs__ = requests.Session.__attrs__ + ['_auth_configs',
'_general_configs',
'_version',
'base_url',
'timeout']
Expand All @@ -105,7 +105,10 @@ def __init__(self, base_url=None, version=None,
self.timeout = timeout
self.headers['User-Agent'] = user_agent

self._auth_configs = auth.load_config()
self._general_configs = config.load_general_config()
self._auth_configs = auth.load_config(
config_dict=self._general_configs
)

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

def _retrieve_server_version(self):
Expand Down Expand Up @@ -349,17 +350,8 @@ def _multiplexed_response_stream_helper(self, response):
break
yield data

def _stream_raw_result_old(self, response):
''' Stream raw output for API versions below 1.6 '''
self._raise_for_status(response)
for line in response.iter_lines(chunk_size=1,
decode_unicode=True):
# filter out keep-alive new lines
if line:
yield line

def _stream_raw_result(self, response):
''' Stream result for TTY-enabled container above API 1.6 '''
''' Stream result for TTY-enabled container '''
self._raise_for_status(response)
for out in response.iter_content(chunk_size=1, decode_unicode=True):
yield out
Expand Down Expand Up @@ -415,11 +407,6 @@ def _get_result(self, container, stream, res):
return self._get_result_tty(stream, res, self._check_is_tty(container))

def _get_result_tty(self, stream, res, is_tty):
# Stream multi-plexing was only introduced in API v1.6. Anything
# before that needs old-style streaming.
if utils.compare_version('1.6', self._version) < 0:
return self._stream_raw_result_old(res)

# We should also use raw streaming (without keep-alives)
# if we're dealing with a tty-enabled container.
if is_tty:
Expand Down
Loading

0 comments on commit 91bc75c

Please sign in to comment.