Skip to content

Commit 01a754a

Browse files
committed
Support links when creating containers or connecting to networks
Signed-off-by: Aanand Prasad <[email protected]>
1 parent 656e6cf commit 01a754a

File tree

6 files changed

+85
-10
lines changed

6 files changed

+85
-10
lines changed

docker/api/network.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import json
22

3-
from ..utils import check_resource, minimum_version
3+
from ..utils import check_resource, minimum_version, normalize_links
44

55

66
class NetworkApiMixin(object):
@@ -47,11 +47,13 @@ def inspect_network(self, net_id):
4747

4848
@check_resource
4949
@minimum_version('1.21')
50-
def connect_container_to_network(self, container, net_id, aliases=None):
50+
def connect_container_to_network(self, container, net_id,
51+
aliases=None, links=None):
5152
data = {
5253
"Container": container,
5354
"EndpointConfig": {
5455
"Aliases": aliases,
56+
"Links": normalize_links(links) if links else None,
5557
},
5658
}
5759
url = self._url("/networks/{0}/connect", net_id)

docker/utils/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
kwargs_from_env, convert_filters, datetime_to_timestamp, create_host_config,
55
create_container_config, parse_bytes, ping_registry, parse_env_file,
66
version_lt, version_gte, decode_json_header, split_command,
7-
create_ipam_config, create_ipam_pool, parse_devices
7+
create_ipam_config, create_ipam_pool, parse_devices, normalize_links,
88
) # flake8: noqa
99

1010
from .types import Ulimit, LogConfig # flake8: noqa

docker/utils/utils.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -674,12 +674,7 @@ def create_host_config(binds=None, port_bindings=None, lxc_conf=None,
674674
host_config['ExtraHosts'] = extra_hosts
675675

676676
if links is not None:
677-
if isinstance(links, dict):
678-
links = six.iteritems(links)
679-
680-
formatted_links = ['{0}:{1}'.format(k, v) for k, v in sorted(links)]
681-
682-
host_config['Links'] = formatted_links
677+
host_config['Links'] = normalize_links(links)
683678

684679
if isinstance(lxc_conf, dict):
685680
formatted = []
@@ -731,6 +726,13 @@ def create_host_config(binds=None, port_bindings=None, lxc_conf=None,
731726
return host_config
732727

733728

729+
def normalize_links(links):
730+
if isinstance(links, dict):
731+
links = six.iteritems(links)
732+
733+
return ['{0}:{1}'.format(k, v) for k, v in sorted(links)]
734+
735+
734736
def create_networking_config(endpoints_config=None):
735737
networking_config = {}
736738

@@ -740,14 +742,19 @@ def create_networking_config(endpoints_config=None):
740742
return networking_config
741743

742744

743-
def create_endpoint_config(version, aliases=None):
745+
def create_endpoint_config(version, aliases=None, links=None):
744746
endpoint_config = {}
745747

746748
if aliases:
747749
if version_lt(version, '1.22'):
748750
raise host_config_version_error('endpoint_config.aliases', '1.22')
749751
endpoint_config["Aliases"] = aliases
750752

753+
if links:
754+
if version_lt(version, '1.22'):
755+
raise host_config_version_error('endpoint_config.links', '1.22')
756+
endpoint_config["Links"] = normalize_links(links)
757+
751758
return endpoint_config
752759

753760

tests/helpers.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,18 @@ def run_container(self, *args, **kwargs):
168168
.format(exitcode, output))
169169

170170
return container
171+
172+
def create_and_start(self, image='busybox', command='top', **kwargs):
173+
container = self.client.create_container(
174+
image=image, command=command, **kwargs)
175+
self.tmp_containers.append(container)
176+
self.client.start(container)
177+
return container
178+
179+
def execute(self, container, cmd, exit_code=0, **kwargs):
180+
exc = self.client.exec_create(container, cmd, **kwargs)
181+
output = self.client.exec_start(exc)
182+
actual_exit_code = self.client.exec_inspect(exc)['ExitCode']
183+
msg = "Expected `{}` to exit with code {} but returned {}:\n{}".format(
184+
" ".join(cmd), exit_code, actual_exit_code, output)
185+
assert actual_exit_code == exit_code, msg

tests/integration/network_test.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,52 @@ def test_create_with_aliases(self):
180180
self.assertEqual(
181181
container_data['NetworkSettings']['Networks'][net_name]['Aliases'],
182182
['foo', 'bar'])
183+
184+
@requires_api_version('1.22')
185+
def test_create_with_links(self):
186+
net_name, net_id = self.create_network()
187+
188+
container = self.create_and_start(
189+
host_config=self.client.create_host_config(network_mode=net_name),
190+
networking_config=self.client.create_networking_config({
191+
net_name: self.client.create_endpoint_config(
192+
links=[('docker-py-test-upstream', 'bar')],
193+
),
194+
}),
195+
)
196+
197+
container_data = self.client.inspect_container(container)
198+
self.assertEqual(
199+
container_data['NetworkSettings']['Networks'][net_name]['Links'],
200+
['docker-py-test-upstream:bar'])
201+
202+
self.create_and_start(
203+
name='docker-py-test-upstream',
204+
host_config=self.client.create_host_config(network_mode=net_name),
205+
)
206+
207+
self.execute(container, ['nslookup', 'bar'])
208+
209+
@requires_api_version('1.22')
210+
def test_connect_with_links(self):
211+
net_name, net_id = self.create_network()
212+
213+
container = self.create_and_start(
214+
host_config=self.client.create_host_config(network_mode=net_name))
215+
216+
self.client.disconnect_container_from_network(container, net_name)
217+
self.client.connect_container_to_network(
218+
container, net_name,
219+
links=[('docker-py-test-upstream', 'bar')])
220+
221+
container_data = self.client.inspect_container(container)
222+
self.assertEqual(
223+
container_data['NetworkSettings']['Networks'][net_name]['Links'],
224+
['docker-py-test-upstream:bar'])
225+
226+
self.create_and_start(
227+
name='docker-py-test-upstream',
228+
host_config=self.client.create_host_config(network_mode=net_name),
229+
)
230+
231+
self.execute(container, ['nslookup', 'bar'])

tests/unit/network_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ def test_connect_container_to_network(self):
150150
{'Id': container_id},
151151
network_id,
152152
aliases=['foo', 'bar'],
153+
links=[('baz', 'quux')]
153154
)
154155

155156
self.assertEqual(
@@ -162,6 +163,7 @@ def test_connect_container_to_network(self):
162163
'Container': container_id,
163164
'EndpointConfig': {
164165
'Aliases': ['foo', 'bar'],
166+
'Links': ['baz:quux'],
165167
},
166168
})
167169

0 commit comments

Comments
 (0)