mirror of
https://github.com/docker/compose.git
synced 2025-07-22 13:14:29 +02:00
Make volume host paths relative to file, merge volumes when extending
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
This commit is contained in:
parent
4c582e4352
commit
37efdb1f8b
@ -166,6 +166,11 @@ def process_container_options(service_dict, working_dir=None):
|
|||||||
msg += " (did you mean '%s'?)" % DOCKER_CONFIG_HINTS[k]
|
msg += " (did you mean '%s'?)" % DOCKER_CONFIG_HINTS[k]
|
||||||
raise ConfigurationError(msg)
|
raise ConfigurationError(msg)
|
||||||
|
|
||||||
|
service_dict = service_dict.copy()
|
||||||
|
|
||||||
|
if 'volumes' in service_dict:
|
||||||
|
service_dict['volumes'] = resolve_host_paths(service_dict['volumes'], working_dir=working_dir)
|
||||||
|
|
||||||
return service_dict
|
return service_dict
|
||||||
|
|
||||||
|
|
||||||
@ -178,8 +183,14 @@ def merge_service_dicts(base, override):
|
|||||||
override.get('environment'),
|
override.get('environment'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if 'volumes' in base or 'volumes' in override:
|
||||||
|
d['volumes'] = merge_volumes(
|
||||||
|
base.get('volumes'),
|
||||||
|
override.get('volumes'),
|
||||||
|
)
|
||||||
|
|
||||||
for k in ALLOWED_KEYS:
|
for k in ALLOWED_KEYS:
|
||||||
if k not in ['environment']:
|
if k not in ['environment', 'volumes']:
|
||||||
if k in override:
|
if k in override:
|
||||||
d[k] = override[k]
|
d[k] = override[k]
|
||||||
|
|
||||||
@ -285,6 +296,42 @@ def env_vars_from_file(filename):
|
|||||||
return env
|
return env
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_host_paths(volumes, working_dir=None):
|
||||||
|
if working_dir is None:
|
||||||
|
raise Exception("No working_dir passed to resolve_host_paths()")
|
||||||
|
|
||||||
|
return [resolve_host_path(v, working_dir) for v in volumes]
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_host_path(volume, working_dir):
|
||||||
|
container_path, host_path = split_volume(volume)
|
||||||
|
if host_path is not None:
|
||||||
|
return "%s:%s" % (expand_path(working_dir, host_path), container_path)
|
||||||
|
else:
|
||||||
|
return container_path
|
||||||
|
|
||||||
|
|
||||||
|
def merge_volumes(base, override):
|
||||||
|
d = dict_from_volumes(base)
|
||||||
|
d.update(dict_from_volumes(override))
|
||||||
|
return volumes_from_dict(d)
|
||||||
|
|
||||||
|
|
||||||
|
def dict_from_volumes(volumes):
|
||||||
|
return dict(split_volume(v) for v in volumes)
|
||||||
|
|
||||||
|
|
||||||
|
def split_volume(volume):
|
||||||
|
if ':' in volume:
|
||||||
|
return reversed(volume.split(':', 1))
|
||||||
|
else:
|
||||||
|
return (volume, None)
|
||||||
|
|
||||||
|
|
||||||
|
def volumes_from_dict(d):
|
||||||
|
return ["%s:%s" % (host_path, container_path) for (container_path, host_path) in d.items()]
|
||||||
|
|
||||||
|
|
||||||
def expand_path(working_dir, path):
|
def expand_path(working_dir, path):
|
||||||
return os.path.abspath(os.path.join(working_dir, path))
|
return os.path.abspath(os.path.join(working_dir, path))
|
||||||
|
|
||||||
|
5
tests/fixtures/volume-path/common/services.yml
vendored
Normal file
5
tests/fixtures/volume-path/common/services.yml
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
db:
|
||||||
|
image: busybox
|
||||||
|
volumes:
|
||||||
|
- ./foo:/foo
|
||||||
|
- ./bar:/bar
|
6
tests/fixtures/volume-path/docker-compose.yml
vendored
Normal file
6
tests/fixtures/volume-path/docker-compose.yml
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
db:
|
||||||
|
extends:
|
||||||
|
file: common/services.yml
|
||||||
|
service: db
|
||||||
|
volumes:
|
||||||
|
- ./bar:/bar
|
@ -7,9 +7,7 @@ from .testcases import DockerClientTestCase
|
|||||||
|
|
||||||
class ProjectTest(DockerClientTestCase):
|
class ProjectTest(DockerClientTestCase):
|
||||||
def test_volumes_from_service(self):
|
def test_volumes_from_service(self):
|
||||||
project = Project.from_dicts(
|
service_dicts = config.from_dictionary({
|
||||||
name='composetest',
|
|
||||||
service_dicts=config.from_dictionary({
|
|
||||||
'data': {
|
'data': {
|
||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
'volumes': ['/var/data'],
|
'volumes': ['/var/data'],
|
||||||
@ -18,7 +16,10 @@ class ProjectTest(DockerClientTestCase):
|
|||||||
'image': 'busybox:latest',
|
'image': 'busybox:latest',
|
||||||
'volumes_from': ['data'],
|
'volumes_from': ['data'],
|
||||||
},
|
},
|
||||||
}),
|
}, working_dir='.')
|
||||||
|
project = Project.from_dicts(
|
||||||
|
name='composetest',
|
||||||
|
service_dicts=service_dicts,
|
||||||
client=self.client,
|
client=self.client,
|
||||||
)
|
)
|
||||||
db = project.get_service('db')
|
db = project.get_service('db')
|
||||||
|
@ -133,7 +133,6 @@ class EnvTest(unittest.TestCase):
|
|||||||
{'FILE_DEF': 'F1', 'FILE_DEF_EMPTY': '', 'ENV_DEF': 'E3', 'NO_DEF': ''},
|
{'FILE_DEF': 'F1', 'FILE_DEF_EMPTY': '', 'ENV_DEF': 'E3', 'NO_DEF': ''},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ExtendsTest(unittest.TestCase):
|
class ExtendsTest(unittest.TestCase):
|
||||||
def test_extends(self):
|
def test_extends(self):
|
||||||
service_dicts = config.load('tests/fixtures/extends/docker-compose.yml')
|
service_dicts = config.load('tests/fixtures/extends/docker-compose.yml')
|
||||||
@ -241,3 +240,13 @@ class ExtendsTest(unittest.TestCase):
|
|||||||
|
|
||||||
with mock.patch.object(config, 'load_yaml', return_value=other_config):
|
with mock.patch.object(config, 'load_yaml', return_value=other_config):
|
||||||
print load_config()
|
print load_config()
|
||||||
|
|
||||||
|
def test_volume_path(self):
|
||||||
|
dicts = config.load('tests/fixtures/volume-path/docker-compose.yml')
|
||||||
|
|
||||||
|
paths = [
|
||||||
|
'%s:/foo' % os.path.abspath('tests/fixtures/volume-path/common/foo'),
|
||||||
|
'%s:/bar' % os.path.abspath('tests/fixtures/volume-path/bar'),
|
||||||
|
]
|
||||||
|
|
||||||
|
self.assertEqual(set(dicts[0]['volumes']), set(paths))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user