mirror of https://github.com/docker/docker-py.git
Replace `network_config` with a dict of EndpointConfig
- Renamed parameter from `network_config` to `networking_config` to be more semantically correct with the rest of the API.
This commit is contained in:
parent
0318ad8e7e
commit
7752996f78
|
|
@ -2,16 +2,16 @@ import copy
|
|||
import ntpath
|
||||
from collections import namedtuple
|
||||
|
||||
from .images import Image
|
||||
from .resource import Collection, Model
|
||||
from ..api import APIClient
|
||||
from ..constants import DEFAULT_DATA_CHUNK_SIZE
|
||||
from ..errors import (
|
||||
ContainerError, DockerException, ImageNotFound,
|
||||
NotFound, create_unexpected_kwargs_error
|
||||
)
|
||||
from ..types import EndpointConfig, HostConfig, NetworkingConfig
|
||||
from ..types import HostConfig, NetworkingConfig
|
||||
from ..utils import version_gte
|
||||
from .images import Image
|
||||
from .resource import Collection, Model
|
||||
|
||||
|
||||
class Container(Model):
|
||||
|
|
@ -21,6 +21,7 @@ class Container(Model):
|
|||
query the Docker daemon for the current properties, causing
|
||||
:py:attr:`attrs` to be refreshed.
|
||||
"""
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""
|
||||
|
|
@ -680,33 +681,13 @@ class ContainerCollection(Collection):
|
|||
This mode is incompatible with ``ports``.
|
||||
|
||||
Incompatible with ``network``.
|
||||
network_config (dict): A dictionary containing options that are
|
||||
passed to the network driver during the connection.
|
||||
networking_config (Dict[str, EndpointConfig]):
|
||||
Dictionary of EndpointConfig objects for each container network.
|
||||
The key is the name of the network.
|
||||
Defaults to ``None``.
|
||||
The dictionary contains the following keys:
|
||||
|
||||
- ``aliases`` (:py:class:`list`): A list of aliases for
|
||||
the network endpoint.
|
||||
Names in that list can be used within the network to
|
||||
reach this container. Defaults to ``None``.
|
||||
- ``links`` (:py:class:`list`): A list of links for
|
||||
the network endpoint endpoint.
|
||||
Containers declared in this list will be linked to this
|
||||
container. Defaults to ``None``.
|
||||
- ``ipv4_address`` (str): The IP address to assign to
|
||||
this container on the network, using the IPv4 protocol.
|
||||
Defaults to ``None``.
|
||||
- ``ipv6_address`` (str): The IP address to assign to
|
||||
this container on the network, using the IPv6 protocol.
|
||||
Defaults to ``None``.
|
||||
- ``link_local_ips`` (:py:class:`list`): A list of link-local
|
||||
(IPv4/IPv6) addresses.
|
||||
- ``driver_opt`` (dict): A dictionary of options to provide to
|
||||
the network driver. Defaults to ``None``.
|
||||
- ``mac_address`` (str): MAC Address to assign to the network
|
||||
interface. Defaults to ``None``. Requires API >= 1.25.
|
||||
|
||||
Used in conjuction with ``network``.
|
||||
|
||||
Incompatible with ``network_mode``.
|
||||
oom_kill_disable (bool): Whether to disable OOM killer.
|
||||
oom_score_adj (int): An integer value containing the score given
|
||||
|
|
@ -872,9 +853,9 @@ class ContainerCollection(Collection):
|
|||
'together.'
|
||||
)
|
||||
|
||||
if kwargs.get('network_config') and not kwargs.get('network'):
|
||||
if kwargs.get('networking_config') and not kwargs.get('network'):
|
||||
raise RuntimeError(
|
||||
'The option "network_config" can not be used '
|
||||
'The option "networking_config" can not be used '
|
||||
'without "network".'
|
||||
)
|
||||
|
||||
|
|
@ -1030,6 +1011,7 @@ class ContainerCollection(Collection):
|
|||
|
||||
def prune(self, filters=None):
|
||||
return self.client.api.prune_containers(filters=filters)
|
||||
|
||||
prune.__doc__ = APIClient.prune_containers.__doc__
|
||||
|
||||
|
||||
|
|
@ -1124,17 +1106,6 @@ RUN_HOST_CONFIG_KWARGS = [
|
|||
]
|
||||
|
||||
|
||||
NETWORKING_CONFIG_ARGS = [
|
||||
'aliases',
|
||||
'links',
|
||||
'ipv4_address',
|
||||
'ipv6_address',
|
||||
'link_local_ips',
|
||||
'driver_opt',
|
||||
'mac_address'
|
||||
]
|
||||
|
||||
|
||||
def _create_container_args(kwargs):
|
||||
"""
|
||||
Convert arguments to create() to arguments to create_container().
|
||||
|
|
@ -1159,24 +1130,17 @@ def _create_container_args(kwargs):
|
|||
host_config_kwargs['binds'] = volumes
|
||||
|
||||
network = kwargs.pop('network', None)
|
||||
network_config = kwargs.pop('network_config', None)
|
||||
networking_config = kwargs.pop('networking_config', None)
|
||||
if network:
|
||||
endpoint_config = None
|
||||
|
||||
if network_config:
|
||||
clean_endpoint_args = {}
|
||||
for arg_name in NETWORKING_CONFIG_ARGS:
|
||||
if arg_name in network_config:
|
||||
clean_endpoint_args[arg_name] = network_config[arg_name]
|
||||
|
||||
if clean_endpoint_args:
|
||||
endpoint_config = EndpointConfig(
|
||||
host_config_kwargs['version'], **clean_endpoint_args
|
||||
)
|
||||
if networking_config:
|
||||
# Sanity check: check if the network is defined in the
|
||||
# networking config dict, otherwise switch to None
|
||||
if network not in networking_config:
|
||||
networking_config = None
|
||||
|
||||
create_kwargs['networking_config'] = NetworkingConfig(
|
||||
{network: endpoint_config}
|
||||
) if endpoint_config else {network: None}
|
||||
networking_config
|
||||
) if networking_config else {network: None}
|
||||
host_config_kwargs['network_mode'] = network
|
||||
|
||||
# All kwargs should have been consumed by this point, so raise
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ import threading
|
|||
import pytest
|
||||
|
||||
import docker
|
||||
from ..helpers import random_name
|
||||
from ..helpers import requires_api_version
|
||||
from .base import BaseIntegrationTest
|
||||
from .base import TEST_API_VERSION
|
||||
from ..helpers import random_name
|
||||
from ..helpers import requires_api_version
|
||||
|
||||
|
||||
class ContainerCollectionTest(BaseIntegrationTest):
|
||||
|
|
@ -104,7 +104,7 @@ class ContainerCollectionTest(BaseIntegrationTest):
|
|||
assert 'Networks' in attrs['NetworkSettings']
|
||||
assert list(attrs['NetworkSettings']['Networks'].keys()) == [net_name]
|
||||
|
||||
def test_run_with_network_config(self):
|
||||
def test_run_with_networking_config(self):
|
||||
net_name = random_name()
|
||||
client = docker.from_env(version=TEST_API_VERSION)
|
||||
client.networks.create(net_name)
|
||||
|
|
@ -113,10 +113,16 @@ class ContainerCollectionTest(BaseIntegrationTest):
|
|||
test_aliases = ['hello']
|
||||
test_driver_opt = {'key1': 'a'}
|
||||
|
||||
networking_config = {
|
||||
net_name: client.api.create_endpoint_config(
|
||||
aliases=test_aliases,
|
||||
driver_opt=test_driver_opt
|
||||
)
|
||||
}
|
||||
|
||||
container = client.containers.run(
|
||||
'alpine', 'echo hello world', network=net_name,
|
||||
network_config={'aliases': test_aliases,
|
||||
'driver_opt': test_driver_opt},
|
||||
networking_config=networking_config,
|
||||
detach=True
|
||||
)
|
||||
self.tmp_containers.append(container.id)
|
||||
|
|
@ -131,7 +137,7 @@ class ContainerCollectionTest(BaseIntegrationTest):
|
|||
assert attrs['NetworkSettings']['Networks'][net_name]['DriverOpts'] \
|
||||
== test_driver_opt
|
||||
|
||||
def test_run_with_network_config_undeclared_params(self):
|
||||
def test_run_with_networking_config_with_undeclared_network(self):
|
||||
net_name = random_name()
|
||||
client = docker.from_env(version=TEST_API_VERSION)
|
||||
client.networks.create(net_name)
|
||||
|
|
@ -140,11 +146,41 @@ class ContainerCollectionTest(BaseIntegrationTest):
|
|||
test_aliases = ['hello']
|
||||
test_driver_opt = {'key1': 'a'}
|
||||
|
||||
networking_config = {
|
||||
net_name: client.api.create_endpoint_config(
|
||||
aliases=test_aliases,
|
||||
driver_opt=test_driver_opt
|
||||
),
|
||||
'bar': client.api.create_endpoint_config(
|
||||
aliases=['test'],
|
||||
driver_opt={'key2': 'b'}
|
||||
),
|
||||
}
|
||||
|
||||
with pytest.raises(docker.errors.APIError) as e:
|
||||
container = client.containers.run(
|
||||
'alpine', 'echo hello world', network=net_name,
|
||||
network_config={'aliases': test_aliases,
|
||||
'driver_opt': test_driver_opt,
|
||||
'undeclared_param': 'random_value'},
|
||||
networking_config=networking_config,
|
||||
detach=True
|
||||
)
|
||||
self.tmp_containers.append(container.id)
|
||||
|
||||
def test_run_with_networking_config_only_undeclared_network(self):
|
||||
net_name = random_name()
|
||||
client = docker.from_env(version=TEST_API_VERSION)
|
||||
client.networks.create(net_name)
|
||||
self.tmp_networks.append(net_name)
|
||||
|
||||
networking_config = {
|
||||
'bar': client.api.create_endpoint_config(
|
||||
aliases=['hello'],
|
||||
driver_opt={'key1': 'a'}
|
||||
),
|
||||
}
|
||||
|
||||
container = client.containers.run(
|
||||
'alpine', 'echo hello world', network=net_name,
|
||||
networking_config=networking_config,
|
||||
detach=True
|
||||
)
|
||||
self.tmp_containers.append(container.id)
|
||||
|
|
@ -154,12 +190,9 @@ class ContainerCollectionTest(BaseIntegrationTest):
|
|||
assert 'NetworkSettings' in attrs
|
||||
assert 'Networks' in attrs['NetworkSettings']
|
||||
assert list(attrs['NetworkSettings']['Networks'].keys()) == [net_name]
|
||||
assert attrs['NetworkSettings']['Networks'][net_name]['Aliases'] == \
|
||||
test_aliases
|
||||
assert attrs['NetworkSettings']['Networks'][net_name]['DriverOpts'] \
|
||||
== test_driver_opt
|
||||
assert 'undeclared_param' not in \
|
||||
attrs['NetworkSettings']['Networks'][net_name]
|
||||
assert attrs['NetworkSettings']['Networks'][net_name]['Aliases'] is None
|
||||
assert (attrs['NetworkSettings']['Networks'][net_name]['DriverOpts']
|
||||
is None)
|
||||
|
||||
def test_run_with_none_driver(self):
|
||||
client = docker.from_env(version=TEST_API_VERSION)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import pytest
|
||||
import unittest
|
||||
|
||||
import pytest
|
||||
|
||||
import docker
|
||||
from docker.constants import DEFAULT_DATA_CHUNK_SIZE, \
|
||||
DEFAULT_DOCKER_API_VERSION
|
||||
from docker.models.containers import Container, _create_container_args
|
||||
from docker.models.images import Image
|
||||
from docker.types import EndpointConfig
|
||||
from .fake_api import FAKE_CONTAINER_ID, FAKE_IMAGE_ID, FAKE_EXEC_ID
|
||||
from .fake_api_client import make_fake_client
|
||||
|
||||
|
|
@ -32,6 +34,13 @@ class ContainerCollectionTest(unittest.TestCase):
|
|||
)
|
||||
|
||||
def test_create_container_args(self):
|
||||
networking_config = {
|
||||
'foo': EndpointConfig(
|
||||
DEFAULT_DOCKER_API_VERSION, aliases=['test'],
|
||||
driver_opt={'key1': 'a'}
|
||||
)
|
||||
}
|
||||
|
||||
create_kwargs = _create_container_args(dict(
|
||||
image='alpine',
|
||||
command='echo hello world',
|
||||
|
|
@ -75,7 +84,7 @@ class ContainerCollectionTest(unittest.TestCase):
|
|||
name='somename',
|
||||
network_disabled=False,
|
||||
network='foo',
|
||||
network_config={'aliases': ['test'], 'driver_opt': {'key1': 'a'}},
|
||||
networking_config=networking_config,
|
||||
oom_kill_disable=True,
|
||||
oom_score_adj=5,
|
||||
pid_mode='host',
|
||||
|
|
@ -349,35 +358,41 @@ class ContainerCollectionTest(unittest.TestCase):
|
|||
host_config={'NetworkMode': 'default'},
|
||||
)
|
||||
|
||||
def test_run_network_config_without_network(self):
|
||||
def test_run_networking_config_without_network(self):
|
||||
client = make_fake_client()
|
||||
|
||||
with pytest.raises(RuntimeError):
|
||||
client.containers.run(
|
||||
image='alpine',
|
||||
network_config={'aliases': ['test'],
|
||||
networking_config={'aliases': ['test'],
|
||||
'driver_opt': {'key1': 'a'}}
|
||||
)
|
||||
|
||||
def test_run_network_config_with_network_mode(self):
|
||||
def test_run_networking_config_with_network_mode(self):
|
||||
client = make_fake_client()
|
||||
|
||||
with pytest.raises(RuntimeError):
|
||||
client.containers.run(
|
||||
image='alpine',
|
||||
network_mode='none',
|
||||
network_config={'aliases': ['test'],
|
||||
networking_config={'aliases': ['test'],
|
||||
'driver_opt': {'key1': 'a'}}
|
||||
)
|
||||
|
||||
def test_run_network_config(self):
|
||||
def test_run_networking_config(self):
|
||||
client = make_fake_client()
|
||||
|
||||
networking_config = {
|
||||
'foo': EndpointConfig(
|
||||
DEFAULT_DOCKER_API_VERSION, aliases=['test'],
|
||||
driver_opt={'key1': 'a'}
|
||||
)
|
||||
}
|
||||
|
||||
client.containers.run(
|
||||
image='alpine',
|
||||
network='foo',
|
||||
network_config={'aliases': ['test'],
|
||||
'driver_opt': {'key1': 'a'}}
|
||||
networking_config=networking_config
|
||||
)
|
||||
|
||||
client.api.create_container.assert_called_with(
|
||||
|
|
@ -390,15 +405,24 @@ class ContainerCollectionTest(unittest.TestCase):
|
|||
host_config={'NetworkMode': 'foo'}
|
||||
)
|
||||
|
||||
def test_run_network_config_undeclared_params(self):
|
||||
def test_run_networking_config_with_undeclared_network(self):
|
||||
client = make_fake_client()
|
||||
|
||||
networking_config = {
|
||||
'foo': EndpointConfig(
|
||||
DEFAULT_DOCKER_API_VERSION, aliases=['test_foo'],
|
||||
driver_opt={'key2': 'b'}
|
||||
),
|
||||
'bar': EndpointConfig(
|
||||
DEFAULT_DOCKER_API_VERSION, aliases=['test'],
|
||||
driver_opt={'key1': 'a'}
|
||||
)
|
||||
}
|
||||
|
||||
client.containers.run(
|
||||
image='alpine',
|
||||
network='foo',
|
||||
network_config={'aliases': ['test'],
|
||||
'driver_opt': {'key1': 'a'},
|
||||
'undeclared_param': 'random_value'}
|
||||
networking_config=networking_config
|
||||
)
|
||||
|
||||
client.api.create_container.assert_called_with(
|
||||
|
|
@ -406,18 +430,26 @@ class ContainerCollectionTest(unittest.TestCase):
|
|||
image='alpine',
|
||||
command=None,
|
||||
networking_config={'EndpointsConfig': {
|
||||
'foo': {'Aliases': ['test'], 'DriverOpts': {'key1': 'a'}}}
|
||||
},
|
||||
'foo': {'Aliases': ['test_foo'], 'DriverOpts': {'key2': 'b'}},
|
||||
'bar': {'Aliases': ['test'], 'DriverOpts': {'key1': 'a'}},
|
||||
}},
|
||||
host_config={'NetworkMode': 'foo'}
|
||||
)
|
||||
|
||||
def test_run_network_config_only_undeclared_params(self):
|
||||
def test_run_networking_config_only_undeclared_network(self):
|
||||
client = make_fake_client()
|
||||
|
||||
networking_config = {
|
||||
'bar': EndpointConfig(
|
||||
DEFAULT_DOCKER_API_VERSION, aliases=['test'],
|
||||
driver_opt={'key1': 'a'}
|
||||
)
|
||||
}
|
||||
|
||||
client.containers.run(
|
||||
image='alpine',
|
||||
network='foo',
|
||||
network_config={'undeclared_param': 'random_value'}
|
||||
networking_config=networking_config
|
||||
)
|
||||
|
||||
client.api.create_container.assert_called_with(
|
||||
|
|
@ -455,12 +487,12 @@ class ContainerCollectionTest(unittest.TestCase):
|
|||
host_config={'NetworkMode': 'default'}
|
||||
)
|
||||
|
||||
def test_create_network_config_without_network(self):
|
||||
def test_create_networking_config_without_network(self):
|
||||
client = make_fake_client()
|
||||
|
||||
client.containers.create(
|
||||
image='alpine',
|
||||
network_config={'aliases': ['test'],
|
||||
networking_config={'aliases': ['test'],
|
||||
'driver_opt': {'key1': 'a'}}
|
||||
)
|
||||
|
||||
|
|
@ -470,13 +502,13 @@ class ContainerCollectionTest(unittest.TestCase):
|
|||
host_config={'NetworkMode': 'default'}
|
||||
)
|
||||
|
||||
def test_create_network_config_with_network_mode(self):
|
||||
def test_create_networking_config_with_network_mode(self):
|
||||
client = make_fake_client()
|
||||
|
||||
client.containers.create(
|
||||
image='alpine',
|
||||
network_mode='none',
|
||||
network_config={'aliases': ['test'],
|
||||
networking_config={'aliases': ['test'],
|
||||
'driver_opt': {'key1': 'a'}}
|
||||
)
|
||||
|
||||
|
|
@ -486,14 +518,20 @@ class ContainerCollectionTest(unittest.TestCase):
|
|||
host_config={'NetworkMode': 'none'}
|
||||
)
|
||||
|
||||
def test_create_network_config(self):
|
||||
def test_create_networking_config(self):
|
||||
client = make_fake_client()
|
||||
|
||||
networking_config = {
|
||||
'foo': EndpointConfig(
|
||||
DEFAULT_DOCKER_API_VERSION, aliases=['test'],
|
||||
driver_opt={'key1': 'a'}
|
||||
)
|
||||
}
|
||||
|
||||
client.containers.create(
|
||||
image='alpine',
|
||||
network='foo',
|
||||
network_config={'aliases': ['test'],
|
||||
'driver_opt': {'key1': 'a'}}
|
||||
networking_config=networking_config
|
||||
)
|
||||
|
||||
client.api.create_container.assert_called_with(
|
||||
|
|
@ -505,33 +543,50 @@ class ContainerCollectionTest(unittest.TestCase):
|
|||
host_config={'NetworkMode': 'foo'}
|
||||
)
|
||||
|
||||
def test_create_network_config_undeclared_params(self):
|
||||
def test_create_networking_config_with_undeclared_network(self):
|
||||
client = make_fake_client()
|
||||
|
||||
networking_config = {
|
||||
'foo': EndpointConfig(
|
||||
DEFAULT_DOCKER_API_VERSION, aliases=['test_foo'],
|
||||
driver_opt={'key2': 'b'}
|
||||
),
|
||||
'bar': EndpointConfig(
|
||||
DEFAULT_DOCKER_API_VERSION, aliases=['test'],
|
||||
driver_opt={'key1': 'a'}
|
||||
)
|
||||
}
|
||||
|
||||
client.containers.create(
|
||||
image='alpine',
|
||||
network='foo',
|
||||
network_config={'aliases': ['test'],
|
||||
'driver_opt': {'key1': 'a'},
|
||||
'undeclared_param': 'random_value'}
|
||||
networking_config=networking_config
|
||||
)
|
||||
|
||||
client.api.create_container.assert_called_with(
|
||||
image='alpine',
|
||||
command=None,
|
||||
networking_config={'EndpointsConfig': {
|
||||
'foo': {'Aliases': ['test'], 'DriverOpts': {'key1': 'a'}}}
|
||||
},
|
||||
'foo': {'Aliases': ['test_foo'], 'DriverOpts': {'key2': 'b'}},
|
||||
'bar': {'Aliases': ['test'], 'DriverOpts': {'key1': 'a'}},
|
||||
}},
|
||||
host_config={'NetworkMode': 'foo'}
|
||||
)
|
||||
|
||||
def test_create_network_config_only_undeclared_params(self):
|
||||
def test_create_networking_config_only_undeclared_network(self):
|
||||
client = make_fake_client()
|
||||
|
||||
networking_config = {
|
||||
'bar': EndpointConfig(
|
||||
DEFAULT_DOCKER_API_VERSION, aliases=['test'],
|
||||
driver_opt={'key1': 'a'}
|
||||
)
|
||||
}
|
||||
|
||||
client.containers.create(
|
||||
image='alpine',
|
||||
network='foo',
|
||||
network_config={'undeclared_param': 'random_value'}
|
||||
networking_config=networking_config
|
||||
)
|
||||
|
||||
client.api.create_container.assert_called_with(
|
||||
|
|
|
|||
Loading…
Reference in New Issue