From 6c19e22deb4f4b0ed3f9b005a6034154590e1019 Mon Sep 17 00:00:00 2001 From: gyurix Date: Mon, 15 Jun 2026 15:25:38 +0200 Subject: [PATCH] refactor(docker): switch container lookup to use filtered ContainerList Replace ContainerInspect with ContainerList and name filters for exact and prefix matching. This improves efficiency and correctness by leveraging Docker's filtering capabilities, matching the old shell script's grep behavior more accurately. Add regexp import to properly escape container names in filters. --- network-go/docker/docker.go | 55 +++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/network-go/docker/docker.go b/network-go/docker/docker.go index 896314b..acb1ab9 100644 --- a/network-go/docker/docker.go +++ b/network-go/docker/docker.go @@ -5,6 +5,7 @@ import ( "fmt" "net" "os/exec" + "regexp" "strings" "time" @@ -203,25 +204,37 @@ func (c *Client) AddRouteInContainer(ctx context.Context, containerName, network } // FindContainerName attempts to find a running container by name or selector. -// First tries the exact name, then tries listing running containers whose name -// starts with the selector prefix (or the name prefix), matching the old shell -// script's grep $D"-" behavior. +// First tries exact name match, then exact selector, then prefix matching +// (matching the old shell script's grep $D"-" behavior). func (c *Client) FindContainerName(ctx context.Context, name, selector string) (string, error) { - // First try the exact name - cont, err := c.cli.ContainerInspect(ctx, name) - if err == nil && cont.State != nil && cont.State.Running { - return name, nil + // Try exact name match using ContainerList with a name filter + // Docker API name filter does an exact match by default + containers, err := c.cli.ContainerList(ctx, container.ListOptions{ + Filters: filters.NewArgs( + filters.Arg("name", "^/?"+regexp.QuoteMeta(name)+"$"), + filters.Arg("status", "running"), + ), + }) + if err == nil && len(containers) > 0 { + cName := strings.TrimPrefix(containers[0].Names[0], "/") + return cName, nil } - // Try exact selector + // Try exact selector match if selector != "" && selector != name { - cont, err := c.cli.ContainerInspect(ctx, selector) - if err == nil && cont.State != nil && cont.State.Running { - return selector, nil + containers, err = c.cli.ContainerList(ctx, container.ListOptions{ + Filters: filters.NewArgs( + filters.Arg("name", "^/?"+regexp.QuoteMeta(selector)+"$"), + filters.Arg("status", "running"), + ), + }) + if err == nil && len(containers) > 0 { + cName := strings.TrimPrefix(containers[0].Names[0], "/") + return cName, nil } } - // Try prefix matching with selector (old shell script behavior: grep $D"-") + // Try prefix matching on both name and selector (shell script behavior: grep $D"-") candidates := []string{name, selector} for _, candidate := range candidates { if candidate == "" { @@ -233,21 +246,23 @@ func (c *Client) FindContainerName(ctx context.Context, name, selector string) ( prefix = candidate[:strings.Index(candidate, "-")] } - containers, err := c.cli.ContainerList(ctx, container.ListOptions{}) + containers, err = c.cli.ContainerList(ctx, container.ListOptions{ + Filters: filters.NewArgs( + filters.Arg("name", prefix+"-"), + filters.Arg("status", "running"), + ), + }) if err != nil { continue } - for _, container := range containers { - // Remove leading / from container names - for _, cName := range container.Names { + for _, c := range containers { + for _, cName := range c.Names { cName = strings.TrimPrefix(cName, "/") - if strings.HasPrefix(cName, prefix+"-") && container.State == "running" { - return cName, nil - } + return cName, nil } } } return "", fmt.Errorf("no running container found matching name=%q selector=%q", name, selector) -} \ No newline at end of file +}