fix: case-insensitive container name matching for docker inspect
Docker container names are case-sensitive for 'docker inspect' but case- insensitive for Docker DNS. Compose templates may render container names with mixed case (e.g. code-server-Headquarter-abc123), causing exact-name docker inspect to fail while DNS resolution in tunnels works fine. - apps/api/src/services/docker.py: get_container_id now tries exact match first, then falls back to case-insensitive exact match via 'docker ps' - apps/api/src/api/tool_instances.py: recreate_tunnel_endpoint uses get_container_id instead of its own docker inspect call Quality gates: ruff clean
This commit is contained in:
@@ -179,22 +179,41 @@ def execute_compose_command(
|
||||
def get_container_id(instance_name: str) -> str | None:
|
||||
"""Get the container ID for a compose service.
|
||||
|
||||
Uses exact name matching via docker inspect to avoid substring collisions
|
||||
with tunnel containers (e.g. tunnel-code-server-... matching code-server-...).
|
||||
Uses exact name matching to avoid substring collisions with tunnel
|
||||
containers (e.g. tunnel-code-server-... matching code-server-...).
|
||||
Falls back to case-insensitive matching since Docker DNS is case-
|
||||
insensitive but docker inspect is case-sensitive.
|
||||
|
||||
Args:
|
||||
instance_name: The exact container name (case-insensitive for Docker).
|
||||
instance_name: The expected container name.
|
||||
|
||||
Returns:
|
||||
Container ID or None if not found.
|
||||
"""
|
||||
expected = instance_name.lower()
|
||||
|
||||
# Fast path: exact match via docker inspect
|
||||
result = subprocess.run(
|
||||
["docker", "inspect", "-f", "{{.Id}}", instance_name.lower()],
|
||||
["docker", "inspect", "-f", "{{.Id}}", expected],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
if result.returncode == 0 and result.stdout.strip():
|
||||
return result.stdout.strip()
|
||||
|
||||
# Fallback: list all containers and do case-insensitive exact match
|
||||
ps_result = subprocess.run(
|
||||
["docker", "ps", "-a", "--format", "{{.Names}}\t{{.ID}}"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
if ps_result.returncode == 0:
|
||||
for line in ps_result.stdout.strip().splitlines():
|
||||
parts = line.split("\t")
|
||||
if len(parts) == 2:
|
||||
name, cid = parts
|
||||
if name.lower() == expected:
|
||||
return cid
|
||||
return None
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user