From 117025a8a235c85d2bbcf4bb294bb911f807578b Mon Sep 17 00:00:00 2001 From: YueGuobin Date: Wed, 22 Apr 2026 23:12:56 +0800 Subject: [PATCH] fix(web-wireshark): improve Docker API version compatibility with fallback mechanism - Change initial API version from 1.40 to 1.44 to support Docker 29.3+ (API 1.54) - Add automatic fallback to API 1.40 for older Docker versions (20.10, API 1.41) - Fixes "client version 1.40 is too old. Minimum supported API version is 1.44" error - Ensures compatibility across Docker versions 20.10 (API 1.41) to 29.3+ (API 1.54+) Co-Authored-By: Claude Sonnet 4.6 --- gns3server/agent/web_wireshark/docker_client.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/gns3server/agent/web_wireshark/docker_client.py b/gns3server/agent/web_wireshark/docker_client.py index e350ae6d3..ca9e86360 100644 --- a/gns3server/agent/web_wireshark/docker_client.py +++ b/gns3server/agent/web_wireshark/docker_client.py @@ -46,7 +46,9 @@ class DockerHTTPClient: self._connector = None self._session = None self._connected = False - self._api_version = DOCKER_MINIMUM_API_VERSION + # Start with preferred API version (1.44) to support newer Docker + # Will fallback to minimum version (1.40) if server doesn't support it + self._api_version = DOCKER_PREFERRED_API_VERSION async def _get_connector(self): """Get or create Unix socket connector.""" @@ -142,6 +144,14 @@ class DockerHTTPClient: raise RuntimeError(f"Docker API timeout after {self.REQUEST_TIMEOUT}s for {endpoint}") except aiohttp.ClientError as e: raise RuntimeError(f"Docker connection error: {e}") from e + except RuntimeError as e: + # Retry with lower API version if Docker daemon doesn't support current version + error_msg = str(e) + if ("400" in error_msg or "not found" in error_msg.lower()) and self._api_version == DOCKER_PREFERRED_API_VERSION: + logger.warning(f"Docker daemon doesn't support API version {self._api_version}, falling back to {DOCKER_MINIMUM_API_VERSION}") + self._api_version = DOCKER_MINIMUM_API_VERSION + return await self._request(method, endpoint, check_connection=False, **kwargs) + raise async def create_network(self, name: str, driver: str = "bridge", subnet: str = None): """Create Docker network."""