Skip to content

Commit

Permalink
Merge pull request #2580 from ulyssessouza/4.2.1-release
Browse files Browse the repository at this point in the history
Bump 4.2.1
  • Loading branch information
ulyssessouza committed Jun 2, 2020
2 parents 1d1532f + 9923746 commit b22095f
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 42 deletions.
6 changes: 2 additions & 4 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def buildImages = { ->
}

def getDockerVersions = { ->
def dockerVersions = ["17.06.2-ce"]
def dockerVersions = ["19.03.5"]
wrappedNode(label: "ubuntu && !zfs && amd64") {
def result = sh(script: """docker run --rm \\
--entrypoint=python \\
Expand All @@ -46,8 +46,6 @@ def getDockerVersions = { ->

def getAPIVersion = { engineVersion ->
def versionMap = [
'17.06': '1.30',
'18.03': '1.37',
'18.09': '1.39',
'19.03': '1.40'
]
Expand Down Expand Up @@ -84,7 +82,7 @@ def runTests = { Map settings ->
try {
sh """docker network create ${testNetwork}"""
sh """docker run -d --name ${dindContainerName} -v /tmp --privileged --network ${testNetwork} \\
dockerswarm/dind:${dockerVersion} dockerd -H tcp://0.0.0.0:2375
docker:${dockerVersion}-dind dockerd -H tcp://0.0.0.0:2375
"""
sh """docker run \\
--name ${testContainerName} \\
Expand Down
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ integration-test-py3: build-py3
docker run -t --rm -v /var/run/docker.sock:/var/run/docker.sock docker-sdk-python3 py.test -v tests/integration/${file}

TEST_API_VERSION ?= 1.35
TEST_ENGINE_VERSION ?= 18.09.5
TEST_ENGINE_VERSION ?= 19.03.5

.PHONY: setup-network
setup-network:
Expand All @@ -55,7 +55,7 @@ integration-dind: integration-dind-py2 integration-dind-py3
integration-dind-py2: build setup-network
docker rm -vf dpy-dind-py2 || :
docker run -d --network dpy-tests --name dpy-dind-py2 --privileged\
dockerswarm/dind:${TEST_ENGINE_VERSION} dockerd -H tcp://0.0.0.0:2375 --experimental
docker:${TEST_ENGINE_VERSION}-dind dockerd -H tcp://0.0.0.0:2375 --experimental
docker run -t --rm --env="DOCKER_HOST=tcp://dpy-dind-py2:2375" --env="DOCKER_TEST_API_VERSION=${TEST_API_VERSION}"\
--network dpy-tests docker-sdk-python py.test tests/integration
docker rm -vf dpy-dind-py2
Expand All @@ -64,7 +64,7 @@ integration-dind-py2: build setup-network
integration-dind-py3: build-py3 setup-network
docker rm -vf dpy-dind-py3 || :
docker run -d --network dpy-tests --name dpy-dind-py3 --privileged\
dockerswarm/dind:${TEST_ENGINE_VERSION} dockerd -H tcp://0.0.0.0:2375 --experimental
docker:${TEST_ENGINE_VERSION}-dind dockerd -H tcp://0.0.0.0:2375 --experimental
docker run -t --rm --env="DOCKER_HOST=tcp://dpy-dind-py3:2375" --env="DOCKER_TEST_API_VERSION=${TEST_API_VERSION}"\
--network dpy-tests docker-sdk-python3 py.test tests/integration
docker rm -vf dpy-dind-py3
Expand All @@ -76,7 +76,7 @@ integration-dind-ssl: build-dind-certs build build-py3
docker run -d --env="DOCKER_HOST=tcp://localhost:2375" --env="DOCKER_TLS_VERIFY=1"\
--env="DOCKER_CERT_PATH=/certs" --volumes-from dpy-dind-certs --name dpy-dind-ssl\
--network dpy-tests --network-alias docker -v /tmp --privileged\
dockerswarm/dind:${TEST_ENGINE_VERSION}\
docker:${TEST_ENGINE_VERSION}-dind\
dockerd --tlsverify --tlscacert=/certs/ca.pem --tlscert=/certs/server-cert.pem\
--tlskey=/certs/server-key.pem -H tcp://0.0.0.0:2375 --experimental
docker run -t --rm --volumes-from dpy-dind-ssl --env="DOCKER_HOST=tcp://docker:2375"\
Expand Down
16 changes: 7 additions & 9 deletions docker/context/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ class ContextAPI(object):
Contains methods for context management:
create, list, remove, get, inspect.
"""
DEFAULT_CONTEXT = Context("default")
DEFAULT_CONTEXT = Context("default", "swarm")

@classmethod
def create_context(
cls, name, orchestrator="swarm", host=None, tls_cfg=None,
cls, name, orchestrator=None, host=None, tls_cfg=None,
default_namespace=None, skip_tls_verify=False):
"""Creates a new context.
Returns:
Expand All @@ -38,9 +38,7 @@ def create_context(
>>> print(ctx.Metadata)
{
"Name": "test",
"Metadata": {
"StackOrchestrator": "swarm"
},
"Metadata": {},
"Endpoints": {
"docker": {
"Host": "unix:///var/run/docker.sock",
Expand All @@ -57,7 +55,9 @@ def create_context(
ctx = Context.load_context(name)
if ctx:
raise errors.ContextAlreadyExists(name)
endpoint = "docker" if orchestrator == "swarm" else orchestrator
endpoint = "docker"
if orchestrator and orchestrator != "swarm":
endpoint = orchestrator
ctx = Context(name, orchestrator)
ctx.set_endpoint(
endpoint, host, tls_cfg,
Expand All @@ -79,9 +79,7 @@ def get_context(cls, name=None):
>>> print(ctx.Metadata)
{
"Name": "test",
"Metadata": {
"StackOrchestrator": "swarm"
},
"Metadata": {},
"Endpoints": {
"docker": {
"Host": "unix:///var/run/docker.sock",
Expand Down
4 changes: 2 additions & 2 deletions docker/context/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ def get_tls_dir(name=None, endpoint=""):
return os.path.join(context_dir, "tls")


def get_context_host(path=None):
host = utils.parse_host(path, IS_WINDOWS_PLATFORM)
def get_context_host(path=None, tls=False):
host = utils.parse_host(path, IS_WINDOWS_PLATFORM, tls)
if host == DEFAULT_UNIX_SOCKET:
# remove http+ from default docker socket url
return host.strip("http+")
Expand Down
25 changes: 14 additions & 11 deletions docker/context/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,20 @@

class Context:
"""A context."""
def __init__(self, name, orchestrator="swarm", host=None, endpoints=None):
def __init__(self, name, orchestrator=None, host=None, endpoints=None,
tls=False):
if not name:
raise Exception("Name not provided")
self.name = name
self.orchestrator = orchestrator
if not endpoints:
default_endpoint = "docker" if (
orchestrator == "swarm"
not orchestrator or orchestrator == "swarm"
) else orchestrator
self.endpoints = {
default_endpoint: {
"Host": get_context_host(host),
"SkipTLSVerify": False
"Host": get_context_host(host, tls),
"SkipTLSVerify": not tls
}
}
else:
Expand All @@ -44,7 +45,7 @@ def set_endpoint(
self, name="docker", host=None, tls_cfg=None,
skip_tls_verify=False, def_namespace=None):
self.endpoints[name] = {
"Host": get_context_host(host),
"Host": get_context_host(host, not skip_tls_verify),
"SkipTLSVerify": skip_tls_verify
}
if def_namespace:
Expand Down Expand Up @@ -84,7 +85,8 @@ def _load_meta(cls, name):
context {} : {}""".format(name, e))

return (
metadata["Name"], metadata["Metadata"]["StackOrchestrator"],
metadata["Name"],
metadata["Metadata"].get("StackOrchestrator", None),
metadata["Endpoints"])
return None, None, None

Expand Down Expand Up @@ -161,7 +163,7 @@ def Name(self):

@property
def Host(self):
if self.orchestrator == "swarm":
if not self.orchestrator or self.orchestrator == "swarm":
return self.endpoints["docker"]["Host"]
return self.endpoints[self.orchestrator]["Host"]

Expand All @@ -171,18 +173,19 @@ def Orchestrator(self):

@property
def Metadata(self):
meta = {}
if self.orchestrator:
meta = {"StackOrchestrator": self.orchestrator}
return {
"Name": self.name,
"Metadata": {
"StackOrchestrator": self.orchestrator
},
"Metadata": meta,
"Endpoints": self.endpoints
}

@property
def TLSConfig(self):
key = self.orchestrator
if key == "swarm":
if not key or key == "swarm":
key = "docker"
if key in self.tls_cfg.keys():
return self.tls_cfg[key]
Expand Down
2 changes: 1 addition & 1 deletion docker/version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version = "4.2.0"
version = "4.2.1"
version_info = tuple([int(d) for d in version.split("-")[0].split(".")])
10 changes: 10 additions & 0 deletions docs/change-log.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
Change log
==========

4.2.1
-----

[List of PRs / issues for this release](https://github.com/docker/docker-py/milestone/65?closed=1)

### Features

- Add option on when to use `tls` on Context constructor
- Make context orchestrator field optional

4.2.0
-----

Expand Down
24 changes: 13 additions & 11 deletions tests/integration/api_container_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,11 +273,14 @@ def test_valid_log_driver_and_log_opt(self):

def test_invalid_log_driver_raises_exception(self):
log_config = docker.types.LogConfig(
type='asdf-nope',
type='asdf',
config={}
)

expected_msg = "logger: no log driver named 'asdf-nope' is registered"
expected_msgs = [
"logger: no log driver named 'asdf' is registered",
"looking up logging plugin asdf: plugin \"asdf\" not found",
]
with pytest.raises(docker.errors.APIError) as excinfo:
# raises an internal server error 500
container = self.client.create_container(
Expand All @@ -287,7 +290,7 @@ def test_invalid_log_driver_raises_exception(self):
)
self.client.start(container)

assert excinfo.value.explanation == expected_msg
assert excinfo.value.explanation in expected_msgs

def test_valid_no_log_driver_specified(self):
log_config = docker.types.LogConfig(
Expand Down Expand Up @@ -1102,6 +1105,8 @@ def test_port(self):


class ContainerTopTest(BaseAPIIntegrationTest):
@pytest.mark.xfail(reason='Output of docker top depends on host distro, '
'and is not formalized.')
def test_top(self):
container = self.client.create_container(
TEST_IMG, ['sleep', '60']
Expand All @@ -1112,28 +1117,25 @@ def test_top(self):
self.client.start(container)
res = self.client.top(container)
if not IS_WINDOWS_PLATFORM:
assert res['Titles'] == [
'UID', 'PID', 'PPID', 'C', 'STIME', 'TTY', 'TIME', 'CMD'
]
assert res['Titles'] == [u'PID', u'USER', u'TIME', u'COMMAND']
assert len(res['Processes']) == 1
assert res['Processes'][0][-1] == 'sleep 60'
self.client.kill(container)

@pytest.mark.skipif(
IS_WINDOWS_PLATFORM, reason='No psargs support on windows'
)
@pytest.mark.xfail(reason='Output of docker top depends on host distro, '
'and is not formalized.')
def test_top_with_psargs(self):
container = self.client.create_container(
TEST_IMG, ['sleep', '60'])

self.tmp_containers.append(container)

self.client.start(container)
res = self.client.top(container, 'waux')
assert res['Titles'] == [
'USER', 'PID', '%CPU', '%MEM', 'VSZ', 'RSS',
'TTY', 'STAT', 'START', 'TIME', 'COMMAND'
]
res = self.client.top(container, '-eopid,user')
assert res['Titles'] == [u'PID', u'USER']
assert len(res['Processes']) == 1
assert res['Processes'][0][10] == 'sleep 60'

Expand Down
7 changes: 7 additions & 0 deletions tests/integration/context_api_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,10 @@ def test_context_remove(self):
ContextAPI.remove_context("test")
with pytest.raises(errors.ContextNotFound):
ContextAPI.inspect_context("test")

def test_load_context_without_orchestrator(self):
ContextAPI.create_context("test")
ctx = ContextAPI.get_context("test")
assert ctx
assert ctx.Name == "test"
assert ctx.Orchestrator is None
4 changes: 4 additions & 0 deletions tests/unit/context_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ def test_default_in_context_list(self):
def test_get_current_context(self):
assert ContextAPI.get_current_context().Name == "default"

def test_https_host(self):
c = Context("test", host="tcp://testdomain:8080", tls=True)
assert c.Host == "https://testdomain:8080"

def test_context_inspect_without_params(self):
ctx = ContextAPI.inspect_context()
assert ctx["Name"] == "default"
Expand Down

0 comments on commit b22095f

Please sign in to comment.