diff --git a/cli/command/formatter/container.go b/cli/command/formatter/container.go index 7b77a8a753..02d8110ad2 100644 --- a/cli/command/formatter/container.go +++ b/cli/command/formatter/container.go @@ -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 + // ("//"). 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() } diff --git a/cli/command/formatter/container_test.go b/cli/command/formatter/container_test.go index 07df93d9ae..98e9be4c22 100644 --- a/cli/command/formatter/container_test.go +++ b/cli/command/formatter/container_test.go @@ -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,