Merge pull request #2126 from mnowster/1188-support-ro-options-in-volumes-from
1188 support ro options in volumes from
This commit is contained in:
commit
627f1acdc4
7 changed files with 105 additions and 34 deletions
|
|
@ -17,8 +17,10 @@ from .legacy import check_for_legacy_containers
|
|||
from .service import ContainerNet
|
||||
from .service import ConvergenceStrategy
|
||||
from .service import Net
|
||||
from .service import parse_volume_from_spec
|
||||
from .service import Service
|
||||
from .service import ServiceNet
|
||||
from .service import VolumeFromSpec
|
||||
from .utils import parallel_execute
|
||||
|
||||
|
||||
|
|
@ -34,12 +36,18 @@ def sort_service_dicts(services):
|
|||
def get_service_names(links):
|
||||
return [link.split(':')[0] for link in links]
|
||||
|
||||
def get_service_names_from_volumes_from(volumes_from):
|
||||
return [
|
||||
parse_volume_from_spec(volume_from).source
|
||||
for volume_from in volumes_from
|
||||
]
|
||||
|
||||
def get_service_dependents(service_dict, services):
|
||||
name = service_dict['name']
|
||||
return [
|
||||
service for service in services
|
||||
if (name in get_service_names(service.get('links', [])) or
|
||||
name in service.get('volumes_from', []) or
|
||||
name in get_service_names_from_volumes_from(service.get('volumes_from', [])) or
|
||||
name == get_service_name_from_net(service.get('net')))
|
||||
]
|
||||
|
||||
|
|
@ -176,20 +184,23 @@ class Project(object):
|
|||
def get_volumes_from(self, service_dict):
|
||||
volumes_from = []
|
||||
if 'volumes_from' in service_dict:
|
||||
for volume_name in service_dict.get('volumes_from', []):
|
||||
for volume_from_config in service_dict.get('volumes_from', []):
|
||||
volume_from_spec = parse_volume_from_spec(volume_from_config)
|
||||
# Get service
|
||||
try:
|
||||
service = self.get_service(volume_name)
|
||||
volumes_from.append(service)
|
||||
service_name = self.get_service(volume_from_spec.source)
|
||||
volume_from_spec = VolumeFromSpec(service_name, volume_from_spec.mode)
|
||||
except NoSuchService:
|
||||
try:
|
||||
container = Container.from_id(self.client, volume_name)
|
||||
volumes_from.append(container)
|
||||
container_name = Container.from_id(self.client, volume_from_spec.source)
|
||||
volume_from_spec = VolumeFromSpec(container_name, volume_from_spec.mode)
|
||||
except APIError:
|
||||
raise ConfigurationError(
|
||||
'Service "%s" mounts volumes from "%s", which is '
|
||||
'not the name of a service or container.' % (
|
||||
service_dict['name'],
|
||||
volume_name))
|
||||
volume_from_spec.source))
|
||||
volumes_from.append(volume_from_spec)
|
||||
del service_dict['volumes_from']
|
||||
return volumes_from
|
||||
|
||||
|
|
|
|||
|
|
@ -83,6 +83,9 @@ class NoSuchImageError(Exception):
|
|||
VolumeSpec = namedtuple('VolumeSpec', 'external internal mode')
|
||||
|
||||
|
||||
VolumeFromSpec = namedtuple('VolumeFromSpec', 'source mode')
|
||||
|
||||
|
||||
ServiceName = namedtuple('ServiceName', 'project service number')
|
||||
|
||||
|
||||
|
|
@ -520,7 +523,7 @@ class Service(object):
|
|||
return [(service.name, alias) for service, alias in self.links]
|
||||
|
||||
def get_volumes_from_names(self):
|
||||
return [s.name for s in self.volumes_from if isinstance(s, Service)]
|
||||
return [s.source.name for s in self.volumes_from if isinstance(s.source, Service)]
|
||||
|
||||
def get_container_name(self, number, one_off=False):
|
||||
# TODO: Implement issue #652 here
|
||||
|
|
@ -560,16 +563,9 @@ class Service(object):
|
|||
|
||||
def _get_volumes_from(self):
|
||||
volumes_from = []
|
||||
for volume_source in self.volumes_from:
|
||||
if isinstance(volume_source, Service):
|
||||
containers = volume_source.containers(stopped=True)
|
||||
if not containers:
|
||||
volumes_from.append(volume_source.create_container().id)
|
||||
else:
|
||||
volumes_from.extend(map(attrgetter('id'), containers))
|
||||
|
||||
elif isinstance(volume_source, Container):
|
||||
volumes_from.append(volume_source.id)
|
||||
for volume_from_spec in self.volumes_from:
|
||||
volumes = build_volume_from(volume_from_spec)
|
||||
volumes_from.extend(volumes)
|
||||
|
||||
return volumes_from
|
||||
|
||||
|
|
@ -989,6 +985,38 @@ def parse_volume_spec(volume_config):
|
|||
|
||||
return VolumeSpec(external, internal, mode)
|
||||
|
||||
|
||||
def build_volume_from(volume_from_spec):
|
||||
"""
|
||||
volume_from can be either a service or a container. We want to return the
|
||||
container.id and format it into a string complete with the mode.
|
||||
"""
|
||||
if isinstance(volume_from_spec.source, Service):
|
||||
containers = volume_from_spec.source.containers(stopped=True)
|
||||
if not containers:
|
||||
return ["{}:{}".format(volume_from_spec.source.create_container().id, volume_from_spec.mode)]
|
||||
|
||||
container = containers[0]
|
||||
return ["{}:{}".format(container.id, volume_from_spec.mode)]
|
||||
elif isinstance(volume_from_spec.source, Container):
|
||||
return ["{}:{}".format(volume_from_spec.source.id, volume_from_spec.mode)]
|
||||
|
||||
|
||||
def parse_volume_from_spec(volume_from_config):
|
||||
parts = volume_from_config.split(':')
|
||||
if len(parts) > 2:
|
||||
raise ConfigError("Volume %s has incorrect format, should be "
|
||||
"external:internal[:mode]" % volume_from_config)
|
||||
|
||||
if len(parts) == 1:
|
||||
source = parts[0]
|
||||
mode = 'rw'
|
||||
else:
|
||||
source, mode = parts
|
||||
|
||||
return VolumeFromSpec(source, mode)
|
||||
|
||||
|
||||
# Labels
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue