cli/command/formatter: restore fallback for container names with slashes

Since commit f7a909d56b, ContainerContext.Names returns an empty string
when truncating and every name of the container contains a slash. Before
that change, all names were printed in that case.

Classic Swarm prefixes container names with the node-name
("/<node-name>/<container-name>"), so `docker ps` against a classic Swarm
API printed an empty NAMES column.

Restore the fallback to printing all names when no name without slashes
is found.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Drew Erny <derny@mirantis.com>
This commit is contained in:
Drew Erny
2026-11-05 08:53:09 -06:00
co-authored by Claude Opus 5.5
parent 997674f459
commit 191aab9fe8
2 changed files with 34 additions and 12 deletions
+15 -12
View File
@@ -146,24 +146,27 @@ func (c *ContainerContext) ID() string {
// slash (/) prefix stripped. Additional names for the container (related to the
// legacy `--link` feature) are omitted when formatting "truncated".
func (c *ContainerContext) Names() string {
var b strings.Builder
for i, n := range c.c.Names {
name := strings.TrimPrefix(n, "/")
if c.trunc {
// When printing truncated, we only print a single name.
//
// Pick the first name that's not a legacy link (does not have
// slashes inside the name itself (e.g., "/other-container/link")).
// Normally this would be the first name found.
if strings.IndexByte(name, '/') == -1 {
if c.trunc {
// When printing truncated, we only print a single name.
//
// Pick the first name that's not a legacy link (does not have
// slashes inside the name itself (e.g., "/other-container/link")).
// Normally this would be the first name found.
for _, n := range c.c.Names {
if name := strings.TrimPrefix(n, "/"); strings.IndexByte(name, '/') == -1 {
return name
}
continue
}
// No name without slashes was found; this can happen when connected
// to a classic Swarm API, which prefixes names with the node-name
// ("/<node-name>/<container-name>"). Fall back to printing all names.
}
var b strings.Builder
for i, n := range c.c.Names {
if i > 0 {
b.WriteByte(',')
}
b.WriteString(name)
b.WriteString(strings.TrimPrefix(n, "/"))
}
return b.String()
}
+19
View File
@@ -48,6 +48,25 @@ func TestContainerPsContext(t *testing.T) {
expValue: "foobar_baz",
call: ctx.Names,
},
{
container: container.Summary{Names: []string{"/other/link", "/foobar_baz"}},
trunc: true,
expValue: "foobar_baz",
call: ctx.Names,
},
{
container: container.Summary{Names: []string{"/foobar_baz", "/other/link"}},
expValue: "foobar_baz,other/link",
call: ctx.Names,
},
{
// Names returned by a classic Swarm API are prefixed with the
// node-name; see https://github.com/docker/cli/pull/6875
container: container.Summary{Names: []string{"/node-1/foobar_baz"}},
trunc: true,
expValue: "node-1/foobar_baz",
call: ctx.Names,
},
{
container: container.Summary{Image: "ubuntu"},
trunc: true,