From c3f82cc310c2777573df96fac28778329fbfcd76 Mon Sep 17 00:00:00 2001 From: Niko Pang Date: Mon, 15 Sep 2025 22:57:11 +0800 Subject: [PATCH] feat: fix api fetch error for docker client (cherry picked from commit 57c497862bf45d94e45717be7ae86a4dffbc6e99) --- aiopslab/service/dock.py | 62 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/aiopslab/service/dock.py b/aiopslab/service/dock.py index 149ff1cc..02fe1ea4 100644 --- a/aiopslab/service/dock.py +++ b/aiopslab/service/dock.py @@ -5,11 +5,32 @@ import docker import subprocess +import os +import json class Docker: - def __init__(self): - self.client = docker.from_env() + def __init__(self, base_url: str | None = None): + self.client = None + + try: + env_client = docker.from_env() + env_client.ping() + self.client = env_client + return + except Exception: + print("Failed to connect to docker client from docker env") + pass + + context_host = _docker_context_host() + try: + if context_host: + env_client = docker.DockerClient(base_url=context_host) + env_client.ping() + self.client = env_client + return + except Exception as e: + print(f"Failed to connect to docker client from {context_host}: {e}") def list_containers(self): """Get all containers.""" @@ -55,3 +76,40 @@ def exec_command(self, command: str, input_data=None, cwd=None): return out.stdout.decode("utf-8") except subprocess.CalledProcessError as e: return e.stderr.decode("utf-8") + + +def _docker_context_host() -> str | None: + try: + ctx = subprocess.run( + ["docker", "context", "show"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + check=False, + ).stdout.strip() + if not ctx: + return None + out = subprocess.run( + [ + "docker", + "context", + "inspect", + ctx, + "--format", + "{{json .Endpoints.docker.Host}}", + ], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + check=False, + ).stdout.strip() + if not out: + return None + # Output is a JSON string like "unix:///Users/.../.docker/run/docker.sock" + try: + host = json.loads(out) + return host + except json.JSONDecodeError: + return out.strip('"') + except Exception: + return None