Browse Source

Handle mismatched network formats in config files

Signed-off-by: Joffrey F <[email protected]>
Joffrey F 9 năm trước cách đây
mục cha
commit
7152f7ea76

+ 5 - 1
compose/config/config.py

@@ -612,6 +612,9 @@ def finalize_service(service_config, service_names, version):
         else:
             service_dict['network_mode'] = network_mode
 
+    if 'networks' in service_dict:
+        service_dict['networks'] = parse_networks(service_dict['networks'])
+
     if 'restart' in service_dict:
         service_dict['restart'] = parse_restart_spec(service_dict['restart'])
 
@@ -701,6 +704,7 @@ def merge_service_dicts(base, override, version):
     md.merge_mapping('environment', parse_environment)
     md.merge_mapping('labels', parse_labels)
     md.merge_mapping('ulimits', parse_ulimits)
+    md.merge_mapping('networks', parse_networks)
     md.merge_sequence('links', ServiceLink.parse)
 
     for field in ['volumes', 'devices']:
@@ -710,7 +714,6 @@ def merge_service_dicts(base, override, version):
         'depends_on',
         'expose',
         'external_links',
-        'networks',
         'ports',
         'volumes_from',
     ]:
@@ -798,6 +801,7 @@ def parse_dict_or_list(split_func, type_name, arguments):
 parse_build_arguments = functools.partial(parse_dict_or_list, split_env, 'build arguments')
 parse_environment = functools.partial(parse_dict_or_list, split_env, 'environment')
 parse_labels = functools.partial(parse_dict_or_list, split_label, 'labels')
+parse_networks = functools.partial(parse_dict_or_list, lambda k: (k, None), 'networks')
 
 
 def parse_ulimits(ulimits):

+ 1 - 4
compose/network.py

@@ -162,10 +162,7 @@ class ProjectNetworks(object):
 def get_network_aliases_for_service(service_dict):
     if 'network_mode' in service_dict:
         return {}
-    networks = service_dict.get('networks', ['default'])
-    if isinstance(networks, list):
-        return dict((net, []) for net in networks)
-
+    networks = service_dict.get('networks', {'default': None})
     return dict(
         (net, (config or {}).get('aliases', []))
         for net, config in networks.items()

+ 9 - 1
docs/compose-file.md

@@ -477,7 +477,15 @@ Networks to join, referencing entries under the
 
 #### aliases
 
-Alias names for this service on the specified network.
+Aliases (alternative hostnames) for this service on the network. Other servers
+on the network can use either the service name or this alias to connect to
+this service.  Since `alias` is network-scoped:
+
+  * the same service can have different aliases when connected to another
+    network.
+  * it is allowable to configure the same alias name to multiple containers
+    (services) on the same network.
+
 
     networks:
       some-network:

+ 1 - 1
tests/acceptance/cli_test.py

@@ -185,7 +185,7 @@ class CLITestCase(DockerClientTestCase):
                     'build': {
                         'context': os.path.abspath(self.base_dir),
                     },
-                    'networks': ['front', 'default'],
+                    'networks': {'front': None, 'default': None},
                     'volumes_from': ['service:other:rw'],
                 },
                 'other': {

+ 2 - 2
tests/integration/project_test.py

@@ -565,7 +565,7 @@ class ProjectTest(DockerClientTestCase):
                 'name': 'web',
                 'image': 'busybox:latest',
                 'command': 'top',
-                'networks': ['foo', 'bar', 'baz'],
+                'networks': {'foo': None, 'bar': None, 'baz': None},
             }],
             volumes={},
             networks={
@@ -598,7 +598,7 @@ class ProjectTest(DockerClientTestCase):
             services=[{
                 'name': 'web',
                 'image': 'busybox:latest',
-                'networks': ['front'],
+                'networks': {'front': None},
             }],
             volumes={},
             networks={

+ 36 - 0
tests/unit/config/config_test.py

@@ -649,6 +649,42 @@ class ConfigTest(unittest.TestCase):
         assert service['build']['args']['opt1'] == '42'
         assert service['build']['args']['opt2'] == 'foobar'
 
+    def test_load_with_multiple_files_mismatched_networks_format(self):
+        base_file = config.ConfigFile(
+            'base.yaml',
+            {
+                'version': '2',
+                'services': {
+                    'web': {
+                        'image': 'example/web',
+                        'networks': {
+                            'foobar': {'aliases': ['foo', 'bar']}
+                        }
+                    }
+                },
+                'networks': {'foobar': {}, 'baz': {}}
+            }
+        )
+
+        override_file = config.ConfigFile(
+            'override.yaml',
+            {
+                'version': '2',
+                'services': {
+                    'web': {
+                        'networks': ['baz']
+                    }
+                }
+            }
+        )
+
+        details = config.ConfigDetails('.', [base_file, override_file])
+        web_service = config.load(details).services[0]
+        assert web_service['networks'] == {
+            'foobar': {'aliases': ['foo', 'bar']},
+            'baz': None
+        }
+
     def test_load_with_multiple_files_v2(self):
         base_file = config.ConfigFile(
             'base.yaml',

+ 1 - 1
tests/unit/project_test.py

@@ -438,7 +438,7 @@ class ProjectTest(unittest.TestCase):
                     {
                         'name': 'foo',
                         'image': 'busybox:latest',
-                        'networks': ['custom']
+                        'networks': {'custom': None}
                     },
                 ],
                 networks={'custom': {}},