Skip to content

Fix unexpected results when filtering images #2413

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Honny1
Copy link
Member

@Honny1 Honny1 commented Apr 7, 2025

The filtered image contains all Names of image. This causes the podman to list images that are not expected.

For example:
If an image box:latest is taged as example:latest and then images are filtered with reference=example, box:latest and example:latest will be output because the image has multiple names.

Fixes: containers/podman#25725
Fixes: https://issues.redhat.com/browse/RUN-2726

Copy link
Contributor

@mtrmac mtrmac left a comment

Choose a reason for hiding this comment

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

The imageMatchesReferenceFilter logic LGTM, that makes sense. The design of the upper parts of the call stack needs a bit of cleanup.

@Honny1 Honny1 force-pushed the list-images branch 4 times, most recently from 3e00335 to 8dd85f6 Compare April 8, 2025 17:37
if lookedUp != nil {
if lookedUp.ID() == img.ID() {
return true, nil
resolvedName, _, _ := strings.Cut(resolvedName, "@")
Copy link
Contributor

Choose a reason for hiding this comment

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

What is this doing?

In the later loop, when we are making various imprecise matches, the return value is the full refString. This seems to be dropping digests from the returned values. Why?

Copy link
Contributor

Choose a reason for hiding this comment

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

I still have no idea what this is doing. AFAICS LookupImage can easily be a (precise) repo:tag or repo@digest match. And the range refs loop below always collects the precise ref.String() values that match. Why is this ignoring the digest part (if that is what it is) and returning all tags (if that is what it is)?

And, even apart from the again, HasPrefix just looks implausible. Why should example.com/a match example.com/ab?

Copy link
Member Author

Choose a reason for hiding this comment

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

I only want to return names that match the name if the name@digest reference format is used.

So, for example, for an image with the following names:

  • quay.io/libpod/alpine:latest
  • quay.io/libpod/al:latest
  • quay.io/libpod/al:tag

I expect the result for filtering with the al@digest reference, these names:

  • quay.io/libpod/al:latest
  • quay.io/libpod/al:tag

Usage HasPrefix is wrong. I fixed that.

@Honny1 Honny1 force-pushed the list-images branch 7 times, most recently from f644901 to c1d4722 Compare April 9, 2025 21:18
@Honny1 Honny1 requested a review from mtrmac April 9, 2025 21:31
@Honny1
Copy link
Member Author

Honny1 commented Apr 14, 2025

PTAL @mtrmac

@Honny1 Honny1 requested a review from Luap99 April 16, 2025 08:21
Copy link
Member

@Luap99 Luap99 left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

openshift-ci bot commented Apr 16, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Honny1, Luap99

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

// and an AND logic for negative matches
ReferenceFilter: filterReferences(r, wantedReferenceMatches, unwantedReferenceMatches),
}
return &cf, needsLayerTree, nil
Copy link
Contributor

Choose a reason for hiding this comment

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

(Absolutely non-blocking: Even the needsLayerTree value could be returned in the struct; that would turn an unnamed bool return value into a named one, and shorten the error paths. That’s unrelated to this PR.)

cf := compiledFilters{
Filters: filters,
// reference filters is a special case as it does an OR for positive matches
// and an AND logic for negative matches
Copy link
Contributor

Choose a reason for hiding this comment

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

… and the filter function type is different.

Comment on lines 32 to 33
Filters map[string][]filterFunc
ReferenceFilter referenceFilterFunc
Copy link
Contributor

Choose a reason for hiding this comment

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

(Absolutely non-blocking: The field names can be package-private. I expect the compiler can figure that out itself.)

Comment on lines 318 to 326
// If there are no wanted match filters, then return false for the image
// that matched the unwanted value otherwise return true
if len(wantedReferenceMatches) == 0 {
return !unwantedMatched, nil
return !unwantedMatched, namesThatMatch, nil
}

if unwantedMatched {
return false, nil, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

(Absolutely non-blocking: possible refactoring steps:

  • if unwantedMatched { return false }; if len(wantedRM) == 0 { return true }
  • Then replace unwantedMatched by an early return from the loop.

This is pre-existing.)

}
matchedNames = append(matchedNames, names...)
}
if len(matchedNames) > 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Non-blocking: Conceptually matchedNames is a set, and implementing that as a map[string]struct{} would make this O(N) instead of O(N^2). Probably doesn’t matter in practice.

}
if len(matchedNames) > 0 {
// Removes non-compliant names from image names
namesThatMatch = slices.DeleteFunc(namesThatMatch, func(name string) bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

slices.DeleteFunc edits a slice in-place. namesThatMatch directly points into Image.Names, it is not a private copy, so it should not be modified in-place.

(Moving the namesThatMatch initialization much closer to these lines would make that a tiny bit easier to see, please do so.)

if lookedUp != nil {
if lookedUp.ID() == img.ID() {
return true, nil
resolvedName, _, _ := strings.Cut(resolvedName, "@")
Copy link
Contributor

Choose a reason for hiding this comment

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

I still have no idea what this is doing. AFAICS LookupImage can easily be a (precise) repo:tag or repo@digest match. And the range refs loop below always collects the precise ref.String() values that match. Why is this ignoring the digest part (if that is what it is) and returning all tags (if that is what it is)?

And, even apart from the again, HasPrefix just looks implausible. Why should example.com/a match example.com/ab?

@Honny1 Honny1 force-pushed the list-images branch 2 times, most recently from fb462fe to 3d1f37e Compare April 17, 2025 12:54
The filtered image contains all Names of image. This causes the podman to list images that are not expected.

For example:
If an image `box:latest` is taged as `example:latest` and then images are filtered with `reference=example`, `box:latest` and `example:latest` will be output because the image has multiple names.

Fixes: containers/podman#25725
Fixes: https://issues.redhat.com/browse/RUN-2726

Signed-off-by: Jan Rodák <[email protected]>
@Honny1
Copy link
Member Author

Honny1 commented Apr 17, 2025

@mtrmac PTAL, I have implemented your feedback.

@Honny1 Honny1 requested a review from mtrmac April 17, 2025 13:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

podman images <image> can show duplicate results
3 participants