Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter dangling images using image filters. #1785

Merged
merged 1 commit into from
Dec 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Contributor Author

@manugupt1 manugupt1 Dec 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every time there is a <none> image listed out; this Warning is printed out; I think we should not do it; now that we are adding more support for dangling images.

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