Merge pull request #6042 from thaJeztah/carry_5804_docker_ps_platform
docker ps: add "Platform" as formatting option
This commit is contained in:
commit
97e060e7b1
@ -11,10 +11,12 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/containerd/platforms"
|
||||||
"github.com/distribution/reference"
|
"github.com/distribution/reference"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/pkg/stringid"
|
"github.com/docker/docker/pkg/stringid"
|
||||||
"github.com/docker/go-units"
|
"github.com/docker/go-units"
|
||||||
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -26,8 +28,18 @@ const (
|
|||||||
mountsHeader = "MOUNTS"
|
mountsHeader = "MOUNTS"
|
||||||
localVolumes = "LOCAL VOLUMES"
|
localVolumes = "LOCAL VOLUMES"
|
||||||
networksHeader = "NETWORKS"
|
networksHeader = "NETWORKS"
|
||||||
|
platformHeader = "PLATFORM"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Platform wraps a [ocispec.Platform] to implement the stringer interface.
|
||||||
|
type Platform struct {
|
||||||
|
ocispec.Platform
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Platform) String() string {
|
||||||
|
return platforms.FormatAll(p.Platform)
|
||||||
|
}
|
||||||
|
|
||||||
// NewContainerFormat returns a Format for rendering using a Context
|
// NewContainerFormat returns a Format for rendering using a Context
|
||||||
func NewContainerFormat(source string, quiet bool, size bool) Format {
|
func NewContainerFormat(source string, quiet bool, size bool) Format {
|
||||||
switch source {
|
switch source {
|
||||||
@ -109,6 +121,7 @@ func NewContainerContext() *ContainerContext {
|
|||||||
"Mounts": mountsHeader,
|
"Mounts": mountsHeader,
|
||||||
"LocalVolumes": localVolumes,
|
"LocalVolumes": localVolumes,
|
||||||
"Networks": networksHeader,
|
"Networks": networksHeader,
|
||||||
|
"Platform": platformHeader,
|
||||||
}
|
}
|
||||||
return &containerCtx
|
return &containerCtx
|
||||||
}
|
}
|
||||||
@ -208,6 +221,16 @@ func (c *ContainerContext) RunningFor() string {
|
|||||||
return units.HumanDuration(time.Now().UTC().Sub(createdAt)) + " ago"
|
return units.HumanDuration(time.Now().UTC().Sub(createdAt)) + " ago"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Platform returns a human-readable representation of the container's
|
||||||
|
// platform if it is available.
|
||||||
|
func (c *ContainerContext) Platform() *Platform {
|
||||||
|
p := c.c.ImageManifestDescriptor
|
||||||
|
if p == nil || p.Platform == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &Platform{*p.Platform}
|
||||||
|
}
|
||||||
|
|
||||||
// Ports returns a comma-separated string representing open ports of the container
|
// Ports returns a comma-separated string representing open ports of the container
|
||||||
// e.g. "0.0.0.0:80->9090/tcp, 9988/tcp"
|
// e.g. "0.0.0.0:80->9090/tcp, 9988/tcp"
|
||||||
// it's used by command 'docker ps'
|
// it's used by command 'docker ps'
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/pkg/stringid"
|
"github.com/docker/docker/pkg/stringid"
|
||||||
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
@ -425,13 +426,36 @@ func TestContainerContextWriteWithNoContainers(t *testing.T) {
|
|||||||
func TestContainerContextWriteJSON(t *testing.T) {
|
func TestContainerContextWriteJSON(t *testing.T) {
|
||||||
unix := time.Now().Add(-65 * time.Second).Unix()
|
unix := time.Now().Add(-65 * time.Second).Unix()
|
||||||
containers := []container.Summary{
|
containers := []container.Summary{
|
||||||
{ID: "containerID1", Names: []string{"/foobar_baz"}, Image: "ubuntu", Created: unix, State: container.StateRunning},
|
{
|
||||||
{ID: "containerID2", Names: []string{"/foobar_bar"}, Image: "ubuntu", Created: unix, State: container.StateRunning},
|
ID: "containerID1",
|
||||||
|
Names: []string{"/foobar_baz"},
|
||||||
|
Image: "ubuntu",
|
||||||
|
Created: unix,
|
||||||
|
State: container.StateRunning,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "containerID2",
|
||||||
|
Names: []string{"/foobar_bar"},
|
||||||
|
Image: "ubuntu",
|
||||||
|
Created: unix,
|
||||||
|
State: container.StateRunning,
|
||||||
|
|
||||||
|
ImageManifestDescriptor: &ocispec.Descriptor{Platform: &ocispec.Platform{Architecture: "amd64", OS: "linux"}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "containerID3",
|
||||||
|
Names: []string{"/foobar_bar"},
|
||||||
|
Image: "ubuntu",
|
||||||
|
Created: unix,
|
||||||
|
State: container.StateRunning,
|
||||||
|
|
||||||
|
ImageManifestDescriptor: &ocispec.Descriptor{Platform: &ocispec.Platform{}},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
expectedCreated := time.Unix(unix, 0).String()
|
expectedCreated := time.Unix(unix, 0).String()
|
||||||
expectedJSONs := []map[string]any{
|
expectedJSONs := []map[string]any{
|
||||||
{
|
{
|
||||||
"Command": "\"\"",
|
"Command": `""`,
|
||||||
"CreatedAt": expectedCreated,
|
"CreatedAt": expectedCreated,
|
||||||
"ID": "containerID1",
|
"ID": "containerID1",
|
||||||
"Image": "ubuntu",
|
"Image": "ubuntu",
|
||||||
@ -440,6 +464,7 @@ func TestContainerContextWriteJSON(t *testing.T) {
|
|||||||
"Mounts": "",
|
"Mounts": "",
|
||||||
"Names": "foobar_baz",
|
"Names": "foobar_baz",
|
||||||
"Networks": "",
|
"Networks": "",
|
||||||
|
"Platform": nil,
|
||||||
"Ports": "",
|
"Ports": "",
|
||||||
"RunningFor": "About a minute ago",
|
"RunningFor": "About a minute ago",
|
||||||
"Size": "0B",
|
"Size": "0B",
|
||||||
@ -447,7 +472,7 @@ func TestContainerContextWriteJSON(t *testing.T) {
|
|||||||
"Status": "",
|
"Status": "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Command": "\"\"",
|
"Command": `""`,
|
||||||
"CreatedAt": expectedCreated,
|
"CreatedAt": expectedCreated,
|
||||||
"ID": "containerID2",
|
"ID": "containerID2",
|
||||||
"Image": "ubuntu",
|
"Image": "ubuntu",
|
||||||
@ -456,6 +481,24 @@ func TestContainerContextWriteJSON(t *testing.T) {
|
|||||||
"Mounts": "",
|
"Mounts": "",
|
||||||
"Names": "foobar_bar",
|
"Names": "foobar_bar",
|
||||||
"Networks": "",
|
"Networks": "",
|
||||||
|
"Platform": map[string]any{"architecture": "amd64", "os": "linux"},
|
||||||
|
"Ports": "",
|
||||||
|
"RunningFor": "About a minute ago",
|
||||||
|
"Size": "0B",
|
||||||
|
"State": "running",
|
||||||
|
"Status": "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Command": `""`,
|
||||||
|
"CreatedAt": expectedCreated,
|
||||||
|
"ID": "containerID3",
|
||||||
|
"Image": "ubuntu",
|
||||||
|
"Labels": "",
|
||||||
|
"LocalVolumes": "0",
|
||||||
|
"Mounts": "",
|
||||||
|
"Names": "foobar_bar",
|
||||||
|
"Networks": "",
|
||||||
|
"Platform": map[string]any{"architecture": "", "os": ""},
|
||||||
"Ports": "",
|
"Ports": "",
|
||||||
"RunningFor": "About a minute ago",
|
"RunningFor": "About a minute ago",
|
||||||
"Size": "0B",
|
"Size": "0B",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user