Merge pull request #5560 from docker/5371-force-windows-volume-parsing

Add environment variable to force windows parsing style of volume paths
This commit is contained in:
Joffrey F 2018-01-17 12:01:47 -08:00 committed by GitHub
commit 98044349a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 9 deletions

View File

@ -815,11 +815,12 @@ def finalize_service_volumes(service_dict, environment):
if 'volumes' in service_dict: if 'volumes' in service_dict:
finalized_volumes = [] finalized_volumes = []
normalize = environment.get_boolean('COMPOSE_CONVERT_WINDOWS_PATHS') normalize = environment.get_boolean('COMPOSE_CONVERT_WINDOWS_PATHS')
win_host = environment.get_boolean('COMPOSE_FORCE_WINDOWS_HOST')
for v in service_dict['volumes']: for v in service_dict['volumes']:
if isinstance(v, dict): if isinstance(v, dict):
finalized_volumes.append(MountSpec.parse(v, normalize)) finalized_volumes.append(MountSpec.parse(v, normalize, win_host))
else: else:
finalized_volumes.append(VolumeSpec.parse(v, normalize)) finalized_volumes.append(VolumeSpec.parse(v, normalize, win_host))
service_dict['volumes'] = finalized_volumes service_dict['volumes'] = finalized_volumes
return service_dict return service_dict

View File

@ -4,6 +4,7 @@ Types for objects parsed from the configuration.
from __future__ import absolute_import from __future__ import absolute_import
from __future__ import unicode_literals from __future__ import unicode_literals
import ntpath
import os import os
import re import re
from collections import namedtuple from collections import namedtuple
@ -145,9 +146,10 @@ class MountSpec(object):
_fields = ['type', 'source', 'target', 'read_only', 'consistency'] _fields = ['type', 'source', 'target', 'read_only', 'consistency']
@classmethod @classmethod
def parse(cls, mount_dict, normalize=False): def parse(cls, mount_dict, normalize=False, win_host=False):
normpath = ntpath.normpath if win_host else os.path.normpath
if mount_dict.get('source'): if mount_dict.get('source'):
mount_dict['source'] = os.path.normpath(mount_dict['source']) mount_dict['source'] = normpath(mount_dict['source'])
if normalize: if normalize:
mount_dict['source'] = normalize_path_for_engine(mount_dict['source']) mount_dict['source'] = normalize_path_for_engine(mount_dict['source'])
@ -193,6 +195,7 @@ class MountSpec(object):
class VolumeSpec(namedtuple('_VolumeSpec', 'external internal mode')): class VolumeSpec(namedtuple('_VolumeSpec', 'external internal mode')):
win32 = False
@classmethod @classmethod
def _parse_unix(cls, volume_config): def _parse_unix(cls, volume_config):
@ -236,7 +239,7 @@ class VolumeSpec(namedtuple('_VolumeSpec', 'external internal mode')):
else: else:
external = parts[0] external = parts[0]
parts = separate_next_section(parts[1]) parts = separate_next_section(parts[1])
external = os.path.normpath(external) external = ntpath.normpath(external)
internal = parts[0] internal = parts[0]
if len(parts) > 1: if len(parts) > 1:
if ':' in parts[1]: if ':' in parts[1]:
@ -249,14 +252,16 @@ class VolumeSpec(namedtuple('_VolumeSpec', 'external internal mode')):
if normalize: if normalize:
external = normalize_path_for_engine(external) if external else None external = normalize_path_for_engine(external) if external else None
return cls(external, internal, mode) result = cls(external, internal, mode)
result.win32 = True
return result
@classmethod @classmethod
def parse(cls, volume_config, normalize=False): def parse(cls, volume_config, normalize=False, win_host=False):
"""Parse a volume_config path and split it into external:internal[:mode] """Parse a volume_config path and split it into external:internal[:mode]
parts to be returned as a valid VolumeSpec. parts to be returned as a valid VolumeSpec.
""" """
if IS_WINDOWS_PLATFORM: if IS_WINDOWS_PLATFORM or win_host:
return cls._parse_win32(volume_config, normalize) return cls._parse_win32(volume_config, normalize)
else: else:
return cls._parse_unix(volume_config) return cls._parse_unix(volume_config)
@ -269,7 +274,7 @@ class VolumeSpec(namedtuple('_VolumeSpec', 'external internal mode')):
@property @property
def is_named_volume(self): def is_named_volume(self):
res = self.external and not self.external.startswith(('.', '/', '~')) res = self.external and not self.external.startswith(('.', '/', '~'))
if not IS_WINDOWS_PLATFORM: if not self.win32:
return res return res
return ( return (