From ee9151f33611f693958a29c38ab0fbf5b6741c1b Mon Sep 17 00:00:00 2001 From: Mariano Scazzariello Date: Fri, 27 Jan 2023 15:26:21 +0100 Subject: client: add `network_driver_opt` to container run and create (#3083) Signed-off-by: Mariano Scazzariello --- docker/models/containers.py | 16 ++++++- tests/unit/models_containers_test.py | 84 +++++++++++++++++++++++++++++++++++- 2 files changed, 98 insertions(+), 2 deletions(-) diff --git a/docker/models/containers.py b/docker/models/containers.py index 6661b21..f1f6e44 100644 --- a/docker/models/containers.py +++ b/docker/models/containers.py @@ -678,6 +678,10 @@ class ContainerCollection(Collection): This mode is incompatible with ``ports``. Incompatible with ``network``. + network_driver_opt (dict): A dictionary of options to provide + to the network driver. Defaults to ``None``. 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 to the container in order to tune OOM killer preferences. @@ -842,6 +846,12 @@ class ContainerCollection(Collection): 'together.' ) + if kwargs.get('network_driver_opt') and not kwargs.get('network'): + raise RuntimeError( + 'The options "network_driver_opt" can not be used ' + 'without "network".' + ) + try: container = self.create(image=image, command=command, detach=detach, **kwargs) @@ -1112,8 +1122,12 @@ def _create_container_args(kwargs): host_config_kwargs['binds'] = volumes network = kwargs.pop('network', None) + network_driver_opt = kwargs.pop('network_driver_opt', None) if network: - create_kwargs['networking_config'] = {network: None} + network_configuration = {'driver_opt': network_driver_opt} \ + if network_driver_opt else None + + create_kwargs['networking_config'] = {network: network_configuration} host_config_kwargs['network_mode'] = network # All kwargs should have been consumed by this point, so raise diff --git a/tests/unit/models_containers_test.py b/tests/unit/models_containers_test.py index 101708e..d2a7ea5 100644 --- a/tests/unit/models_containers_test.py +++ b/tests/unit/models_containers_test.py @@ -74,6 +74,7 @@ class ContainerCollectionTest(unittest.TestCase): name='somename', network_disabled=False, network='foo', + network_driver_opt={'key1': 'a'}, oom_kill_disable=True, oom_score_adj=5, pid_mode='host', @@ -188,7 +189,7 @@ class ContainerCollectionTest(unittest.TestCase): mac_address='abc123', name='somename', network_disabled=False, - networking_config={'foo': None}, + networking_config={'foo': {'driver_opt': {'key1': 'a'}}}, platform='linux', ports=[('1111', 'tcp'), ('2222', 'tcp')], stdin_open=True, @@ -345,6 +346,42 @@ class ContainerCollectionTest(unittest.TestCase): host_config={'NetworkMode': 'default'}, ) + def test_run_network_driver_opts_without_network(self): + client = make_fake_client() + + with pytest.raises(RuntimeError): + client.containers.run( + image='alpine', + network_driver_opt={'key1': 'a'} + ) + + def test_run_network_driver_opts_with_network_mode(self): + client = make_fake_client() + + with pytest.raises(RuntimeError): + client.containers.run( + image='alpine', + network_mode='none', + network_driver_opt={'key1': 'a'} + ) + + def test_run_network_driver_opts(self): + client = make_fake_client() + + client.containers.run( + image='alpine', + network='foo', + network_driver_opt={'key1': 'a'} + ) + + client.api.create_container.assert_called_with( + detach=False, + image='alpine', + command=None, + networking_config={'foo': {'driver_opt': {'key1': 'a'}}}, + host_config={'NetworkMode': 'foo'} + ) + def test_create(self): client = make_fake_client() container = client.containers.create( @@ -372,6 +409,51 @@ class ContainerCollectionTest(unittest.TestCase): host_config={'NetworkMode': 'default'} ) + def test_create_network_driver_opts_without_network(self): + client = make_fake_client() + + client.containers.create( + image='alpine', + network_driver_opt={'key1': 'a'} + ) + + client.api.create_container.assert_called_with( + image='alpine', + command=None, + host_config={'NetworkMode': 'default'} + ) + + def test_create_network_driver_opts_with_network_mode(self): + client = make_fake_client() + + client.containers.create( + image='alpine', + network_mode='none', + network_driver_opt={'key1': 'a'} + ) + + client.api.create_container.assert_called_with( + image='alpine', + command=None, + host_config={'NetworkMode': 'none'} + ) + + def test_create_network_driver_opts(self): + client = make_fake_client() + + client.containers.create( + image='alpine', + network='foo', + network_driver_opt={'key1': 'a'} + ) + + client.api.create_container.assert_called_with( + image='alpine', + command=None, + networking_config={'foo': {'driver_opt': {'key1': 'a'}}}, + host_config={'NetworkMode': 'foo'} + ) + def test_get(self): client = make_fake_client() container = client.containers.get(FAKE_CONTAINER_ID) -- cgit v1.2.1