From 002505084710d96bc7c16a7c984ed02e10e475c8 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Mon, 18 Dec 2017 12:35:59 -0800 Subject: [PATCH] Convert mounts to legacy volumes if API version < 1.30 Signed-off-by: Joffrey F --- compose/service.py | 65 ++++++++++++++++++------------- tests/integration/service_test.py | 18 +++++++++ 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/compose/service.py b/compose/service.py index f51f0e5af..fbab9281f 100644 --- a/compose/service.py +++ b/compose/service.py @@ -785,34 +785,9 @@ class Service(object): self.options.get('labels'), override_options.get('labels')) - container_volumes = [] - container_mounts = [] - if 'volumes' in container_options: - container_volumes = [ - v for v in container_options.get('volumes') if isinstance(v, VolumeSpec) - ] - container_mounts = [v for v in container_options.get('volumes') if isinstance(v, MountSpec)] - - binds, affinity = merge_volume_bindings( - container_volumes, self.options.get('tmpfs') or [], previous_container, - container_mounts + container_options, override_options = self._build_container_volume_options( + previous_container, container_options, override_options ) - override_options['binds'] = binds - container_options['environment'].update(affinity) - - container_options['volumes'] = dict((v.internal, {}) for v in container_volumes or {}) - override_options['mounts'] = [build_mount(v) for v in container_mounts] or None - - secret_volumes = self.get_secret_volumes() - if secret_volumes: - if version_lt(self.client.api_version, '1.30'): - override_options['binds'].extend(v.legacy_repr() for v in secret_volumes) - container_options['volumes'].update( - (v.target, {}) for v in secret_volumes - ) - else: - override_options['mounts'] = override_options.get('mounts') or [] - override_options['mounts'].extend([build_mount(v) for v in secret_volumes]) container_options['image'] = self.image_name @@ -838,6 +813,42 @@ class Service(object): container_options['environment']) return container_options + def _build_container_volume_options(self, previous_container, container_options, override_options): + container_volumes = [] + container_mounts = [] + if 'volumes' in container_options: + container_volumes = [ + v for v in container_options.get('volumes') if isinstance(v, VolumeSpec) + ] + container_mounts = [v for v in container_options.get('volumes') if isinstance(v, MountSpec)] + + binds, affinity = merge_volume_bindings( + container_volumes, self.options.get('tmpfs') or [], previous_container, + container_mounts + ) + override_options['binds'] = binds + container_options['environment'].update(affinity) + + container_options['volumes'] = dict((v.internal, {}) for v in container_volumes or {}) + if version_gte(self.client.api_version, '1.30'): + override_options['mounts'] = [build_mount(v) for v in container_mounts] or None + else: + override_options['binds'].extend(m.legacy_repr() for m in container_mounts) + container_options['volumes'].update((m.target, {}) for m in container_mounts) + + secret_volumes = self.get_secret_volumes() + if secret_volumes: + if version_lt(self.client.api_version, '1.30'): + override_options['binds'].extend(v.legacy_repr() for v in secret_volumes) + container_options['volumes'].update( + (v.target, {}) for v in secret_volumes + ) + else: + override_options['mounts'] = override_options.get('mounts') or [] + override_options['mounts'].extend([build_mount(v) for v in secret_volumes]) + + return container_options, override_options + def _get_container_host_config(self, override_options, one_off=False): options = dict(self.options, **override_options) diff --git a/tests/integration/service_test.py b/tests/integration/service_test.py index b9005b8e1..c1681a8de 100644 --- a/tests/integration/service_test.py +++ b/tests/integration/service_test.py @@ -13,6 +13,7 @@ from six import StringIO from six import text_type from .. import mock +from .testcases import docker_client from .testcases import DockerClientTestCase from .testcases import get_links from .testcases import pull_busybox @@ -326,6 +327,23 @@ class ServiceTest(DockerClientTestCase): assert mount assert mount['Name'] == volume_name + @v3_only() + def test_create_container_with_legacy_mount(self): + # Ensure mounts are converted to volumes if API version < 1.30 + # Needed to support long syntax in the 3.2 format + client = docker_client({}, version='1.25') + container_path = '/container-volume' + volume_name = 'composetest_abcde' + self.client.create_volume(volume_name) + service = Service('db', client=client, volumes=[ + MountSpec(type='volume', source=volume_name, target=container_path) + ], image='busybox:latest', command=['top'], project='composetest') + container = service.create_container() + service.start_container(container) + mount = container.get_mount(container_path) + assert mount + assert mount['Name'] == volume_name + def test_create_container_with_healthcheck_config(self): one_second = parse_nanoseconds_int('1s') healthcheck = {