From 42577072443384d2dc35cc4f827bc57239a42757 Mon Sep 17 00:00:00 2001 From: Jason Bernardino Alonso Date: Wed, 8 Oct 2014 22:31:04 -0400 Subject: [PATCH] Accept an external_links list in the service configuration dictionary to create links to containers outside of the project Signed-off-by: Jason Bernardino Alonso Signed-off-by: Mauricio de Abreu Antunes --- docs/yml.md | 12 ++++++++++++ fig/service.py | 12 ++++++++++-- tests/integration/service_test.py | 20 ++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/docs/yml.md b/docs/yml.md index a911e450b86..71d2cb7a2c1 100644 --- a/docs/yml.md +++ b/docs/yml.md @@ -58,6 +58,18 @@ An entry with the alias' name will be created in `/etc/hosts` inside containers Environment variables will also be created - see the [environment variable reference](env.html) for details. +### external_links + +Link to containers started outside this `fig.yml` or even outside of fig, especially for containers that provide shared or common services. +`external_links` follow semantics similar to `links` when specifying both the container name and the link alias (`CONTAINER:ALIAS`). + +``` +external_links: + - redis_1 + - project_db_1:mysql + - project_db_1:postgresql +``` + ### ports Expose ports. Either specify both ports (`HOST:CONTAINER`), or just the container port (a random host port will be chosen). diff --git a/fig/service.py b/fig/service.py index bd3000c6207..f88b466d545 100644 --- a/fig/service.py +++ b/fig/service.py @@ -74,7 +74,7 @@ class ConfigError(ValueError): class Service(object): - def __init__(self, name, client=None, project='default', links=None, volumes_from=None, **options): + def __init__(self, name, client=None, project='default', links=None, external_links=None, volumes_from=None, **options): if not re.match('^%s+$' % VALID_NAME_CHARS, name): raise ConfigError('Invalid service name "%s" - only %s are allowed' % (name, VALID_NAME_CHARS)) if not re.match('^%s+$' % VALID_NAME_CHARS, project): @@ -82,7 +82,8 @@ def __init__(self, name, client=None, project='default', links=None, volumes_fro if 'image' in options and 'build' in options: raise ConfigError('Service %s has both an image and build path specified. A service can either be built to image or use an existing image, not both.' % name) - supported_options = DOCKER_CONFIG_KEYS + ['build', 'expose'] + supported_options = DOCKER_CONFIG_KEYS + ['build', 'expose', + 'external_links'] for k in options: if k not in supported_options: @@ -95,6 +96,7 @@ def __init__(self, name, client=None, project='default', links=None, volumes_fro self.client = client self.project = project self.links = links or [] + self.external_links = external_links or [] self.volumes_from = volumes_from or [] self.options = options @@ -345,6 +347,12 @@ def _get_links(self, link_to_self): links.append((container.name, self.name)) links.append((container.name, container.name)) links.append((container.name, container.name_without_project)) + for external_link in self.external_links: + if ':' not in external_link: + link_name = external_link + else: + external_link, link_name = external_link.split(':') + links.append((external_link, link_name)) return links def _get_volumes_from(self, intermediate_container=None): diff --git a/tests/integration/service_test.py b/tests/integration/service_test.py index a1740272b53..bbe348eedb5 100644 --- a/tests/integration/service_test.py +++ b/tests/integration/service_test.py @@ -219,6 +219,26 @@ def test_start_container_creates_links_with_names(self): ]), ) + def test_start_container_with_external_links(self): + db = self.create_service('db') + web = self.create_service('web', external_links=['figtest_db_1', + 'figtest_db_2', + 'figtest_db_3:db_3']) + + db.start_container() + db.start_container() + db.start_container() + web.start_container() + + self.assertEqual( + set(web.containers()[0].links()), + set([ + 'figtest_db_1', + 'figtest_db_2', + 'db_3', + ]), + ) + def test_start_normal_container_does_not_create_links_to_its_own_service(self): db = self.create_service('db')