Skip to content

Commit 97e060e

Browse files
authored
Merge pull request #6042 from thaJeztah/carry_5804_docker_ps_platform
docker ps: add "Platform" as formatting option
2 parents af09051 + 67c0be4 commit 97e060e

File tree

2 files changed

+70
-4
lines changed

2 files changed

+70
-4
lines changed

cli/command/formatter/container.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ import (
1111
"strings"
1212
"time"
1313

14+
"github.com/containerd/platforms"
1415
"github.com/distribution/reference"
1516
"github.com/docker/docker/api/types/container"
1617
"github.com/docker/docker/pkg/stringid"
1718
"github.com/docker/go-units"
19+
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
1820
)
1921

2022
const (
@@ -26,8 +28,18 @@ const (
2628
mountsHeader = "MOUNTS"
2729
localVolumes = "LOCAL VOLUMES"
2830
networksHeader = "NETWORKS"
31+
platformHeader = "PLATFORM"
2932
)
3033

34+
// Platform wraps a [ocispec.Platform] to implement the stringer interface.
35+
type Platform struct {
36+
ocispec.Platform
37+
}
38+
39+
func (p Platform) String() string {
40+
return platforms.FormatAll(p.Platform)
41+
}
42+
3143
// NewContainerFormat returns a Format for rendering using a Context
3244
func NewContainerFormat(source string, quiet bool, size bool) Format {
3345
switch source {
@@ -109,6 +121,7 @@ func NewContainerContext() *ContainerContext {
109121
"Mounts": mountsHeader,
110122
"LocalVolumes": localVolumes,
111123
"Networks": networksHeader,
124+
"Platform": platformHeader,
112125
}
113126
return &containerCtx
114127
}
@@ -208,6 +221,16 @@ func (c *ContainerContext) RunningFor() string {
208221
return units.HumanDuration(time.Now().UTC().Sub(createdAt)) + " ago"
209222
}
210223

224+
// Platform returns a human-readable representation of the container's
225+
// platform if it is available.
226+
func (c *ContainerContext) Platform() *Platform {
227+
p := c.c.ImageManifestDescriptor
228+
if p == nil || p.Platform == nil {
229+
return nil
230+
}
231+
return &Platform{*p.Platform}
232+
}
233+
211234
// Ports returns a comma-separated string representing open ports of the container
212235
// e.g. "0.0.0.0:80->9090/tcp, 9988/tcp"
213236
// it's used by command 'docker ps'

cli/command/formatter/container_test.go

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/docker/cli/internal/test"
1515
"github.com/docker/docker/api/types/container"
1616
"github.com/docker/docker/pkg/stringid"
17+
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
1718
"gotest.tools/v3/assert"
1819
is "gotest.tools/v3/assert/cmp"
1920
"gotest.tools/v3/golden"
@@ -425,13 +426,36 @@ func TestContainerContextWriteWithNoContainers(t *testing.T) {
425426
func TestContainerContextWriteJSON(t *testing.T) {
426427
unix := time.Now().Add(-65 * time.Second).Unix()
427428
containers := []container.Summary{
428-
{ID: "containerID1", Names: []string{"/foobar_baz"}, Image: "ubuntu", Created: unix, State: container.StateRunning},
429-
{ID: "containerID2", Names: []string{"/foobar_bar"}, Image: "ubuntu", Created: unix, State: container.StateRunning},
429+
{
430+
ID: "containerID1",
431+
Names: []string{"/foobar_baz"},
432+
Image: "ubuntu",
433+
Created: unix,
434+
State: container.StateRunning,
435+
},
436+
{
437+
ID: "containerID2",
438+
Names: []string{"/foobar_bar"},
439+
Image: "ubuntu",
440+
Created: unix,
441+
State: container.StateRunning,
442+
443+
ImageManifestDescriptor: &ocispec.Descriptor{Platform: &ocispec.Platform{Architecture: "amd64", OS: "linux"}},
444+
},
445+
{
446+
ID: "containerID3",
447+
Names: []string{"/foobar_bar"},
448+
Image: "ubuntu",
449+
Created: unix,
450+
State: container.StateRunning,
451+
452+
ImageManifestDescriptor: &ocispec.Descriptor{Platform: &ocispec.Platform{}},
453+
},
430454
}
431455
expectedCreated := time.Unix(unix, 0).String()
432456
expectedJSONs := []map[string]any{
433457
{
434-
"Command": "\"\"",
458+
"Command": `""`,
435459
"CreatedAt": expectedCreated,
436460
"ID": "containerID1",
437461
"Image": "ubuntu",
@@ -440,14 +464,15 @@ func TestContainerContextWriteJSON(t *testing.T) {
440464
"Mounts": "",
441465
"Names": "foobar_baz",
442466
"Networks": "",
467+
"Platform": nil,
443468
"Ports": "",
444469
"RunningFor": "About a minute ago",
445470
"Size": "0B",
446471
"State": "running",
447472
"Status": "",
448473
},
449474
{
450-
"Command": "\"\"",
475+
"Command": `""`,
451476
"CreatedAt": expectedCreated,
452477
"ID": "containerID2",
453478
"Image": "ubuntu",
@@ -456,6 +481,24 @@ func TestContainerContextWriteJSON(t *testing.T) {
456481
"Mounts": "",
457482
"Names": "foobar_bar",
458483
"Networks": "",
484+
"Platform": map[string]any{"architecture": "amd64", "os": "linux"},
485+
"Ports": "",
486+
"RunningFor": "About a minute ago",
487+
"Size": "0B",
488+
"State": "running",
489+
"Status": "",
490+
},
491+
{
492+
"Command": `""`,
493+
"CreatedAt": expectedCreated,
494+
"ID": "containerID3",
495+
"Image": "ubuntu",
496+
"Labels": "",
497+
"LocalVolumes": "0",
498+
"Mounts": "",
499+
"Names": "foobar_bar",
500+
"Networks": "",
501+
"Platform": map[string]any{"architecture": "", "os": ""},
459502
"Ports": "",
460503
"RunningFor": "About a minute ago",
461504
"Size": "0B",

0 commit comments

Comments
 (0)