浏览代码

Convert mounts to legacy volumes if API version < 1.30

Signed-off-by: Joffrey F <[email protected]>
Joffrey F 7 年之前
父节点
当前提交
5a7ba590fb
共有 2 个文件被更改,包括 53 次插入24 次删除
  1. 35 24
      compose/service.py
  2. 18 0
      tests/integration/service_test.py

+ 35 - 24
compose/service.py

@@ -785,6 +785,35 @@ class Service(object):
             self.options.get('labels'),
             override_options.get('labels'))
 
+        container_options, override_options = self._build_container_volume_options(
+            previous_container, container_options, override_options
+        )
+
+        container_options['image'] = self.image_name
+
+        container_options['labels'] = build_container_labels(
+            container_options.get('labels', {}),
+            self.labels(one_off=one_off),
+            number,
+            self.config_hash if add_config_hash else None)
+
+        # Delete options which are only used in HostConfig
+        for key in HOST_CONFIG_KEYS:
+            container_options.pop(key, None)
+
+        container_options['host_config'] = self._get_container_host_config(
+            override_options,
+            one_off=one_off)
+
+        networking_config = self.build_default_networking_config()
+        if networking_config:
+            container_options['networking_config'] = networking_config
+
+        container_options['environment'] = format_environment(
+            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:
@@ -801,7 +830,11 @@ class Service(object):
         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
+        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:
@@ -814,29 +847,7 @@ class Service(object):
                 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
-
-        container_options['labels'] = build_container_labels(
-            container_options.get('labels', {}),
-            self.labels(one_off=one_off),
-            number,
-            self.config_hash if add_config_hash else None)
-
-        # Delete options which are only used in HostConfig
-        for key in HOST_CONFIG_KEYS:
-            container_options.pop(key, None)
-
-        container_options['host_config'] = self._get_container_host_config(
-            override_options,
-            one_off=one_off)
-
-        networking_config = self.build_default_networking_config()
-        if networking_config:
-            container_options['networking_config'] = networking_config
-
-        container_options['environment'] = format_environment(
-            container_options['environment'])
-        return container_options
+        return container_options, override_options
 
     def _get_container_host_config(self, override_options, one_off=False):
         options = dict(self.options, **override_options)

+ 18 - 0
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 = {