mirror of https://github.com/docker/docker-py.git
commit
b22095f742
|
|
@ -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'
|
||||
]
|
||||
|
|
@ -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} \\
|
||||
|
|
|
|||
8
Makefile
8
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:
|
||||
|
|
@ -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"\
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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+")
|
||||
|
|
|
|||
|
|
@ -11,19 +11,20 @@ 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")
|
||||
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:
|
||||
|
|
@ -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:
|
||||
|
|
@ -84,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
|
||||
|
||||
|
|
@ -161,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"]
|
||||
|
||||
|
|
@ -171,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]
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
version = "4.2.0"
|
||||
version = "4.2.1"
|
||||
version_info = tuple([int(d) for d in version.split("-")[0].split(".")])
|
||||
|
|
|
|||
|
|
@ -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
|
||||
-----
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
@ -1102,6 +1105,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 +1117,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 +1125,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 +1134,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'
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue