refactor(docker): switch container lookup to use filtered ContainerList
continuous-integration/drone/push Build is passing

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.
This commit is contained in:
gyurix
2026-06-15 15:25:38 +02:00
parent aac9b83576
commit 6c19e22deb
+35 -20
View File
@@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"net" "net"
"os/exec" "os/exec"
"regexp"
"strings" "strings"
"time" "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. // FindContainerName attempts to find a running container by name or selector.
// First tries the exact name, then tries listing running containers whose name // First tries exact name match, then exact selector, then prefix matching
// starts with the selector prefix (or the name prefix), matching the old shell // (matching the old shell script's grep $D"-" behavior).
// script's grep $D"-" behavior.
func (c *Client) FindContainerName(ctx context.Context, name, selector string) (string, error) { func (c *Client) FindContainerName(ctx context.Context, name, selector string) (string, error) {
// First try the exact name // Try exact name match using ContainerList with a name filter
cont, err := c.cli.ContainerInspect(ctx, name) // Docker API name filter does an exact match by default
if err == nil && cont.State != nil && cont.State.Running { containers, err := c.cli.ContainerList(ctx, container.ListOptions{
return name, nil 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 { if selector != "" && selector != name {
cont, err := c.cli.ContainerInspect(ctx, selector) containers, err = c.cli.ContainerList(ctx, container.ListOptions{
if err == nil && cont.State != nil && cont.State.Running { Filters: filters.NewArgs(
return selector, nil 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} candidates := []string{name, selector}
for _, candidate := range candidates { for _, candidate := range candidates {
if candidate == "" { if candidate == "" {
@@ -233,21 +246,23 @@ func (c *Client) FindContainerName(ctx context.Context, name, selector string) (
prefix = candidate[:strings.Index(candidate, "-")] 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 { if err != nil {
continue continue
} }
for _, container := range containers { for _, c := range containers {
// Remove leading / from container names for _, cName := range c.Names {
for _, cName := range container.Names {
cName = strings.TrimPrefix(cName, "/") 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) return "", fmt.Errorf("no running container found matching name=%q selector=%q", name, selector)
} }