From 73fbd01cfe7c1e8ad7d297d7f7cfb8704aeb501d Mon Sep 17 00:00:00 2001 From: Aanand Prasad <aanand.prasad@gmail.com> Date: Thu, 14 Jan 2016 13:39:44 +0000 Subject: [PATCH] Support the 'external' option for networks Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com> --- compose/network.py | 25 +++++++++++++++++-- compose/project.py | 4 ++- tests/acceptance/cli_test.py | 23 +++++++++++++++++ tests/fixtures/networks/external-networks.yml | 16 ++++++++++++ 4 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 tests/fixtures/networks/external-networks.yml diff --git a/compose/network.py b/compose/network.py index a8f7e918d..b2ba2e9b7 100644 --- a/compose/network.py +++ b/compose/network.py @@ -11,16 +11,35 @@ from .config import ConfigurationError log = logging.getLogger(__name__) -# TODO: support external networks class Network(object): - def __init__(self, client, project, name, driver=None, driver_opts=None): + def __init__(self, client, project, name, driver=None, driver_opts=None, + external_name=None): self.client = client self.project = project self.name = name self.driver = driver self.driver_opts = driver_opts + self.external_name = external_name def ensure(self): + if self.external_name: + try: + self.inspect() + log.debug( + 'Network {0} declared as external. No new ' + 'network will be created.'.format(self.name) + ) + except NotFound: + raise ConfigurationError( + 'Network {name} declared as external, but could' + ' not be found. Please create the network manually' + ' using `{command} {name}` and try again.'.format( + name=self.external_name, + command='docker network create' + ) + ) + return + try: data = self.inspect() if self.driver and data['Driver'] != self.driver: @@ -55,4 +74,6 @@ class Network(object): @property def full_name(self): + if self.external_name: + return self.external_name return '{0}_{1}'.format(self.project, self.name) diff --git a/compose/project.py b/compose/project.py index 1b5d2eb94..6a171d514 100644 --- a/compose/project.py +++ b/compose/project.py @@ -64,7 +64,9 @@ class Project(object): custom_networks.append( Network( client=client, project=name, name=network_name, - driver=data.get('driver'), driver_opts=data.get('driver_opts') + driver=data.get('driver'), + driver_opts=data.get('driver_opts'), + external_name=data.get('external_name'), ) ) diff --git a/tests/acceptance/cli_test.py b/tests/acceptance/cli_test.py index 90c507698..a7d5dbaae 100644 --- a/tests/acceptance/cli_test.py +++ b/tests/acceptance/cli_test.py @@ -456,6 +456,29 @@ class CLITestCase(DockerClientTestCase): assert container.get('NetworkSettings.Networks').keys() == [name] assert container.get('HostConfig.NetworkMode') == name + def test_up_external_networks(self): + filename = 'external-networks.yml' + + self.base_dir = 'tests/fixtures/networks' + self._project = get_project(self.base_dir, [filename]) + + result = self.dispatch(['-f', filename, 'up', '-d'], returncode=1) + assert 'declared as external, but could not be found' in result.stderr + + networks = [ + n['Name'] for n in self.client.networks() + if n['Name'].startswith('{}_'.format(self.project.name)) + ] + assert not networks + + network_names = ['{}_{}'.format(self.project.name, n) for n in ['foo', 'bar']] + for name in network_names: + self.client.create_network(name) + + self.dispatch(['-f', filename, 'up', '-d']) + container = self.project.containers()[0] + assert sorted(container.get('NetworkSettings.Networks').keys()) == sorted(network_names) + def test_up_no_services(self): self.base_dir = 'tests/fixtures/no-services' self.dispatch(['up', '-d'], None) diff --git a/tests/fixtures/networks/external-networks.yml b/tests/fixtures/networks/external-networks.yml new file mode 100644 index 000000000..644e3dda9 --- /dev/null +++ b/tests/fixtures/networks/external-networks.yml @@ -0,0 +1,16 @@ +version: 2 + +services: + web: + image: busybox + command: top + networks: + - networks_foo + - bar + +networks: + networks_foo: + external: true + bar: + external: + name: networks_bar