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 a682aa1
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 2 deletions.
21 changes: 21 additions & 0 deletions cmd/nerdctl/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ func imagesAction(cmd *cobra.Command, args []string) error {
return err
}

imageList = filterDangling(imageList, f.Dangling)

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

func filterDangling(imageList []images.Image, dangling imgutil.Dangling) []images.Image {
if dangling == imgutil.DanglingUnset {
return imageList
}

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

if dangling == imgutil.DanglingTrue && tag == "" {
filtered = append(filtered, image)
}
if dangling == imgutil.DanglingFalse && 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 TestDanglingImagesFilter(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>")
}
22 changes: 20 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 @@ -383,11 +384,20 @@ func ParseRepoTag(imgName string) (string, string) {
return repository, tag
}

type Dangling int

const (
DanglingUnset Dangling = iota
DanglingTrue
DanglingFalse
)

type Filters struct {
Before []string
Since []string
Labels map[string]string
Reference []string
Dangling Dangling
}

func ParseFilters(filters []string) (*Filters, error) {
Expand All @@ -398,7 +408,15 @@ 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 {
if strings.EqualFold(tempFilterToken[1], "true") {
f.Dangling = DanglingTrue
} else if strings.EqualFold(tempFilterToken[1], "false") {
f.Dangling = DanglingFalse
} else {
return nil, fmt.Errorf("invalid filter %q", filter)
}
} else if tempFilterToken[0] == FilterBeforeType {
canonicalRef, err := referenceutil.ParseAny(tempFilterToken[1])
if err != nil {
return nil, err
Expand Down

0 comments on commit a682aa1

Please sign in to comment.