mirror of https://github.com/docker/compose.git
Prevent duplicate binds in generated container config
Signed-off-by: Joffrey F <joffrey@docker.com>
This commit is contained in:
parent
9f42fac2bb
commit
aecc0de28f
|
@ -877,7 +877,6 @@ class Service(object):
|
||||||
container_volumes, self.options.get('tmpfs') or [], previous_container,
|
container_volumes, self.options.get('tmpfs') or [], previous_container,
|
||||||
container_mounts
|
container_mounts
|
||||||
)
|
)
|
||||||
override_options['binds'] = binds
|
|
||||||
container_options['environment'].update(affinity)
|
container_options['environment'].update(affinity)
|
||||||
|
|
||||||
container_options['volumes'] = dict((v.internal, {}) for v in container_volumes or {})
|
container_options['volumes'] = dict((v.internal, {}) for v in container_volumes or {})
|
||||||
|
@ -890,13 +889,13 @@ class Service(object):
|
||||||
if m.is_tmpfs:
|
if m.is_tmpfs:
|
||||||
override_options['tmpfs'].append(m.target)
|
override_options['tmpfs'].append(m.target)
|
||||||
else:
|
else:
|
||||||
override_options['binds'].append(m.legacy_repr())
|
binds.append(m.legacy_repr())
|
||||||
container_options['volumes'][m.target] = {}
|
container_options['volumes'][m.target] = {}
|
||||||
|
|
||||||
secret_volumes = self.get_secret_volumes()
|
secret_volumes = self.get_secret_volumes()
|
||||||
if secret_volumes:
|
if secret_volumes:
|
||||||
if version_lt(self.client.api_version, '1.30'):
|
if version_lt(self.client.api_version, '1.30'):
|
||||||
override_options['binds'].extend(v.legacy_repr() for v in secret_volumes)
|
binds.extend(v.legacy_repr() for v in secret_volumes)
|
||||||
container_options['volumes'].update(
|
container_options['volumes'].update(
|
||||||
(v.target, {}) for v in secret_volumes
|
(v.target, {}) for v in secret_volumes
|
||||||
)
|
)
|
||||||
|
@ -904,6 +903,8 @@ class Service(object):
|
||||||
override_options['mounts'] = override_options.get('mounts') or []
|
override_options['mounts'] = override_options.get('mounts') or []
|
||||||
override_options['mounts'].extend([build_mount(v) for v in secret_volumes])
|
override_options['mounts'].extend([build_mount(v) for v in secret_volumes])
|
||||||
|
|
||||||
|
# Remove possible duplicates (see e.g. https://github.com/docker/compose/issues/5885)
|
||||||
|
override_options['binds'] = list(set(binds))
|
||||||
return container_options, override_options
|
return container_options, override_options
|
||||||
|
|
||||||
def _get_container_host_config(self, override_options, one_off=False):
|
def _get_container_host_config(self, override_options, one_off=False):
|
||||||
|
|
|
@ -10,6 +10,7 @@ from docker.errors import NotFound
|
||||||
from .. import mock
|
from .. import mock
|
||||||
from .. import unittest
|
from .. import unittest
|
||||||
from compose.config.errors import DependencyError
|
from compose.config.errors import DependencyError
|
||||||
|
from compose.config.types import MountSpec
|
||||||
from compose.config.types import ServicePort
|
from compose.config.types import ServicePort
|
||||||
from compose.config.types import ServiceSecret
|
from compose.config.types import ServiceSecret
|
||||||
from compose.config.types import VolumeFromSpec
|
from compose.config.types import VolumeFromSpec
|
||||||
|
@ -955,6 +956,24 @@ class ServiceTest(unittest.TestCase):
|
||||||
|
|
||||||
assert service.create_container().id == 'new_cont_id'
|
assert service.create_container().id == 'new_cont_id'
|
||||||
|
|
||||||
|
def test_build_volume_options_duplicate_binds(self):
|
||||||
|
self.mock_client.api_version = '1.29' # Trigger 3.2 format workaround
|
||||||
|
service = Service('foo', client=self.mock_client)
|
||||||
|
ctnr_opts, override_opts = service._build_container_volume_options(
|
||||||
|
previous_container=None,
|
||||||
|
container_options={
|
||||||
|
'volumes': [
|
||||||
|
MountSpec.parse({'source': 'vol', 'target': '/data', 'type': 'volume'}),
|
||||||
|
VolumeSpec.parse('vol:/data:rw'),
|
||||||
|
],
|
||||||
|
'environment': {},
|
||||||
|
},
|
||||||
|
override_options={},
|
||||||
|
)
|
||||||
|
assert 'binds' in override_opts
|
||||||
|
assert len(override_opts['binds']) == 1
|
||||||
|
assert override_opts['binds'][0] == 'vol:/data:rw'
|
||||||
|
|
||||||
|
|
||||||
class TestServiceNetwork(unittest.TestCase):
|
class TestServiceNetwork(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
Loading…
Reference in New Issue