mirror of https://github.com/docker/compose.git
Fixes #2205 - extends must be copied from override file.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
parent
f1f3acd070
commit
938d49cbdc
|
@ -193,7 +193,9 @@ def load(config_details):
|
||||||
def merge_services(base, override):
|
def merge_services(base, override):
|
||||||
all_service_names = set(base) | set(override)
|
all_service_names = set(base) | set(override)
|
||||||
return {
|
return {
|
||||||
name: merge_service_dicts(base.get(name, {}), override.get(name, {}))
|
name: merge_service_dicts_from_files(
|
||||||
|
base.get(name, {}),
|
||||||
|
override.get(name, {}))
|
||||||
for name in all_service_names
|
for name in all_service_names
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,9 +272,7 @@ class ServiceLoader(object):
|
||||||
extends,
|
extends,
|
||||||
self.filename
|
self.filename
|
||||||
)
|
)
|
||||||
self.extended_config_path = self.get_extended_config_path(
|
self.extended_config_path = self.get_extended_config_path(extends)
|
||||||
extends
|
|
||||||
)
|
|
||||||
self.extended_service_name = extends['service']
|
self.extended_service_name = extends['service']
|
||||||
|
|
||||||
config = load_yaml(self.extended_config_path)
|
config = load_yaml(self.extended_config_path)
|
||||||
|
@ -355,6 +355,17 @@ def process_container_options(service_dict, working_dir=None):
|
||||||
return service_dict
|
return service_dict
|
||||||
|
|
||||||
|
|
||||||
|
def merge_service_dicts_from_files(base, override):
|
||||||
|
"""When merging services from multiple files we need to merge the `extends`
|
||||||
|
field. This is not handled by `merge_service_dicts()` which is used to
|
||||||
|
perform the `extends`.
|
||||||
|
"""
|
||||||
|
new_service = merge_service_dicts(base, override)
|
||||||
|
if 'extends' in override:
|
||||||
|
new_service['extends'] = override['extends']
|
||||||
|
return new_service
|
||||||
|
|
||||||
|
|
||||||
def merge_service_dicts(base, override):
|
def merge_service_dicts(base, override):
|
||||||
d = base.copy()
|
d = base.copy()
|
||||||
|
|
||||||
|
|
|
@ -156,6 +156,43 @@ class ConfigTest(unittest.TestCase):
|
||||||
config.load(details)
|
config.load(details)
|
||||||
assert 'Top level object needs to be a dictionary' in exc.exconly()
|
assert 'Top level object needs to be a dictionary' in exc.exconly()
|
||||||
|
|
||||||
|
def test_load_with_multiple_files_and_extends_in_override_file(self):
|
||||||
|
base_file = config.ConfigFile(
|
||||||
|
'base.yaml',
|
||||||
|
{
|
||||||
|
'web': {'image': 'example/web'},
|
||||||
|
})
|
||||||
|
override_file = config.ConfigFile(
|
||||||
|
'override.yaml',
|
||||||
|
{
|
||||||
|
'web': {
|
||||||
|
'extends': {
|
||||||
|
'file': 'common.yml',
|
||||||
|
'service': 'base',
|
||||||
|
},
|
||||||
|
'volumes': ['/home/user/project:/code'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
details = config.ConfigDetails('.', [base_file, override_file])
|
||||||
|
|
||||||
|
tmpdir = py.test.ensuretemp('config_test')
|
||||||
|
tmpdir.join('common.yml').write("""
|
||||||
|
base:
|
||||||
|
labels: ['label=one']
|
||||||
|
""")
|
||||||
|
with tmpdir.as_cwd():
|
||||||
|
service_dicts = config.load(details)
|
||||||
|
|
||||||
|
expected = [
|
||||||
|
{
|
||||||
|
'name': 'web',
|
||||||
|
'image': 'example/web',
|
||||||
|
'volumes': ['/home/user/project:/code'],
|
||||||
|
'labels': {'label': 'one'},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
self.assertEqual(service_sort(service_dicts), service_sort(expected))
|
||||||
|
|
||||||
def test_config_valid_service_names(self):
|
def test_config_valid_service_names(self):
|
||||||
for valid_name in ['_', '-', '.__.', '_what-up.', 'what_.up----', 'whatup']:
|
for valid_name in ['_', '-', '.__.', '_what-up.', 'what_.up----', 'whatup']:
|
||||||
config.load(
|
config.load(
|
||||||
|
|
Loading…
Reference in New Issue