From a60011ca3a7142d28282b70d87708b6c66e85c51 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Thu, 1 Feb 2018 16:51:36 -0800 Subject: [PATCH 1/4] Add workaround for bpo-32713 Signed-off-by: Joffrey F --- docker/utils/utils.py | 4 ++++ tests/unit/utils_test.py | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/docker/utils/utils.py b/docker/utils/utils.py index e4e2c0df..b145f116 100644 --- a/docker/utils/utils.py +++ b/docker/utils/utils.py @@ -107,6 +107,10 @@ def create_archive(root, files=None, fileobj=None, gzip=False): # ignore it and proceed. continue + # Workaround https://bugs.python.org/issue32713 + if i.mtime < 0 or i.mtime > 8**11 - 1: + i.mtime = int(i.mtime) + if constants.IS_WINDOWS_PLATFORM: # Windows doesn't keep track of the execute bit, so we make files # and directories executable by default. diff --git a/tests/unit/utils_test.py b/tests/unit/utils_test.py index 1f9daf60..15588918 100644 --- a/tests/unit/utils_test.py +++ b/tests/unit/utils_test.py @@ -995,6 +995,18 @@ class TarTest(unittest.TestCase): tar_data = tarfile.open(fileobj=archive) assert sorted(tar_data.getnames()) == ['bar', 'foo'] + def tar_test_negative_mtime_bug(self): + base = tempfile.mkdtemp() + filename = os.path.join(base, 'th.txt') + self.addCleanup(shutil.rmtree, base) + with open(filename, 'w') as f: + f.write('Invisible Full Moon') + os.utime(filename, (12345, -3600.0)) + with tar(base) as archive: + tar_data = tarfile.open(fileobj=archive) + assert tar_data.getnames() == ['th.txt'] + assert tar_data.getmember('th.txt').mtime == -3600 + class ShouldCheckDirectoryTest(unittest.TestCase): exclude_patterns = [ From 539b321bd1dfc5cbbba4c1573cd46adb0f47a3f1 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Thu, 1 Feb 2018 16:02:09 -0800 Subject: [PATCH 2/4] Add login data to the right subdict in auth_configs Signed-off-by: Joffrey F --- docker/api/daemon.py | 2 +- tests/unit/api_test.py | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/docker/api/daemon.py b/docker/api/daemon.py index 033dbf19..0e1c7538 100644 --- a/docker/api/daemon.py +++ b/docker/api/daemon.py @@ -139,7 +139,7 @@ class DaemonApiMixin(object): if response.status_code == 200: if 'auths' not in self._auth_configs: self._auth_configs['auths'] = {} - self._auth_configs[registry or auth.INDEX_NAME] = req_data + self._auth_configs['auths'][registry or auth.INDEX_NAME] = req_data return self._result(response, json=True) def ping(self): diff --git a/tests/unit/api_test.py b/tests/unit/api_test.py index c53a4be1..f65e13ec 100644 --- a/tests/unit/api_test.py +++ b/tests/unit/api_test.py @@ -212,6 +212,24 @@ class DockerApiTest(BaseAPIClientTest): timeout=DEFAULT_TIMEOUT_SECONDS ) + def test_login(self): + self.client.login('sakuya', 'izayoi') + fake_request.assert_called_with( + 'POST', url_prefix + 'auth', + data=json.dumps({'username': 'sakuya', 'password': 'izayoi'}), + timeout=DEFAULT_TIMEOUT_SECONDS, + headers={'Content-Type': 'application/json'} + ) + + assert self.client._auth_configs['auths'] == { + 'docker.io': { + 'email': None, + 'password': 'izayoi', + 'username': 'sakuya', + 'serveraddress': None, + } + } + def test_events(self): self.client.events() From 6de7bab22fc339c7e38cc89732a3a05ab3a94eda Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Mon, 5 Feb 2018 13:11:19 -0800 Subject: [PATCH 3/4] Rewrite access check in create_archive with EAFP Signed-off-by: Joffrey F --- docker/utils/utils.py | 8 +++----- tests/unit/utils_test.py | 8 ++++++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docker/utils/utils.py b/docker/utils/utils.py index b145f116..3cd2be81 100644 --- a/docker/utils/utils.py +++ b/docker/utils/utils.py @@ -97,10 +97,6 @@ def create_archive(root, files=None, fileobj=None, gzip=False): for path in files: full_path = os.path.join(root, path) - if os.lstat(full_path).st_mode & os.R_OK == 0: - raise IOError( - 'Can not access file in context: {}'.format(full_path) - ) i = t.gettarinfo(full_path, arcname=path) if i is None: # This happens when we encounter a socket file. We can safely @@ -121,7 +117,9 @@ def create_archive(root, files=None, fileobj=None, gzip=False): with open(full_path, 'rb') as f: t.addfile(i, f) except IOError: - t.addfile(i, None) + raise IOError( + 'Can not read file in context: {}'.format(full_path) + ) else: # Directories, FIFOs, symlinks... don't need to be read. t.addfile(i, None) diff --git a/tests/unit/utils_test.py b/tests/unit/utils_test.py index 15588918..eedcf71a 100644 --- a/tests/unit/utils_test.py +++ b/tests/unit/utils_test.py @@ -933,7 +933,10 @@ class TarTest(unittest.TestCase): tar_data = tarfile.open(fileobj=archive) assert sorted(tar_data.getnames()) == ['bar', 'foo'] - @pytest.mark.skipif(IS_WINDOWS_PLATFORM, reason='No chmod on Windows') + @pytest.mark.skipif( + IS_WINDOWS_PLATFORM or os.geteuid() == 0, + reason='root user always has access ; no chmod on Windows' + ) def test_tar_with_inaccessible_file(self): base = tempfile.mkdtemp() full_path = os.path.join(base, 'foo') @@ -944,8 +947,9 @@ class TarTest(unittest.TestCase): with pytest.raises(IOError) as ei: tar(base) - assert 'Can not access file in context: {}'.format(full_path) in \ + assert 'Can not read file in context: {}'.format(full_path) in ( ei.exconly() + ) @pytest.mark.skipif(IS_WINDOWS_PLATFORM, reason='No symlinks on Windows') def test_tar_with_file_symlinks(self): From 8649f48a4c2bc89e271b09d17a3e61866a1ead1c Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Mon, 5 Feb 2018 13:44:57 -0800 Subject: [PATCH 4/4] Bump 3.0.1 Signed-off-by: Joffrey F --- docker/version.py | 2 +- docs/change-log.md | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/docker/version.py b/docker/version.py index f141747a..635e84cb 100644 --- a/docker/version.py +++ b/docker/version.py @@ -1,2 +1,2 @@ -version = "3.0.0" +version = "3.0.1" version_info = tuple([int(d) for d in version.split("-")[0].split(".")]) diff --git a/docs/change-log.md b/docs/change-log.md index 08d4e8f7..8ae88ef2 100644 --- a/docs/change-log.md +++ b/docs/change-log.md @@ -1,6 +1,20 @@ Change log ========== +3.0.1 +----- + +[List of PRs / issues for this release](https://github.com/docker/docker-py/milestone/43?closed=1) + +### Bugfixes + +* Fixed a bug where `APIClient.login` didn't populate the `_auth_configs` + dictionary properly, causing subsequent `pull` and `push` operations to fail +* Fixed a bug where some build context files were incorrectly recognized as + being inaccessible. +* Fixed a bug where files with a negative mtime value would + cause errors when included in a build context + 3.0.0 -----