diff --git a/docker/api/build.py b/docker/api/build.py index f62a7319af..3c3f130f98 100644 --- a/docker/api/build.py +++ b/docker/api/build.py @@ -341,4 +341,9 @@ def process_dockerfile(dockerfile, path): ) # Dockerfile is inside the context - return path relative to context root - return (os.path.relpath(abs_dockerfile, path), None) + if dockerfile == abs_dockerfile: + # Only calculate relpath if necessary to avoid errors + # on Windows client -> Linux Docker + # see https://github.com/docker/compose/issues/5969 + dockerfile = os.path.relpath(abs_dockerfile, path) + return (dockerfile, None) diff --git a/docker/api/plugin.py b/docker/api/plugin.py index 73f185251e..33d7419964 100644 --- a/docker/api/plugin.py +++ b/docker/api/plugin.py @@ -44,7 +44,10 @@ def create_plugin(self, name, plugin_data_dir, gzip=False): """ url = self._url('/plugins/create') - with utils.create_archive(root=plugin_data_dir, gzip=gzip) as archv: + with utils.create_archive( + root=plugin_data_dir, gzip=gzip, + files=set(utils.build.walk(plugin_data_dir, [])) + ) as archv: res = self._post(url, params={'name': name}, data=archv) self._raise_for_status(res) return True diff --git a/docker/types/daemon.py b/docker/types/daemon.py index 852f3d8292..ee8624e80a 100644 --- a/docker/types/daemon.py +++ b/docker/types/daemon.py @@ -57,6 +57,8 @@ def close(self): else: sock = sock_fp._sock + if isinstance(sock, urllib3.contrib.pyopenssl.WrappedSocket): + sock = sock.socket sock.shutdown(socket.SHUT_RDWR) sock.close() diff --git a/tests/integration/api_build_test.py b/tests/integration/api_build_test.py index 92e0062544..baaf33e3d9 100644 --- a/tests/integration/api_build_test.py +++ b/tests/integration/api_build_test.py @@ -415,18 +415,20 @@ def test_build_out_of_context_dockerfile(self): f.write('hello world') with open(os.path.join(base_dir, '.dockerignore'), 'w') as f: f.write('.dockerignore\n') - df = tempfile.NamedTemporaryFile() - self.addCleanup(df.close) - df.write(('\n'.join([ - 'FROM busybox', - 'COPY . /src', - 'WORKDIR /src', - ])).encode('utf-8')) - df.flush() + df_dir = tempfile.mkdtemp() + self.addCleanup(shutil.rmtree, df_dir) + df_name = os.path.join(df_dir, 'Dockerfile') + with open(df_name, 'wb') as df: + df.write(('\n'.join([ + 'FROM busybox', + 'COPY . /src', + 'WORKDIR /src', + ])).encode('utf-8')) + df.flush() img_name = random_name() self.tmp_imgs.append(img_name) stream = self.client.build( - path=base_dir, dockerfile=df.name, tag=img_name, + path=base_dir, dockerfile=df_name, tag=img_name, decode=True ) lines = [] @@ -472,6 +474,39 @@ def test_build_in_context_dockerfile(self): [b'.', b'..', b'file.txt', b'custom.dockerfile'] ) == sorted(lsdata) + def test_build_in_context_nested_dockerfile(self): + base_dir = tempfile.mkdtemp() + self.addCleanup(shutil.rmtree, base_dir) + with open(os.path.join(base_dir, 'file.txt'), 'w') as f: + f.write('hello world') + subdir = os.path.join(base_dir, 'hello', 'world') + os.makedirs(subdir) + with open(os.path.join(subdir, 'custom.dockerfile'), 'w') as df: + df.write('\n'.join([ + 'FROM busybox', + 'COPY . /src', + 'WORKDIR /src', + ])) + img_name = random_name() + self.tmp_imgs.append(img_name) + stream = self.client.build( + path=base_dir, dockerfile='hello/world/custom.dockerfile', + tag=img_name, decode=True + ) + lines = [] + for chunk in stream: + lines.append(chunk) + assert 'Successfully tagged' in lines[-1]['stream'] + + ctnr = self.client.create_container(img_name, 'ls -a') + self.tmp_containers.append(ctnr) + self.client.start(ctnr) + lsdata = self.client.logs(ctnr).strip().split(b'\n') + assert len(lsdata) == 4 + assert sorted( + [b'.', b'..', b'file.txt', b'hello'] + ) == sorted(lsdata) + def test_build_in_context_abs_dockerfile(self): base_dir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, base_dir) diff --git a/tests/integration/api_container_test.py b/tests/integration/api_container_test.py index afd439f9ce..ff7014879c 100644 --- a/tests/integration/api_container_test.py +++ b/tests/integration/api_container_test.py @@ -491,6 +491,9 @@ def test_create_with_device_cgroup_rules(self): assert rule in self.client.logs(ctnr).decode('utf-8') +@pytest.mark.xfail( + IS_WINDOWS_PLATFORM, reason='Test not designed for Windows platform' +) class VolumeBindTest(BaseAPIIntegrationTest): def setUp(self): super(VolumeBindTest, self).setUp() @@ -507,9 +510,6 @@ def setUp(self): ['touch', os.path.join(self.mount_dest, self.filename)], ) - @pytest.mark.xfail( - IS_WINDOWS_PLATFORM, reason='Test not designed for Windows platform' - ) def test_create_with_binds_rw(self): container = self.run_with_volume( @@ -525,9 +525,6 @@ def test_create_with_binds_rw(self): inspect_data = self.client.inspect_container(container) self.check_container_data(inspect_data, True) - @pytest.mark.xfail( - IS_WINDOWS_PLATFORM, reason='Test not designed for Windows platform' - ) def test_create_with_binds_ro(self): self.run_with_volume( False, @@ -548,9 +545,6 @@ def test_create_with_binds_ro(self): inspect_data = self.client.inspect_container(container) self.check_container_data(inspect_data, False) - @pytest.mark.xfail( - IS_WINDOWS_PLATFORM, reason='Test not designed for Windows platform' - ) @requires_api_version('1.30') def test_create_with_mounts(self): mount = docker.types.Mount( @@ -569,9 +563,6 @@ def test_create_with_mounts(self): inspect_data = self.client.inspect_container(container) self.check_container_data(inspect_data, True) - @pytest.mark.xfail( - IS_WINDOWS_PLATFORM, reason='Test not designed for Windows platform' - ) @requires_api_version('1.30') def test_create_with_mounts_ro(self): mount = docker.types.Mount( @@ -1116,9 +1107,7 @@ def test_top(self): self.client.start(container) res = self.client.top(container) - if IS_WINDOWS_PLATFORM: - assert res['Titles'] == ['PID', 'USER', 'TIME', 'COMMAND'] - else: + if not IS_WINDOWS_PLATFORM: assert res['Titles'] == [ 'UID', 'PID', 'PPID', 'C', 'STIME', 'TTY', 'TIME', 'CMD' ] diff --git a/tests/integration/api_plugin_test.py b/tests/integration/api_plugin_test.py index 433d44d101..1150b0957a 100644 --- a/tests/integration/api_plugin_test.py +++ b/tests/integration/api_plugin_test.py @@ -135,7 +135,7 @@ def test_upgrade_plugin(self): def test_create_plugin(self): plugin_data_dir = os.path.join( - os.path.dirname(__file__), 'testdata/dummy-plugin' + os.path.dirname(__file__), os.path.join('testdata', 'dummy-plugin') ) assert self.client.create_plugin( 'docker-sdk-py/dummy', plugin_data_dir diff --git a/tests/integration/models_containers_test.py b/tests/integration/models_containers_test.py index 6ddb034b41..ab41ea57de 100644 --- a/tests/integration/models_containers_test.py +++ b/tests/integration/models_containers_test.py @@ -36,6 +36,9 @@ def test_run_with_image_that_does_not_exist(self): with pytest.raises(docker.errors.ImageNotFound): client.containers.run("dockerpytest_does_not_exist") + @pytest.mark.skipif( + docker.constants.IS_WINDOWS_PLATFORM, reason="host mounts on Windows" + ) def test_run_with_volume(self): client = docker.from_env(version=TEST_API_VERSION) path = tempfile.mkdtemp()