From 5afe15ea50512cd983fd98f87bceff7dd1009d03 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 26 May 2026 21:11:50 +0200 Subject: [PATCH] Close response instead of derived socket. (#1260) --- changelogs/fragments/1260-close.yml | 4 ++++ plugins/connection/docker_api.py | 4 ++-- plugins/module_utils/_api/api/client.py | 17 ++++++++--------- plugins/modules/docker_container_exec.py | 4 ++-- 4 files changed, 16 insertions(+), 13 deletions(-) create mode 100644 changelogs/fragments/1260-close.yml diff --git a/changelogs/fragments/1260-close.yml b/changelogs/fragments/1260-close.yml new file mode 100644 index 00000000..6f7c3c58 --- /dev/null +++ b/changelogs/fragments/1260-close.yml @@ -0,0 +1,4 @@ +bugfixes: + - "docker_container_exec module, docker_api connection plugin - ensure that when a command is run in a container with stdin provided, that the actual response is closed and not a socket derived from it. + The old behavior causes warnings to be shown on Python 3.13+ under certain conditions + (https://github.com/ansible-collections/community.docker/issues/1247, https://github.com/ansible-collections/community.docker/pull/1260)." diff --git a/plugins/connection/docker_api.py b/plugins/connection/docker_api.py index 6338b4a8..879b013b 100644 --- a/plugins/connection/docker_api.py +++ b/plugins/connection/docker_api.py @@ -303,7 +303,7 @@ class Connection(ConnectionBase): data = {"Tty": False, "Detach": False} if need_stdin: - exec_socket = self._call_client( + exec_socket, response = self._call_client( lambda client: client.post_json_to_stream_socket( "/exec/{0}/start", exec_id, data=data ) @@ -356,7 +356,7 @@ class Connection(ConnectionBase): stdout, stderr = exec_socket_handler.consume() finally: - exec_socket.close() + response.close() else: stdout, stderr = self._call_client( lambda client: client.post_json_to_stream( diff --git a/plugins/module_utils/_api/api/client.py b/plugins/module_utils/_api/api/client.py index a90fc184..1ac44d90 100644 --- a/plugins/module_utils/_api/api/client.py +++ b/plugins/module_utils/_api/api/client.py @@ -795,7 +795,7 @@ class APIClient(_Session): data: t.Any = None, headers: dict[str, str] | None = None, **kwargs: t.Any, - ) -> SocketLike: + ) -> tuple[SocketLike, Response]: headers = headers.copy() if headers else {} headers.update( { @@ -803,15 +803,14 @@ class APIClient(_Session): "Upgrade": "tcp", } ) - return self._get_raw_response_socket( - self._post_json( - self._url(pathfmt, *args, versioned_api=True), - data, - headers=headers, - stream=True, - **kwargs, - ) + response = self._post_json( + self._url(pathfmt, *args, versioned_api=True), + data, + headers=headers, + stream=True, + **kwargs, ) + return self._get_raw_response_socket(response), response @t.overload def post_json_to_stream( diff --git a/plugins/modules/docker_container_exec.py b/plugins/modules/docker_container_exec.py index aaf94034..2a623778 100644 --- a/plugins/modules/docker_container_exec.py +++ b/plugins/modules/docker_container_exec.py @@ -274,7 +274,7 @@ def main() -> None: stdout: bytes | None stderr: bytes | None if stdin and not detach: - exec_socket = client.post_json_to_stream_socket( + exec_socket, response = client.post_json_to_stream_socket( "/exec/{0}/start", exec_id, data=data ) try: @@ -286,7 +286,7 @@ def main() -> None: stdout, stderr = exec_socket_handler.consume() finally: - exec_socket.close() + response.close() elif tty: stdout, stderr = client.post_json_to_stream( "/exec/{0}/start",