From fd4526a7d34a08d55532dac34d0e94804176de10 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 17 Feb 2020 10:19:56 +0100 Subject: [PATCH 1/9] xfail "docker top" tests, and adjust for alpine image Signed-off-by: Sebastiaan van Stijn --- tests/integration/api_container_test.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/integration/api_container_test.py b/tests/integration/api_container_test.py index 1ba3eaa5..c503a367 100644 --- a/tests/integration/api_container_test.py +++ b/tests/integration/api_container_test.py @@ -1102,6 +1102,8 @@ class PortTest(BaseAPIIntegrationTest): 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'] @@ -1112,9 +1114,7 @@ class ContainerTopTest(BaseAPIIntegrationTest): 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) @@ -1122,6 +1122,8 @@ class ContainerTopTest(BaseAPIIntegrationTest): @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']) @@ -1129,11 +1131,8 @@ class ContainerTopTest(BaseAPIIntegrationTest): 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' From db6a2471f527c69b33840ed1121114dd526a0134 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sat, 15 Feb 2020 00:13:16 +0100 Subject: [PATCH 2/9] Use official docker:dind image instead of custom image This replaces the custom dockerswarm/dind image with the official dind images, which should provide the same functionality. Signed-off-by: Sebastiaan van Stijn --- Jenkinsfile | 2 +- Makefile | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 7af23e9c..28511b22 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -84,7 +84,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} \\ diff --git a/Makefile b/Makefile index db103f5b..f456283f 100644 --- a/Makefile +++ b/Makefile @@ -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 @@ -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 @@ -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"\ From 9713227d7bca2ae37357a500a4e80e6bab152b16 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 14 Feb 2020 23:51:44 +0100 Subject: [PATCH 3/9] Jenkinsfile: remove obsolete engine versions Signed-off-by: Sebastiaan van Stijn --- Jenkinsfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 28511b22..f905325c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -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 \\ @@ -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' ] From 913d129dc9e5cb84bfe385a1b58badfae48e1344 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 14 Feb 2020 23:54:20 +0100 Subject: [PATCH 4/9] Update test engine version to 19.03.5 Signed-off-by: Sebastiaan van Stijn --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f456283f..551868ec 100644 --- a/Makefile +++ b/Makefile @@ -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: From 9b59e4911309dc1e9ff9017f2adad8bad8060e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wilson=20J=C3=BAnior?= Date: Fri, 17 Apr 2020 09:37:34 -0300 Subject: [PATCH 5/9] Fix tests to support both log plugin feedbacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Wilson Júnior Docker-DCO-1.1-Signed-off-by: Wilson Júnior (github: wpjunior) --- tests/integration/api_container_test.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/integration/api_container_test.py b/tests/integration/api_container_test.py index c503a367..411d4c2e 100644 --- a/tests/integration/api_container_test.py +++ b/tests/integration/api_container_test.py @@ -273,11 +273,14 @@ class CreateContainerTest(BaseAPIIntegrationTest): 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( @@ -287,7 +290,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): ) 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( From 105efa02a9016646998400efe3cb4f0c7dcce16b Mon Sep 17 00:00:00 2001 From: Ulysses Souza Date: Thu, 28 May 2020 20:53:45 +0200 Subject: [PATCH 6/9] Specify when to use `tls` on Context constructor Signed-off-by: Ulysses Souza --- docker/context/config.py | 4 ++-- docker/context/context.py | 9 +++++---- tests/unit/context_test.py | 4 ++++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/docker/context/config.py b/docker/context/config.py index ac9a342e..baf54f79 100644 --- a/docker/context/config.py +++ b/docker/context/config.py @@ -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+") diff --git a/docker/context/context.py b/docker/context/context.py index 4a0549ca..fdc290a0 100644 --- a/docker/context/context.py +++ b/docker/context/context.py @@ -11,7 +11,8 @@ from docker.context.config import get_context_host class Context: """A context.""" - def __init__(self, name, orchestrator="swarm", host=None, endpoints=None): + def __init__(self, name, orchestrator="swarm", host=None, endpoints=None, + tls=False): if not name: raise Exception("Name not provided") self.name = name @@ -22,8 +23,8 @@ class Context: ) else orchestrator self.endpoints = { default_endpoint: { - "Host": get_context_host(host), - "SkipTLSVerify": False + "Host": get_context_host(host, tls), + "SkipTLSVerify": not tls } } else: @@ -44,7 +45,7 @@ class Context: 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: diff --git a/tests/unit/context_test.py b/tests/unit/context_test.py index 5e88c691..6d6d6726 100644 --- a/tests/unit/context_test.py +++ b/tests/unit/context_test.py @@ -37,6 +37,10 @@ class BaseContextTest(unittest.TestCase): 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" From 31276df6a31511f5d1654b98112f2ea02dea4a91 Mon Sep 17 00:00:00 2001 From: aiordache Date: Sat, 30 May 2020 11:01:22 +0200 Subject: [PATCH 7/9] Make orchestrator field optional Signed-off-by: aiordache --- docker/context/api.py | 16 +++++++--------- docker/context/context.py | 18 ++++++++++-------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docker/context/api.py b/docker/context/api.py index fc7e8940..c45115bc 100644 --- a/docker/context/api.py +++ b/docker/context/api.py @@ -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: @@ -38,9 +38,7 @@ class ContextAPI(object): >>> print(ctx.Metadata) { "Name": "test", - "Metadata": { - "StackOrchestrator": "swarm" - }, + "Metadata": {}, "Endpoints": { "docker": { "Host": "unix:///var/run/docker.sock", @@ -57,7 +55,9 @@ class ContextAPI(object): 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, @@ -79,9 +79,7 @@ class ContextAPI(object): >>> print(ctx.Metadata) { "Name": "test", - "Metadata": { - "StackOrchestrator": "swarm" - }, + "Metadata": {}, "Endpoints": { "docker": { "Host": "unix:///var/run/docker.sock", diff --git a/docker/context/context.py b/docker/context/context.py index fdc290a0..b2af20c6 100644 --- a/docker/context/context.py +++ b/docker/context/context.py @@ -11,7 +11,7 @@ from docker.context.config import get_context_host 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") @@ -19,7 +19,7 @@ class Context: self.orchestrator = orchestrator if not endpoints: default_endpoint = "docker" if ( - orchestrator == "swarm" + not orchestrator or orchestrator == "swarm" ) else orchestrator self.endpoints = { default_endpoint: { @@ -85,7 +85,8 @@ class Context: context {} : {}""".format(name, e)) return ( - metadata["Name"], metadata["Metadata"]["StackOrchestrator"], + metadata["Name"], + metadata["Metadata"].get("StackOrchestrator", None), metadata["Endpoints"]) return None, None, None @@ -162,7 +163,7 @@ class Context: @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"] @@ -172,18 +173,19 @@ class Context: @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] From 67cad6842ceb9a49fbff70faa8dbff8b7ef20134 Mon Sep 17 00:00:00 2001 From: aiordache Date: Tue, 2 Jun 2020 10:45:52 +0200 Subject: [PATCH 8/9] add test for context load without orchestrator Signed-off-by: aiordache --- tests/integration/context_api_test.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/integration/context_api_test.py b/tests/integration/context_api_test.py index 60235ee7..a2a12a5c 100644 --- a/tests/integration/context_api_test.py +++ b/tests/integration/context_api_test.py @@ -50,3 +50,10 @@ class ContextLifecycleTest(BaseAPIIntegrationTest): 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 From 9923746095d9fd9a8fabf4a8ce5e895ad5a3e48c Mon Sep 17 00:00:00 2001 From: Ulysses Souza Date: Tue, 2 Jun 2020 15:47:10 +0200 Subject: [PATCH 9/9] Bump 4.2.1 Signed-off-by: Ulysses Souza --- docker/version.py | 2 +- docs/change-log.md | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docker/version.py b/docker/version.py index f0a31709..d69fbd0d 100644 --- a/docker/version.py +++ b/docker/version.py @@ -1,2 +1,2 @@ -version = "4.2.0" +version = "4.2.1" version_info = tuple([int(d) for d in version.split("-")[0].split(".")]) diff --git a/docs/change-log.md b/docs/change-log.md index 2f0a9ed6..4a37b594 100644 --- a/docs/change-log.md +++ b/docs/change-log.md @@ -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 -----