From 608f29c7cb574e1f6a36f39a48f78676738738e0 Mon Sep 17 00:00:00 2001 From: Aanand Prasad Date: Fri, 16 Jan 2015 13:12:29 +0000 Subject: [PATCH 1/3] Unit tests for Service.containers() and get_container_name() Signed-off-by: Aanand Prasad --- tests/unit/service_test.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/unit/service_test.py b/tests/unit/service_test.py index 68dcf06ab..1f0333809 100644 --- a/tests/unit/service_test.py +++ b/tests/unit/service_test.py @@ -17,6 +17,7 @@ from fig.service import ( parse_volume_spec, build_volume_binding, APIError, + get_container_name, parse_repository_tag, ) @@ -49,6 +50,25 @@ class ServiceTest(unittest.TestCase): self.assertRaises(ConfigError, lambda: Service(name='foo', port=['8000'])) Service(name='foo', ports=['8000']) + def test_get_container_name(self): + self.assertIsNone(get_container_name({})) + self.assertEqual(get_container_name({'Name': 'myproject_db_1'}), 'myproject_db_1') + self.assertEqual(get_container_name({'Names': ['/myproject_db_1', '/myproject_web_1/db']}), 'myproject_db_1') + + def test_containers(self): + service = Service('db', client=self.mock_client, project='myproject') + + self.mock_client.containers.return_value = [] + self.assertEqual(service.containers(), []) + + self.mock_client.containers.return_value = [ + {'Image': 'busybox', 'Id': 'OUT_1', 'Names': ['/myproject', '/foo/bar']}, + {'Image': 'busybox', 'Id': 'OUT_2', 'Names': ['/myproject_db']}, + {'Image': 'busybox', 'Id': 'OUT_3', 'Names': ['/db_1']}, + {'Image': 'busybox', 'Id': 'IN_1', 'Names': ['/myproject_db_1', '/myproject_web_1/db']}, + ] + self.assertEqual([c.id for c in service.containers()], ['IN_1']) + def test_get_volumes_from_container(self): container_id = 'aabbccddee' service = Service( From edb6b24b8ff1c13cefe3ee347d75557918f38aa8 Mon Sep 17 00:00:00 2001 From: Aanand Prasad Date: Fri, 16 Jan 2015 16:43:59 +0000 Subject: [PATCH 2/3] Handle Swarm-style prefixed names in Service.containers() Signed-off-by: Aanand Prasad --- fig/service.py | 5 ++--- tests/unit/service_test.py | 12 ++++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/fig/service.py b/fig/service.py index 18ba3f618..369d4e845 100644 --- a/fig/service.py +++ b/fig/service.py @@ -545,9 +545,8 @@ def get_container_name(container): if 'Name' in container: return container['Name'] # ps - for name in container['Names']: - if len(name.split('/')) == 2: - return name[1:] + shortest_name = min(container['Names'], key=lambda n: len(n.split('/'))) + return shortest_name.split('/')[-1] def parse_restart_spec(restart_config): diff --git a/tests/unit/service_test.py b/tests/unit/service_test.py index 1f0333809..6db603d05 100644 --- a/tests/unit/service_test.py +++ b/tests/unit/service_test.py @@ -54,6 +54,7 @@ class ServiceTest(unittest.TestCase): self.assertIsNone(get_container_name({})) self.assertEqual(get_container_name({'Name': 'myproject_db_1'}), 'myproject_db_1') self.assertEqual(get_container_name({'Names': ['/myproject_db_1', '/myproject_web_1/db']}), 'myproject_db_1') + self.assertEqual(get_container_name({'Names': ['/swarm-host-1/myproject_db_1', '/swarm-host-1/myproject_web_1/db']}), 'myproject_db_1') def test_containers(self): service = Service('db', client=self.mock_client, project='myproject') @@ -69,6 +70,17 @@ class ServiceTest(unittest.TestCase): ] self.assertEqual([c.id for c in service.containers()], ['IN_1']) + def test_containers_prefixed(self): + service = Service('db', client=self.mock_client, project='myproject') + + self.mock_client.containers.return_value = [ + {'Image': 'busybox', 'Id': 'OUT_1', 'Names': ['/swarm-host-1/myproject', '/swarm-host-1/foo/bar']}, + {'Image': 'busybox', 'Id': 'OUT_2', 'Names': ['/swarm-host-1/myproject_db']}, + {'Image': 'busybox', 'Id': 'OUT_3', 'Names': ['/swarm-host-1/db_1']}, + {'Image': 'busybox', 'Id': 'IN_1', 'Names': ['/swarm-host-1/myproject_db_1', '/swarm-host-1/myproject_web_1/db']}, + ] + self.assertEqual([c.id for c in service.containers()], ['IN_1']) + def test_get_volumes_from_container(self): container_id = 'aabbccddee' service = Service( From cbd3ca07c4644c62b3914cecfa60436a46d77836 Mon Sep 17 00:00:00 2001 From: Aanand Prasad Date: Fri, 16 Jan 2015 17:24:29 +0000 Subject: [PATCH 3/3] Handle Swarm-style prefixed names in Container.from_ps() Signed-off-by: Aanand Prasad --- fig/container.py | 15 ++++++++++++--- fig/service.py | 13 +------------ tests/unit/container_test.py | 14 +++++++++++++- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/fig/container.py b/fig/container.py index 0ab755120..692145988 100644 --- a/fig/container.py +++ b/fig/container.py @@ -22,10 +22,8 @@ class Container(object): new_dictionary = { 'Id': dictionary['Id'], 'Image': dictionary['Image'], + 'Name': '/' + get_container_name(dictionary), } - for name in dictionary.get('Names', []): - if len(name.split('/')) == 2: - new_dictionary['Name'] = name return cls(client, new_dictionary, **kwargs) @classmethod @@ -170,3 +168,14 @@ class Container(object): if type(self) != type(other): return False return self.id == other.id + + +def get_container_name(container): + if not container.get('Name') and not container.get('Names'): + return None + # inspect + if 'Name' in container: + return container['Name'] + # ps + shortest_name = min(container['Names'], key=lambda n: len(n.split('/'))) + return shortest_name.split('/')[-1] diff --git a/fig/service.py b/fig/service.py index 369d4e845..6743e1717 100644 --- a/fig/service.py +++ b/fig/service.py @@ -9,7 +9,7 @@ import sys from docker.errors import APIError -from .container import Container +from .container import Container, get_container_name from .progress_stream import stream_output, StreamOutputError log = logging.getLogger(__name__) @@ -538,17 +538,6 @@ def parse_name(name): return ServiceName(project, service_name, int(suffix)) -def get_container_name(container): - if not container.get('Name') and not container.get('Names'): - return None - # inspect - if 'Name' in container: - return container['Name'] - # ps - shortest_name = min(container['Names'], key=lambda n: len(n.split('/'))) - return shortest_name.split('/')[-1] - - def parse_restart_spec(restart_config): if not restart_config: return None diff --git a/tests/unit/container_test.py b/tests/unit/container_test.py index 18f7944eb..264681185 100644 --- a/tests/unit/container_test.py +++ b/tests/unit/container_test.py @@ -20,7 +20,7 @@ class ContainerTest(unittest.TestCase): "Ports": None, "SizeRw": 0, "SizeRootFs": 0, - "Names": ["/figtest_db_1"], + "Names": ["/figtest_db_1", "/figtest_web_1/db"], "NetworkSettings": { "Ports": {}, }, @@ -36,6 +36,18 @@ class ContainerTest(unittest.TestCase): "Name": "/figtest_db_1", }) + def test_from_ps_prefixed(self): + self.container_dict['Names'] = ['/swarm-host-1' + n for n in self.container_dict['Names']] + + container = Container.from_ps(None, + self.container_dict, + has_been_inspected=True) + self.assertEqual(container.dictionary, { + "Id": "abc", + "Image":"busybox:latest", + "Name": "/figtest_db_1", + }) + def test_environment(self): container = Container(None, { 'Id': 'abc',