From 2ab87da0567cb3e2224bd0dfb04ee566be1a9f29 Mon Sep 17 00:00:00 2001 From: "Hsing-Yu (David) Chen" Date: Tue, 24 Jan 2023 11:26:41 -0800 Subject: [PATCH] refactor: extract main logic of image.List Signed-off-by: Hsing-Yu (David) Chen --- cmd/nerdctl/image_list.go | 2 +- pkg/cmd/image/list.go | 44 +++++++++++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/cmd/nerdctl/image_list.go b/cmd/nerdctl/image_list.go index 5f67a76d3de..e63f14fc6fd 100644 --- a/cmd/nerdctl/image_list.go +++ b/cmd/nerdctl/image_list.go @@ -139,7 +139,7 @@ func imagesAction(cmd *cobra.Command, args []string) error { } defer cancel() - return image.List(ctx, client, options) + return image.ListCommandHandler(ctx, client, options) } func imagesShellComplete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { diff --git a/pkg/cmd/image/list.go b/pkg/cmd/image/list.go index 5b9ff08f319..c95cee00514 100644 --- a/pkg/cmd/image/list.go +++ b/pkg/cmd/image/list.go @@ -44,16 +44,38 @@ import ( "github.com/sirupsen/logrus" ) -func List(ctx context.Context, client *containerd.Client, options types.ImageListOptions) error { - var imageStore = client.ImageService() - imageList, err := imageStore.List(ctx, options.NameAndRefFilter...) +// ListCommandHandler `List` and print images matching filters in `options`. +func ListCommandHandler(ctx context.Context, client *containerd.Client, options types.ImageListOptions) error { + imageList, err := List(ctx, client, options.Filters, options.NameAndRefFilter) if err != nil { return err } - if len(options.Filters) > 0 { - f, err := imgutil.ParseFilters(options.Filters) + return printImages(ctx, client, imageList, options) +} + +// List queries containerd client to get image list and only returns those matching given filters. +// +// Supported filters: +// - before=[:]: Images created before given image (exclusive) +// - since=[:]: Images created after given image (exclusive) +// - label=[=]: Matches images based on the presence of a label alone or a label and a value +// - dangling=true: Filter images by dangling +// - reference=[:]: Filter images by reference (Matches both docker compatible wildcard pattern and regexp +// +// nameAndRefFilter has the format of `name==([:])|ID`, +// and they will be used when getting images from containerd, +// while the remaining filters are only applied after getting images from containerd, +// which means that having nameAndRefFilter may speed up the process if there are a lot of images in containerd. +func List(ctx context.Context, client *containerd.Client, filters, nameAndRefFilter []string) ([]images.Image, error) { + var imageStore = client.ImageService() + imageList, err := imageStore.List(ctx, nameAndRefFilter...) + if err != nil { + return nil, err + } + if len(filters) > 0 { + f, err := imgutil.ParseFilters(filters) if err != nil { - return err + return nil, err } if f.Dangling != nil { @@ -62,32 +84,32 @@ func List(ctx context.Context, client *containerd.Client, options types.ImageLis imageList, err = filterByLabel(ctx, client, imageList, f.Labels) if err != nil { - return err + return nil, err } imageList, err = filterByReference(imageList, f.Reference) if err != nil { - return err + return nil, err } var beforeImages []images.Image if len(f.Before) > 0 { beforeImages, err = imageStore.List(ctx, f.Before...) if err != nil { - return err + return nil, err } } var sinceImages []images.Image if len(f.Since) > 0 { sinceImages, err = imageStore.List(ctx, f.Since...) if err != nil { - return err + return nil, err } } imageList = imgutil.FilterImages(imageList, beforeImages, sinceImages) } - return printImages(ctx, client, imageList, options) + return imageList, nil } func filterByReference(imageList []images.Image, filters []string) ([]images.Image, error) {