mirror of https://github.com/docker/cli.git
show platforms for `docker manifest ls`
Signed-off-by: Wayne Cheng <zhengwei@tiduyun.com>
This commit is contained in:
parent
46b474267b
commit
b039c0e9af
|
@ -1,16 +1,21 @@
|
||||||
package manifest
|
package manifest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/distribution/reference"
|
"github.com/distribution/reference"
|
||||||
"github.com/docker/cli/cli/command/formatter"
|
"github.com/docker/cli/cli/command/formatter"
|
||||||
|
"github.com/docker/cli/cli/manifest/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultManifestListQuietFormat = "{{.Name}}"
|
defaultManifestListQuietFormat = "{{.Name}}"
|
||||||
defaultManifestListTableFormat = "table {{.Repository}}\t{{.Tag}}"
|
defaultManifestListTableFormat = "table {{.Repository}}\t{{.Tag}}\t{{.Platforms}}"
|
||||||
|
|
||||||
repositoryHeader = "REPOSITORY"
|
repositoryHeader = "REPOSITORY"
|
||||||
tagHeader = "TAG"
|
tagHeader = "TAG"
|
||||||
|
platformsHeader = "PLATFORMS"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewFormat returns a Format for rendering using a manifest list Context
|
// NewFormat returns a Format for rendering using a manifest list Context
|
||||||
|
@ -31,15 +36,16 @@ func NewFormat(source string, quiet bool) formatter.Format {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FormatWrite writes formatted manifestLists using the Context
|
// FormatWrite writes formatted manifestLists using the Context
|
||||||
func FormatWrite(ctx formatter.Context, manifestLists []reference.Reference) error {
|
func FormatWrite(ctx formatter.Context, manifestLists []reference.Reference, manifests map[string][]types.ImageManifest) error {
|
||||||
render := func(format func(subContext formatter.SubContext) error) error {
|
render := func(format func(subContext formatter.SubContext) error) error {
|
||||||
for _, manifestList := range manifestLists {
|
for _, manifestList := range manifestLists {
|
||||||
if n, ok := manifestList.(reference.Named); ok {
|
if n, ok := manifestList.(reference.Named); ok {
|
||||||
if nt, ok := n.(reference.NamedTagged); ok {
|
if nt, ok := n.(reference.NamedTagged); ok {
|
||||||
if err := format(&manifestListContext{
|
if err := format(&manifestListContext{
|
||||||
name: reference.FamiliarString(manifestList),
|
name: reference.FamiliarString(manifestList),
|
||||||
repo: reference.FamiliarName(nt),
|
repo: reference.FamiliarName(nt),
|
||||||
tag: nt.Tag(),
|
tag: nt.Tag(),
|
||||||
|
imageManifests: manifests[manifestList.String()],
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -53,9 +59,10 @@ func FormatWrite(ctx formatter.Context, manifestLists []reference.Reference) err
|
||||||
|
|
||||||
type manifestListContext struct {
|
type manifestListContext struct {
|
||||||
formatter.HeaderContext
|
formatter.HeaderContext
|
||||||
name string
|
name string
|
||||||
repo string
|
repo string
|
||||||
tag string
|
tag string
|
||||||
|
imageManifests []types.ImageManifest
|
||||||
}
|
}
|
||||||
|
|
||||||
func newManifestListContext() *manifestListContext {
|
func newManifestListContext() *manifestListContext {
|
||||||
|
@ -64,6 +71,7 @@ func newManifestListContext() *manifestListContext {
|
||||||
"Name": formatter.NameHeader,
|
"Name": formatter.NameHeader,
|
||||||
"Repository": repositoryHeader,
|
"Repository": repositoryHeader,
|
||||||
"Tag": tagHeader,
|
"Tag": tagHeader,
|
||||||
|
"Platforms": platformsHeader,
|
||||||
}
|
}
|
||||||
return &manifestListCtx
|
return &manifestListCtx
|
||||||
}
|
}
|
||||||
|
@ -83,3 +91,13 @@ func (c *manifestListContext) Repository() string {
|
||||||
func (c *manifestListContext) Tag() string {
|
func (c *manifestListContext) Tag() string {
|
||||||
return c.tag
|
return c.tag
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *manifestListContext) Platforms() string {
|
||||||
|
platforms := []string{}
|
||||||
|
for _, manifest := range c.imageManifests {
|
||||||
|
os := manifest.Descriptor.Platform.OS
|
||||||
|
arch := manifest.Descriptor.Platform.Architecture
|
||||||
|
platforms = append(platforms, fmt.Sprintf("%s/%s", os, arch))
|
||||||
|
}
|
||||||
|
return strings.Join(platforms, ", ")
|
||||||
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/formatter"
|
"github.com/docker/cli/cli/command/formatter"
|
||||||
flagsHelper "github.com/docker/cli/cli/flags"
|
flagsHelper "github.com/docker/cli/cli/flags"
|
||||||
|
"github.com/docker/cli/cli/manifest/types"
|
||||||
"github.com/fvbommel/sortorder"
|
"github.com/fvbommel/sortorder"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -42,9 +42,16 @@ func runList(dockerCli command.Cli, options listOptions) error {
|
||||||
|
|
||||||
var manifestLists []reference.Reference
|
var manifestLists []reference.Reference
|
||||||
|
|
||||||
manifestLists, searchErr := manifestStore.List()
|
manifestLists, err := manifestStore.List()
|
||||||
if searchErr != nil {
|
if err != nil {
|
||||||
return errors.New(searchErr.Error())
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
manifests := map[string][]types.ImageManifest{}
|
||||||
|
for _, manifestList := range manifestLists {
|
||||||
|
if imageManifests, err := manifestStore.GetList(manifestList); err == nil {
|
||||||
|
manifests[manifestList.String()] = imageManifests
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
format := options.format
|
format := options.format
|
||||||
|
@ -63,5 +70,5 @@ func runList(dockerCli command.Cli, options listOptions) error {
|
||||||
sort.Slice(manifestLists, func(i, j int) bool {
|
sort.Slice(manifestLists, func(i, j int) bool {
|
||||||
return sortorder.NaturalLess(manifestLists[i].String(), manifestLists[j].String())
|
return sortorder.NaturalLess(manifestLists[i].String(), manifestLists[j].String())
|
||||||
})
|
})
|
||||||
return FormatWrite(manifestListsCtx, manifestLists)
|
return FormatWrite(manifestListsCtx, manifestLists, manifests)
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,10 @@ func TestList(t *testing.T) {
|
||||||
err := manifestStore.Save(list1, namedRef, fullImageManifest(t, namedRef))
|
err := manifestStore.Save(list1, namedRef, fullImageManifest(t, namedRef))
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
namedRef = ref(t, "alpine:3.1")
|
namedRef = ref(t, "alpine:3.1")
|
||||||
err = manifestStore.Save(list1, namedRef, fullImageManifest(t, namedRef))
|
imageManifest := fullImageManifest(t, namedRef)
|
||||||
|
imageManifest.Descriptor.Platform.OS = "linux"
|
||||||
|
imageManifest.Descriptor.Platform.Architecture = "arm64"
|
||||||
|
err = manifestStore.Save(list1, namedRef, imageManifest)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
list2 := ref(t, "second:2")
|
list2 := ref(t, "second:2")
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
REPOSITORY TAG
|
REPOSITORY TAG PLATFORMS
|
||||||
example.com/first 1
|
example.com/first 1 linux/amd64, linux/arm64
|
||||||
example.com/second 2
|
example.com/second 2 linux/amd64
|
||||||
|
|
Loading…
Reference in New Issue