Merge pull request #1151 from stevvooe/image-metadata-service
images, containers: converge metadata API conventions
This commit is contained in:
109
cmd/dist/images.go
vendored
109
cmd/dist/images.go
vendored
@@ -3,9 +3,12 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/progress"
|
||||
"github.com/pkg/errors"
|
||||
@@ -18,6 +21,7 @@ var imageCommand = cli.Command{
|
||||
Subcommands: cli.Commands{
|
||||
imagesListCommand,
|
||||
imageRemoveCommand,
|
||||
imagesSetLabelsCommand,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -29,7 +33,10 @@ var imagesListCommand = cli.Command{
|
||||
Description: `List images registered with containerd.`,
|
||||
Flags: []cli.Flag{},
|
||||
Action: func(clicontext *cli.Context) error {
|
||||
ctx, cancel := appContext(clicontext)
|
||||
var (
|
||||
filters = clicontext.Args()
|
||||
ctx, cancel = appContext(clicontext)
|
||||
)
|
||||
defer cancel()
|
||||
|
||||
client, err := getClient(clicontext)
|
||||
@@ -40,26 +47,93 @@ var imagesListCommand = cli.Command{
|
||||
imageStore := client.ImageService()
|
||||
cs := client.ContentStore()
|
||||
|
||||
images, err := imageStore.List(ctx)
|
||||
images, err := imageStore.List(ctx, filters...)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to list images")
|
||||
}
|
||||
|
||||
tw := tabwriter.NewWriter(os.Stdout, 1, 8, 1, ' ', 0)
|
||||
fmt.Fprintln(tw, "REF\tTYPE\tDIGEST\tSIZE\t")
|
||||
fmt.Fprintln(tw, "REF\tTYPE\tDIGEST\tSIZE\tLABELS\t")
|
||||
for _, image := range images {
|
||||
size, err := image.Size(ctx, cs)
|
||||
if err != nil {
|
||||
log.G(ctx).WithError(err).Errorf("failed calculating size for image %s", image.Name)
|
||||
}
|
||||
|
||||
fmt.Fprintf(tw, "%v\t%v\t%v\t%v\t\n", image.Name, image.Target.MediaType, image.Target.Digest, progress.Bytes(size))
|
||||
labels := "-"
|
||||
if len(image.Labels) > 0 {
|
||||
var pairs []string
|
||||
for k, v := range image.Labels {
|
||||
pairs = append(pairs, fmt.Sprintf("%v=%v", k, v))
|
||||
}
|
||||
sort.Strings(pairs)
|
||||
labels = strings.Join(pairs, ",")
|
||||
}
|
||||
|
||||
fmt.Fprintf(tw, "%v\t%v\t%v\t%v\t%s\t\n",
|
||||
image.Name,
|
||||
image.Target.MediaType,
|
||||
image.Target.Digest,
|
||||
progress.Bytes(size),
|
||||
labels)
|
||||
}
|
||||
|
||||
return tw.Flush()
|
||||
},
|
||||
}
|
||||
|
||||
var imagesSetLabelsCommand = cli.Command{
|
||||
Name: "set-labels",
|
||||
Usage: "Set and clear labels for an image.",
|
||||
ArgsUsage: "[flags] <name> [<key>=<value>, ...]",
|
||||
Description: "Set and clear labels for an image.",
|
||||
Flags: []cli.Flag{},
|
||||
Action: func(clicontext *cli.Context) error {
|
||||
var (
|
||||
ctx, cancel = appContext(clicontext)
|
||||
name, labels = objectWithLabelArgs(clicontext)
|
||||
)
|
||||
defer cancel()
|
||||
|
||||
client, err := getClient(clicontext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if name == "" {
|
||||
return errors.New("please specify an image")
|
||||
}
|
||||
|
||||
var (
|
||||
is = client.ImageService()
|
||||
fieldpaths []string
|
||||
)
|
||||
|
||||
for k := range labels {
|
||||
fieldpaths = append(fieldpaths, strings.Join([]string{"labels", k}, "."))
|
||||
}
|
||||
|
||||
image := images.Image{
|
||||
Name: name,
|
||||
Labels: labels,
|
||||
}
|
||||
|
||||
updated, err := is.Update(ctx, image, fieldpaths...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var labelStrings []string
|
||||
for k, v := range updated.Labels {
|
||||
labelStrings = append(labelStrings, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
|
||||
fmt.Println(strings.Join(labelStrings, ","))
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var imageRemoveCommand = cli.Command{
|
||||
Name: "remove",
|
||||
Aliases: []string{"rm"},
|
||||
@@ -98,3 +172,30 @@ var imageRemoveCommand = cli.Command{
|
||||
return exitErr
|
||||
},
|
||||
}
|
||||
|
||||
// TODO(stevvooe): These helpers should go away when we merge dist and ctr.
|
||||
|
||||
func objectWithLabelArgs(clicontext *cli.Context) (string, map[string]string) {
|
||||
var (
|
||||
name = clicontext.Args().First()
|
||||
labelStrings = clicontext.Args().Tail()
|
||||
)
|
||||
|
||||
return name, labelArgs(labelStrings)
|
||||
}
|
||||
|
||||
func labelArgs(labelStrings []string) map[string]string {
|
||||
labels := make(map[string]string, len(labelStrings))
|
||||
for _, label := range labelStrings {
|
||||
parts := strings.SplitN(label, "=", 2)
|
||||
key := parts[0]
|
||||
value := "true"
|
||||
if len(parts) > 1 {
|
||||
value = parts[1]
|
||||
}
|
||||
|
||||
labels[key] = value
|
||||
}
|
||||
|
||||
return labels
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user