From 2494d63f36eba0e1811f05e7b2136f8b30f7cdb7 Mon Sep 17 00:00:00 2001 From: Milas Bowman Date: Thu, 18 Aug 2022 17:03:32 -0400 Subject: [PATCH 1/5] docs: install package in ReadTheDocs build (#3032) Need to install ourselves so that we can introspect on version using `setuptools_scm` in `docs/conf.py`. Signed-off-by: Milas Bowman --- .readthedocs.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 464c782604..80000ee7f1 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -4,11 +4,14 @@ sphinx: configuration: docs/conf.py build: - os: ubuntu-20.04 - tools: - python: '3.10' + os: ubuntu-20.04 + tools: + python: '3.10' python: install: - requirements: docs-requirements.txt - - requirements: requirements.txt + - method: pip + path: . + extra_requirements: + - ssh From 1c27ec1f0c34f6b9510f5caadada5fd8ecc430d9 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 19 Aug 2022 21:09:12 +0200 Subject: [PATCH 2/5] ci: use latest stable syntax for Dockerfiles (#3035) I noticed one Dockerfile was pinned to 1.4; given that there's a backward compatibility guarantee on the stable syntax, the general recommendation is to use `dockerfile:1`, which makes sure that the latest stable release of the Dockerfile syntax is pulled before building. While changing, I also made some minor changes to some Dockerfiles to reduce some unneeded layers. Signed-off-by: Sebastiaan van Stijn --- Dockerfile | 2 ++ Dockerfile-docs | 2 ++ tests/Dockerfile | 4 +++- tests/Dockerfile-dind-certs | 2 ++ tests/Dockerfile-ssh-dind | 10 ++++++---- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index ef9b886cd4..3476c6d036 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + ARG PYTHON_VERSION=3.10 FROM python:${PYTHON_VERSION} diff --git a/Dockerfile-docs b/Dockerfile-docs index e993822b85..11adbfe85d 100644 --- a/Dockerfile-docs +++ b/Dockerfile-docs @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + ARG PYTHON_VERSION=3.10 FROM python:${PYTHON_VERSION} diff --git a/tests/Dockerfile b/tests/Dockerfile index 2cac785d9d..bf95cd6a3c 100644 --- a/tests/Dockerfile +++ b/tests/Dockerfile @@ -1,5 +1,7 @@ -# syntax = docker/dockerfile:1.4 +# syntax=docker/dockerfile:1 + ARG PYTHON_VERSION=3.10 + FROM python:${PYTHON_VERSION} ARG APT_MIRROR diff --git a/tests/Dockerfile-dind-certs b/tests/Dockerfile-dind-certs index 6e711892ca..288a340ab1 100644 --- a/tests/Dockerfile-dind-certs +++ b/tests/Dockerfile-dind-certs @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + ARG PYTHON_VERSION=3.10 FROM python:${PYTHON_VERSION} diff --git a/tests/Dockerfile-ssh-dind b/tests/Dockerfile-ssh-dind index 22c707a075..0da15aa40f 100644 --- a/tests/Dockerfile-ssh-dind +++ b/tests/Dockerfile-ssh-dind @@ -1,18 +1,20 @@ +# syntax=docker/dockerfile:1 + ARG API_VERSION=1.41 ARG ENGINE_VERSION=20.10 FROM docker:${ENGINE_VERSION}-dind RUN apk add --no-cache --upgrade \ - openssh + openssh COPY tests/ssh/config/server /etc/ssh/ -RUN chmod -R 600 /etc/ssh # set authorized keys for client paswordless connection COPY tests/ssh/config/client/id_rsa.pub /root/.ssh/authorized_keys -RUN chmod -R 600 /root/.ssh # RUN echo "root:root" | chpasswd -RUN ln -s /usr/local/bin/docker /usr/bin/docker +RUN chmod -R 600 /etc/ssh \ + && chmod -R 600 /root/.ssh \ + && ln -s /usr/local/bin/docker /usr/bin/docker EXPOSE 22 From 923e067dddc3d4b86e4e620a99fcdcdafbd17a98 Mon Sep 17 00:00:00 2001 From: Rhiza <6900588+ArchiMoebius@users.noreply.github.com> Date: Fri, 19 Aug 2022 15:10:53 -0400 Subject: [PATCH 3/5] api: add support for floats to docker logs params since / until (#3031) Add support for floats to docker logs params `since` / `until` since the Docker Engine APIs support it. This allows using fractional seconds for greater precision. Signed-off-by: Archi Moebius --- docker/api/container.py | 17 +++++++++++------ docker/models/containers.py | 9 +++++---- tests/unit/api_container_test.py | 18 +++++++++++++++++- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/docker/api/container.py b/docker/api/container.py index f600be1811..ce483710cb 100644 --- a/docker/api/container.py +++ b/docker/api/container.py @@ -826,11 +826,12 @@ def logs(self, container, stdout=True, stderr=True, stream=False, tail (str or int): Output specified number of lines at the end of logs. Either an integer of number of lines or the string ``all``. Default ``all`` - since (datetime or int): Show logs since a given datetime or - integer epoch (in seconds) + since (datetime, int, or float): Show logs since a given datetime, + integer epoch (in seconds) or float (in fractional seconds) follow (bool): Follow log output. Default ``False`` - until (datetime or int): Show logs that occurred before the given - datetime or integer epoch (in seconds) + until (datetime, int, or float): Show logs that occurred before + the given datetime, integer epoch (in seconds), or + float (in fractional seconds) Returns: (generator or str) @@ -855,9 +856,11 @@ def logs(self, container, stdout=True, stderr=True, stream=False, params['since'] = utils.datetime_to_timestamp(since) elif (isinstance(since, int) and since > 0): params['since'] = since + elif (isinstance(since, float) and since > 0.0): + params['since'] = since else: raise errors.InvalidArgument( - 'since value should be datetime or positive int, ' + 'since value should be datetime or positive int/float, ' 'not {}'.format(type(since)) ) @@ -870,9 +873,11 @@ def logs(self, container, stdout=True, stderr=True, stream=False, params['until'] = utils.datetime_to_timestamp(until) elif (isinstance(until, int) and until > 0): params['until'] = until + elif (isinstance(until, float) and until > 0.0): + params['until'] = until else: raise errors.InvalidArgument( - 'until value should be datetime or positive int, ' + 'until value should be datetime or positive int/float, ' 'not {}'.format(type(until)) ) diff --git a/docker/models/containers.py b/docker/models/containers.py index 6661b213bf..4508557d28 100644 --- a/docker/models/containers.py +++ b/docker/models/containers.py @@ -290,11 +290,12 @@ def logs(self, **kwargs): tail (str or int): Output specified number of lines at the end of logs. Either an integer of number of lines or the string ``all``. Default ``all`` - since (datetime or int): Show logs since a given datetime or - integer epoch (in seconds) + since (datetime, int, or float): Show logs since a given datetime, + integer epoch (in seconds) or float (in nanoseconds) follow (bool): Follow log output. Default ``False`` - until (datetime or int): Show logs that occurred before the given - datetime or integer epoch (in seconds) + until (datetime, int, or float): Show logs that occurred before + the given datetime, integer epoch (in seconds), or + float (in nanoseconds) Returns: (generator or str): Logs from the container. diff --git a/tests/unit/api_container_test.py b/tests/unit/api_container_test.py index 8f120f4d49..d7b356c444 100644 --- a/tests/unit/api_container_test.py +++ b/tests/unit/api_container_test.py @@ -1279,6 +1279,22 @@ def test_log_since(self): stream=False ) + def test_log_since_with_float(self): + ts = 809222400.000000 + with mock.patch('docker.api.client.APIClient.inspect_container', + fake_inspect_container): + self.client.logs(fake_api.FAKE_CONTAINER_ID, stream=False, + follow=False, since=ts) + + fake_request.assert_called_with( + 'GET', + url_prefix + 'containers/' + fake_api.FAKE_CONTAINER_ID + '/logs', + params={'timestamps': 0, 'follow': 0, 'stderr': 1, 'stdout': 1, + 'tail': 'all', 'since': ts}, + timeout=DEFAULT_TIMEOUT_SECONDS, + stream=False + ) + def test_log_since_with_datetime(self): ts = 809222400 time = datetime.datetime.utcfromtimestamp(ts) @@ -1301,7 +1317,7 @@ def test_log_since_with_invalid_value_raises_error(self): fake_inspect_container): with pytest.raises(docker.errors.InvalidArgument): self.client.logs(fake_api.FAKE_CONTAINER_ID, stream=False, - follow=False, since=42.42) + follow=False, since="42.42") def test_log_tty(self): m = mock.Mock() From bc0a5fbacd7617fd338d121adca61600fc70d221 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Wed, 5 Oct 2022 10:54:45 -0700 Subject: [PATCH 4/5] test: use anonymous volume for prune (#3051) This is related to https://github.com/moby/moby/pull/44216 Prunes will, by default, no longer prune named volumes, only anonymous ones. Signed-off-by: Brian Goff --- tests/integration/api_volume_test.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/integration/api_volume_test.py b/tests/integration/api_volume_test.py index 8e7dd3afb1..2085e83113 100644 --- a/tests/integration/api_volume_test.py +++ b/tests/integration/api_volume_test.py @@ -57,11 +57,10 @@ def test_force_remove_volume(self): @requires_api_version('1.25') def test_prune_volumes(self): - name = 'hopelessmasquerade' - self.client.create_volume(name) - self.tmp_volumes.append(name) + v = self.client.create_volume() + self.tmp_volumes.append(v["Name"]) result = self.client.prune_volumes() - assert name in result['VolumesDeleted'] + assert v["Name"] in result['VolumesDeleted'] def test_remove_nonexistent_volume(self): name = 'shootthebullet' From 30022984f6445fbc322cbe97bb99aab1ddb1e4fd Mon Sep 17 00:00:00 2001 From: Nick Santos Date: Wed, 2 Nov 2022 15:31:00 -0400 Subject: [PATCH 5/5] socket: handle npipe close on Windows (#3056) Fixes https://github.com/docker/docker-py/issues/3045 Signed-off-by: Nick Santos --- docker/utils/socket.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docker/utils/socket.py b/docker/utils/socket.py index 4a2076ec4a..5aca30b17d 100644 --- a/docker/utils/socket.py +++ b/docker/utils/socket.py @@ -18,6 +18,11 @@ class SocketError(Exception): pass +# NpipeSockets have their own error types +# pywintypes.error: (109, 'ReadFile', 'The pipe has been ended.') +NPIPE_ENDED = 109 + + def read(socket, n=4096): """ Reads at most n bytes from socket @@ -37,6 +42,15 @@ def read(socket, n=4096): except OSError as e: if e.errno not in recoverable_errors: raise + except Exception as e: + is_pipe_ended = (isinstance(socket, NpipeSocket) and + len(e.args) > 0 and + e.args[0] == NPIPE_ENDED) + if is_pipe_ended: + # npipes don't support duplex sockets, so we interpret + # a PIPE_ENDED error as a close operation (0-length read). + return 0 + raise def read_exactly(socket, n):