Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't convert slashes for UNIX paths on Windows hosts #6204

Merged
merged 1 commit into from
Sep 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions compose/config/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,20 @@ def normalize_path_for_engine(path):
return path.replace('\\', '/')


def normpath(path, win_host=False):
""" Custom path normalizer that handles Compose-specific edge cases like
UNIX paths on Windows hosts and vice-versa. """

sysnorm = ntpath.normpath if win_host else os.path.normpath
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be:

-sysnorm = ntpath.normpath if win_host else os.path.normpath
+sysnorm = ntpath.normpath if win_host else posix.normpath

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

win_host will be true only if COMPOSE_FORCE_WINDOWS_HOST is set. In this case we want to produce NT style paths regardless of the client platform. In all other cases, we want to use the default normalization for the client system, hence the use of os.path.normpath

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we? If you have a compose on Windows talking to a remote linux engine?

# If a path looks like a UNIX absolute path on Windows, it probably is;
# we'll need to revert the backslashes to forward slashes after normalization
flip_slashes = path.startswith('/') and IS_WINDOWS_PLATFORM
path = sysnorm(path)
if flip_slashes:
path = path.replace('\\', '/')
return path


class MountSpec(object):
options_map = {
'volume': {
Expand All @@ -152,12 +166,11 @@ class MountSpec(object):

@classmethod
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['type'] == 'tmpfs':
raise ConfigurationError('tmpfs mounts can not specify a source')

mount_dict['source'] = normpath(mount_dict['source'])
mount_dict['source'] = normpath(mount_dict['source'], win_host)
if normalize:
mount_dict['source'] = normalize_path_for_engine(mount_dict['source'])

Expand Down Expand Up @@ -247,7 +260,7 @@ def separate_next_section(volume_config):
else:
external = parts[0]
parts = separate_next_section(parts[1])
external = ntpath.normpath(external)
external = normpath(external, True)
internal = parts[0]
if len(parts) > 1:
if ':' in parts[1]:
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/config/config_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1291,7 +1291,7 @@ def test_volumes_long_syntax(self):
assert tmpfs_mount.target == '/tmpfs'
assert not tmpfs_mount.is_named_volume

assert host_mount.source == os.path.normpath('/abc')
assert host_mount.source == '/abc'
assert host_mount.target == '/xyz'
assert not host_mount.is_named_volume

Expand Down