From cbd2ba52af076219198a002533ac75fcd75a1ca3 Mon Sep 17 00:00:00 2001 From: Sebastian Schwarz Date: Wed, 10 Feb 2016 13:31:46 +0100 Subject: [PATCH 1/2] Synthesize executable bit on Windows The build context is tarred up on the client and then sent to the Docker daemon. However Windows permissions don't match the Unix ones. Therefore we have to mark all files as executable when creating a build context on Windows, like `docker build` already does: https://github.com/docker/docker/issues/11047. Signed-off-by: Sebastian Schwarz --- docker/utils/utils.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docker/utils/utils.py b/docker/utils/utils.py index d46f8fcd..62e06a2d 100644 --- a/docker/utils/utils.py +++ b/docker/utils/utils.py @@ -4,6 +4,7 @@ import os import os.path import json import shlex +import sys import tarfile import tempfile import warnings @@ -92,7 +93,10 @@ def tar(path, exclude=None, dockerfile=None, fileobj=None, gzip=False): exclude = exclude or [] for path in sorted(exclude_paths(root, exclude, dockerfile=dockerfile)): - t.add(os.path.join(root, path), arcname=path, recursive=False) + i = t.gettarinfo(os.path.join(root, path), arcname=path) + if sys.platform == 'win32': + i.mode = i.mode & 0o755 | 0o111 + t.addfile(i) t.close() fileobj.seek(0) From a718ab690e3b97c5c9ae4a9697ed2511f4c6f7dd Mon Sep 17 00:00:00 2001 From: Christian Bundy Date: Tue, 27 Sep 2016 00:56:12 +0000 Subject: [PATCH 2/2] Pass file object to Tarfile.addfile() This resolves an issue where TarFile.gettarinfo() doesn't include the file object, meaning that TarFile.addfile(TarFile.gettarinfo()) doesn't pass the test suite. Instead, this uses an open() within a try...except block to include a file object for each file without passing a file object when the path is a directory. Signed-off-by: Christian Bundy --- docker/utils/utils.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/docker/utils/utils.py b/docker/utils/utils.py index 62e06a2d..b565732d 100644 --- a/docker/utils/utils.py +++ b/docker/utils/utils.py @@ -94,9 +94,20 @@ def tar(path, exclude=None, dockerfile=None, fileobj=None, gzip=False): for path in sorted(exclude_paths(root, exclude, dockerfile=dockerfile)): i = t.gettarinfo(os.path.join(root, path), arcname=path) + if sys.platform == 'win32': + # Windows doesn't keep track of the execute bit, so we make files + # and directories executable by default. i.mode = i.mode & 0o755 | 0o111 - t.addfile(i) + + try: + # We open the file object in binary mode for Windows support. + f = open(os.path.join(root, path), 'rb') + except IOError: + # When we encounter a directory the file object is set to None. + f = None + + t.addfile(i, f) t.close() fileobj.seek(0)