Skip to content

Commit

Permalink
Filter dangling images using image filters.
Browse files Browse the repository at this point in the history
Signed-off-by: Manu Gupta <manugupt1@gmail.com>
  • Loading branch information
manugupt1 committed Dec 31, 2022
1 parent 8c991c2 commit 9d79e98
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 2 deletions.
19 changes: 19 additions & 0 deletions cmd/nerdctl/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ func imagesAction(cmd *cobra.Command, args []string) error {
return err
}

if f.Dangling != nil {
imageList = filterDangling(imageList, *f.Dangling)
}

imageList, err = filterByLabel(ctx, client, imageList, f.Labels)
if err != nil {
return err
Expand Down Expand Up @@ -182,6 +186,21 @@ func filterByReference(imageList []images.Image, filters []string) ([]images.Ima
return filteredImageList, nil
}

func filterDangling(imageList []images.Image, dangling bool) []images.Image {
var filtered []images.Image
for _, image := range imageList {
_, tag := imgutil.ParseRepoTag(image.Name)

if dangling && tag == "" {
filtered = append(filtered, image)
}
if !dangling && tag != "" {
filtered = append(filtered, image)
}
}
return filtered
}

func filterByLabel(ctx context.Context, client *containerd.Client, imageList []images.Image, filters map[string]string) ([]images.Image, error) {
for lk, lv := range filters {
var imageLabels []images.Image
Expand Down
19 changes: 19 additions & 0 deletions cmd/nerdctl/images_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,22 @@ LABEL version=0.1`, testutil.CommonImage)
base.Cmd("images", "--filter", "reference=busy*:*libc*").AssertOutContains("glibc")
base.Cmd("images", "--filter", "reference=busy*:*libc*").AssertOutContains("uclibc")
}

func TestImagesFilterDangling(t *testing.T) {
testutil.RequiresBuild(t)
base := testutil.NewBase(t)
base.Cmd("images", "prune", "--all").AssertOK()

dockerfile := fmt.Sprintf(`FROM %s
CMD ["echo", "nerdctl-build-notag-string"]
`, testutil.CommonImage)
buildCtx, err := createBuildContext(dockerfile)
assert.NilError(t, err)

defer os.RemoveAll(buildCtx)
base.Cmd("build", "-f", buildCtx+"/Dockerfile", buildCtx).AssertOK()

// dangling image test
base.Cmd("images", "--filter", "dangling=true").AssertOutContains("<none>")
base.Cmd("images", "--filter", "dangling=false").AssertOutNotContains("<none>")
}
16 changes: 14 additions & 2 deletions pkg/imgutil/imgutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ var (
FilterSinceType = "since"
FilterLabelType = "label"
FilterReferenceType = "reference"
FilterDanglingType = "dangling"
)

// PullMode is either one of "always", "missing", "never"
Expand Down Expand Up @@ -369,7 +370,7 @@ func ParseRepoTag(imgName string) (string, string) {

ref, err := refdocker.ParseDockerRef(imgName)
if err != nil {
logrus.WithError(err).Warnf("unparsable image name %q", imgName)
logrus.WithError(err).Debugf("unparsable image name %q", imgName)
return "", ""
}

Expand All @@ -388,6 +389,7 @@ type Filters struct {
Since []string
Labels map[string]string
Reference []string
Dangling *bool
}

func ParseFilters(filters []string) (*Filters, error) {
Expand All @@ -398,7 +400,17 @@ func ParseFilters(filters []string) (*Filters, error) {
case 1:
return nil, fmt.Errorf("invalid filter %q", filter)
case 2:
if tempFilterToken[0] == FilterBeforeType {
if tempFilterToken[0] == FilterDanglingType {
var isDangling bool
if tempFilterToken[1] == "true" {
isDangling = true
} else if tempFilterToken[1] == "false" {
isDangling = false
} else {
return nil, fmt.Errorf("invalid filter %q", filter)
}
f.Dangling = &isDangling
} else if tempFilterToken[0] == FilterBeforeType {
canonicalRef, err := referenceutil.ParseAny(tempFilterToken[1])
if err != nil {
return nil, err
Expand Down

0 comments on commit 9d79e98

Please sign in to comment.