From 5b6e02d13ac929efdf99c145f351429040493940 Mon Sep 17 00:00:00 2001 From: Thomas Scholtes Date: Wed, 10 May 2017 10:36:05 +0200 Subject: [PATCH 1/3] 'run' command can use network aliases for service It is now possible for the 'run' command to use the network aliases defined for the service. Fixes #3492 Signed-off-by: Thomas Scholtes --- compose/cli/main.py | 10 +++++++--- compose/service.py | 26 ++++++++++++-------------- tests/unit/cli_test.py | 4 ++++ 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/compose/cli/main.py b/compose/cli/main.py index aff69c2d3..c79e4f7e4 100644 --- a/compose/cli/main.py +++ b/compose/cli/main.py @@ -803,6 +803,8 @@ class TopLevelCommand(object): -p, --publish=[] Publish a container's port(s) to the host --service-ports Run command with the service's ports enabled and mapped to the host. + --use-aliases Use the service's network aliases in the network(s) the + container connects to. -v, --volume=[] Bind mount a volume (default []) -T Disable pseudo-tty allocation. By default `docker-compose run` allocates a TTY. @@ -1279,8 +1281,10 @@ def run_one_off_container(container_options, project, service, options, toplevel one_off=True, **container_options) + use_network_aliases = options['--use-aliases'] + if options.get('--detach'): - service.start_container(container) + service.start_container(container, use_network_aliases) print(container.name) return @@ -1296,7 +1300,7 @@ def run_one_off_container(container_options, project, service, options, toplevel try: try: if IS_WINDOWS_PLATFORM or use_cli: - service.connect_container_to_networks(container) + service.connect_container_to_networks(container, use_network_aliases) exit_code = call_docker( ["start", "--attach", "--interactive", container.id], toplevel_options @@ -1310,7 +1314,7 @@ def run_one_off_container(container_options, project, service, options, toplevel ) pty = PseudoTerminal(project.client, operation) sockets = pty.sockets() - service.start_container(container) + service.start_container(container, use_network_aliases) pty.start(sockets) exit_code = container.wait() except (signals.ShutdownException): diff --git a/compose/service.py b/compose/service.py index 85aa74f26..cd1f77587 100644 --- a/compose/service.py +++ b/compose/service.py @@ -557,8 +557,8 @@ class Service(object): container.attach_log_stream() return self.start_container(container) - def start_container(self, container): - self.connect_container_to_networks(container) + def start_container(self, container, use_network_aliases=True): + self.connect_container_to_networks(container, use_network_aliases) try: container.start() except APIError as ex: @@ -574,7 +574,7 @@ class Service(object): ) ) - def connect_container_to_networks(self, container): + def connect_container_to_networks(self, container, use_network_aliases=True): connected_networks = container.get('NetworkSettings.Networks') for network, netdefs in self.prioritized_networks.items(): @@ -583,10 +583,15 @@ class Service(object): continue self.client.disconnect_container_from_network(container.id, network) - log.debug('Connecting to {}'.format(network)) + self.client.disconnect_container_from_network( + container.id, + network) + + aliases = self._get_aliases(netdefs) if use_network_aliases else [] + self.client.connect_container_to_network( container.id, network, - aliases=self._get_aliases(netdefs, container), + aliases=aliases, ipv4_address=netdefs.get('ipv4_address', None), ipv6_address=netdefs.get('ipv6_address', None), links=self._get_links(False), @@ -691,15 +696,8 @@ class Service(object): numbers = [c.number for c in containers] return 1 if not numbers else max(numbers) + 1 - def _get_aliases(self, network, container=None): - if container and container.labels.get(LABEL_ONE_OFF) == "True": - return [] - - return list( - {self.name} | - ({container.short_id} if container else set()) | - set(network.get('aliases', ())) - ) + def _get_aliases(self, network): + return list({self.name} | set(network.get('aliases', ()))) def build_default_networking_config(self): if not self.networks: diff --git a/tests/unit/cli_test.py b/tests/unit/cli_test.py index cef53740d..47eaabf9d 100644 --- a/tests/unit/cli_test.py +++ b/tests/unit/cli_test.py @@ -124,6 +124,7 @@ class CLITestCase(unittest.TestCase): '-T': None, '--entrypoint': None, '--service-ports': None, + '--use-aliases': None, '--publish': [], '--volume': [], '--rm': None, @@ -162,6 +163,7 @@ class CLITestCase(unittest.TestCase): '-T': None, '--entrypoint': None, '--service-ports': None, + '--use-aliases': None, '--publish': [], '--volume': [], '--rm': None, @@ -183,6 +185,7 @@ class CLITestCase(unittest.TestCase): '-T': None, '--entrypoint': None, '--service-ports': None, + '--use-aliases': None, '--publish': [], '--volume': [], '--rm': True, @@ -214,6 +217,7 @@ class CLITestCase(unittest.TestCase): '-T': None, '--entrypoint': None, '--service-ports': True, + '--use-aliases': None, '--publish': ['80:80'], '--rm': None, '--name': None, From e78c0bf533280ee526e1b5cc52cc7e7db139fb36 Mon Sep 17 00:00:00 2001 From: Jim Dalton Date: Wed, 10 May 2017 13:28:40 +0200 Subject: [PATCH 2/3] Add acceptance test for use-aliases feature Signed-off-by: Jim Dalton --- tests/acceptance/cli_test.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/acceptance/cli_test.py b/tests/acceptance/cli_test.py index 42b487aab..404cd8c48 100644 --- a/tests/acceptance/cli_test.py +++ b/tests/acceptance/cli_test.py @@ -1903,6 +1903,28 @@ class CLITestCase(DockerClientTestCase): container = service.containers(stopped=True, one_off=True)[0] assert workdir == container.get('Config.WorkingDir') + @v2_only() + def test_run_service_with_use_aliases(self): + filename = 'network-aliases.yml' + self.base_dir = 'tests/fixtures/networks' + self.dispatch(['-f', filename, 'run', '-d', '--use-aliases', 'web', 'top']) + + back_name = '{}_back'.format(self.project.name) + front_name = '{}_front'.format(self.project.name) + + web_container = self.project.get_service('web').containers(one_off=OneOffFilter.only)[0] + + back_aliases = web_container.get( + 'NetworkSettings.Networks.{}.Aliases'.format(back_name) + ) + assert 'web' in back_aliases + front_aliases = web_container.get( + 'NetworkSettings.Networks.{}.Aliases'.format(front_name) + ) + assert 'web' in front_aliases + assert 'forward_facing' in front_aliases + assert 'ahead' in front_aliases + @v2_only() def test_run_interactive_connects_to_network(self): self.base_dir = 'tests/fixtures/networks' From 07199fac374c427dcd949507e282abd2082d7564 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Tue, 27 Feb 2018 13:17:28 -0800 Subject: [PATCH 3/3] Restore container ID alias Signed-off-by: Joffrey F --- compose/service.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/compose/service.py b/compose/service.py index cd1f77587..b9f9af2cd 100644 --- a/compose/service.py +++ b/compose/service.py @@ -583,11 +583,7 @@ class Service(object): continue self.client.disconnect_container_from_network(container.id, network) - self.client.disconnect_container_from_network( - container.id, - network) - - aliases = self._get_aliases(netdefs) if use_network_aliases else [] + aliases = self._get_aliases(netdefs, container) if use_network_aliases else [] self.client.connect_container_to_network( container.id, network, @@ -696,8 +692,12 @@ class Service(object): numbers = [c.number for c in containers] return 1 if not numbers else max(numbers) + 1 - def _get_aliases(self, network): - return list({self.name} | set(network.get('aliases', ()))) + def _get_aliases(self, network, container=None): + return list( + {self.name} | + ({container.short_id} if container else set()) | + set(network.get('aliases', ())) + ) def build_default_networking_config(self): if not self.networks: