Merge pull request #1787 from aanand/fix-duplicate-volume-bind

Fix "Duplicate volume mount" error when config has trailing slashes
(cherry picked from commit dc7bdd10d4)

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
This commit is contained in:
Aanand Prasad 2015-07-30 09:59:08 +01:00
parent 49bafdc4cd
commit ad922cd7a1
2 changed files with 42 additions and 4 deletions

View File

@ -3,6 +3,7 @@ from __future__ import absolute_import
from collections import namedtuple from collections import namedtuple
import logging import logging
import re import re
import os
import sys import sys
from operator import attrgetter from operator import attrgetter
@ -848,12 +849,15 @@ def parse_volume_spec(volume_config):
"external:internal[:mode]" % volume_config) "external:internal[:mode]" % volume_config)
if len(parts) == 1: if len(parts) == 1:
return VolumeSpec(None, parts[0], 'rw') external = None
internal = os.path.normpath(parts[0])
else:
external = os.path.normpath(parts[0])
internal = os.path.normpath(parts[1])
if len(parts) == 2: mode = parts[2] if len(parts) == 3 else 'rw'
parts.append('rw')
return VolumeSpec(*parts) return VolumeSpec(external, internal, mode)
# Ports # Ports

View File

@ -221,6 +221,40 @@ class ServiceTest(DockerClientTestCase):
self.assertTrue(path.basename(actual_host_path) == path.basename(host_path), self.assertTrue(path.basename(actual_host_path) == path.basename(host_path),
msg=("Last component differs: %s, %s" % (actual_host_path, host_path))) msg=("Last component differs: %s, %s" % (actual_host_path, host_path)))
def test_duplicate_volume_trailing_slash(self):
"""
When an image specifies a volume, and the Compose file specifies a host path
but adds a trailing slash, make sure that we don't create duplicate binds.
"""
host_path = '/tmp/data'
container_path = '/data'
volumes = ['{}:{}/'.format(host_path, container_path)]
tmp_container = self.client.create_container(
'busybox', 'true',
volumes={container_path: {}},
labels={'com.docker.compose.test_image': 'true'},
)
image = self.client.commit(tmp_container)['Id']
service = self.create_service('db', image=image, volumes=volumes)
old_container = create_and_start_container(service)
self.assertEqual(
old_container.get('Config.Volumes'),
{container_path: {}},
)
service = self.create_service('db', image=image, volumes=volumes)
new_container = service.recreate_container(old_container)
self.assertEqual(
new_container.get('Config.Volumes'),
{container_path: {}},
)
self.assertEqual(service.containers(stopped=False), [new_container])
@patch.dict(os.environ) @patch.dict(os.environ)
def test_create_container_with_home_and_env_var_in_volume_path(self): def test_create_container_with_home_and_env_var_in_volume_path(self):
os.environ['VOLUME_NAME'] = 'my-volume' os.environ['VOLUME_NAME'] = 'my-volume'