mirror of https://github.com/docker/compose.git
Handle mismatched network formats in config files
Signed-off-by: Joffrey F <joffrey@docker.com>
This commit is contained in:
parent
e5689afe4c
commit
f4a22b94ed
|
@ -601,6 +601,9 @@ def finalize_service(service_config, service_names, version):
|
||||||
else:
|
else:
|
||||||
service_dict['network_mode'] = network_mode
|
service_dict['network_mode'] = network_mode
|
||||||
|
|
||||||
|
if 'networks' in service_dict:
|
||||||
|
service_dict['networks'] = parse_networks(service_dict['networks'])
|
||||||
|
|
||||||
if 'restart' in service_dict:
|
if 'restart' in service_dict:
|
||||||
service_dict['restart'] = parse_restart_spec(service_dict['restart'])
|
service_dict['restart'] = parse_restart_spec(service_dict['restart'])
|
||||||
|
|
||||||
|
@ -690,6 +693,7 @@ def merge_service_dicts(base, override, version):
|
||||||
md.merge_mapping('environment', parse_environment)
|
md.merge_mapping('environment', parse_environment)
|
||||||
md.merge_mapping('labels', parse_labels)
|
md.merge_mapping('labels', parse_labels)
|
||||||
md.merge_mapping('ulimits', parse_ulimits)
|
md.merge_mapping('ulimits', parse_ulimits)
|
||||||
|
md.merge_mapping('networks', parse_networks)
|
||||||
md.merge_sequence('links', ServiceLink.parse)
|
md.merge_sequence('links', ServiceLink.parse)
|
||||||
|
|
||||||
for field in ['volumes', 'devices']:
|
for field in ['volumes', 'devices']:
|
||||||
|
@ -699,7 +703,6 @@ def merge_service_dicts(base, override, version):
|
||||||
'depends_on',
|
'depends_on',
|
||||||
'expose',
|
'expose',
|
||||||
'external_links',
|
'external_links',
|
||||||
'networks',
|
|
||||||
'ports',
|
'ports',
|
||||||
'volumes_from',
|
'volumes_from',
|
||||||
]:
|
]:
|
||||||
|
@ -787,6 +790,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_build_arguments = functools.partial(parse_dict_or_list, split_env, 'build arguments')
|
||||||
parse_environment = functools.partial(parse_dict_or_list, split_env, 'environment')
|
parse_environment = functools.partial(parse_dict_or_list, split_env, 'environment')
|
||||||
parse_labels = functools.partial(parse_dict_or_list, split_label, 'labels')
|
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):
|
def parse_ulimits(ulimits):
|
||||||
|
|
|
@ -162,10 +162,7 @@ class ProjectNetworks(object):
|
||||||
def get_network_aliases_for_service(service_dict):
|
def get_network_aliases_for_service(service_dict):
|
||||||
if 'network_mode' in service_dict:
|
if 'network_mode' in service_dict:
|
||||||
return {}
|
return {}
|
||||||
networks = service_dict.get('networks', ['default'])
|
networks = service_dict.get('networks', {'default': None})
|
||||||
if isinstance(networks, list):
|
|
||||||
return dict((net, []) for net in networks)
|
|
||||||
|
|
||||||
return dict(
|
return dict(
|
||||||
(net, (config or {}).get('aliases', []))
|
(net, (config or {}).get('aliases', []))
|
||||||
for net, config in networks.items()
|
for net, config in networks.items()
|
||||||
|
|
|
@ -477,7 +477,15 @@ Networks to join, referencing entries under the
|
||||||
|
|
||||||
#### aliases
|
#### 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:
|
networks:
|
||||||
some-network:
|
some-network:
|
||||||
|
|
|
@ -185,7 +185,7 @@ class CLITestCase(DockerClientTestCase):
|
||||||
'build': {
|
'build': {
|
||||||
'context': os.path.abspath(self.base_dir),
|
'context': os.path.abspath(self.base_dir),
|
||||||
},
|
},
|
||||||
'networks': ['front', 'default'],
|
'networks': {'front': None, 'default': None},
|
||||||
'volumes_from': ['service:other:rw'],
|
'volumes_from': ['service:other:rw'],
|
||||||
},
|
},
|
||||||
'other': {
|
'other': {
|
||||||
|
|
|
@ -565,7 +565,7 @@ class ProjectTest(DockerClientTestCase):
|
||||||
'name': 'web',
|
'name': 'web',
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
'command': 'top',
|
'command': 'top',
|
||||||
'networks': ['foo', 'bar', 'baz'],
|
'networks': {'foo': None, 'bar': None, 'baz': None},
|
||||||
}],
|
}],
|
||||||
volumes={},
|
volumes={},
|
||||||
networks={
|
networks={
|
||||||
|
@ -598,7 +598,7 @@ class ProjectTest(DockerClientTestCase):
|
||||||
services=[{
|
services=[{
|
||||||
'name': 'web',
|
'name': 'web',
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
'networks': ['front'],
|
'networks': {'front': None},
|
||||||
}],
|
}],
|
||||||
volumes={},
|
volumes={},
|
||||||
networks={
|
networks={
|
||||||
|
|
|
@ -608,6 +608,70 @@ class ConfigTest(unittest.TestCase):
|
||||||
self.assertTrue('context' in service[0]['build'])
|
self.assertTrue('context' in service[0]['build'])
|
||||||
self.assertEqual(service[0]['build']['dockerfile'], 'Dockerfile-alt')
|
self.assertEqual(service[0]['build']['dockerfile'], 'Dockerfile-alt')
|
||||||
|
|
||||||
|
def test_load_with_buildargs(self):
|
||||||
|
service = config.load(
|
||||||
|
build_config_details(
|
||||||
|
{
|
||||||
|
'version': '2',
|
||||||
|
'services': {
|
||||||
|
'web': {
|
||||||
|
'build': {
|
||||||
|
'context': '.',
|
||||||
|
'dockerfile': 'Dockerfile-alt',
|
||||||
|
'args': {
|
||||||
|
'opt1': 42,
|
||||||
|
'opt2': 'foobar'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'tests/fixtures/extends',
|
||||||
|
'filename.yml'
|
||||||
|
)
|
||||||
|
).services[0]
|
||||||
|
assert 'args' in service['build']
|
||||||
|
assert 'opt1' in service['build']['args']
|
||||||
|
assert isinstance(service['build']['args']['opt1'], str)
|
||||||
|
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):
|
def test_load_with_multiple_files_v2(self):
|
||||||
base_file = config.ConfigFile(
|
base_file = config.ConfigFile(
|
||||||
'base.yaml',
|
'base.yaml',
|
||||||
|
|
|
@ -438,7 +438,7 @@ class ProjectTest(unittest.TestCase):
|
||||||
{
|
{
|
||||||
'name': 'foo',
|
'name': 'foo',
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
'networks': ['custom']
|
'networks': {'custom': None}
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
networks={'custom': {}},
|
networks={'custom': {}},
|
||||||
|
|
Loading…
Reference in New Issue