-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Add referrers fetcher to remotes #12309
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
Conversation
core/remotes/docker/referrers.go
Outdated
| desc.Size = cl | ||
| // Digest is not known ahead of time and there is nothing in the distribution | ||
| // specification defining an HTTP header to return the digest on referrers. | ||
| return rc, desc, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this descriptor? What's the use case of returning Descriptor without a Digest (other than hoping to cause a panic in the caller)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original idea was the caller would fill this in and use it to save the referrers index, however I think we discussed that we probably don't want to save the referrers index at all. We could return the index directly, we just don't currently use those parsed objects at this level of the interface normally.
And other places we do use partial descriptors for content verification, it can certainly be a trap for callers though.
fc864f5 to
c33374d
Compare
core/remotes/docker/referrers.go
Outdated
| defer rc.Close() | ||
|
|
||
| var index ocispec.Index | ||
| if err := json.NewDecoder(io.LimitReader(rc, size)).Decode(&index); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Safe usage of json.NewDecoder requires calling smth like
if _, err := dec.Token(); !errors.Is(err, io.EOF) {
return nil, errors.Errorf("unexpected data after JSON object")
}
after Decode. No actual security issue in here, just potentially not validating garbage data from registry.
| ocispec "github.com/opencontainers/image-spec/specs-go/v1" | ||
| ) | ||
|
|
||
| func (r dockerFetcher) FetchReferrers(ctx context.Context, dgst digest.Digest, artifactTypes ...string) ([]ocispec.Descriptor, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you change this to take descriptor instead of digest I could avoid defining https://github.com/containerd/containerd/compare/main...tonistiigi:containerd:referrers-wip?expand=1#diff-85dea1ce2bec55085339d4ec90127de60f896bae284b627e7c03c1ff7bcb6533R214 and just use remotes. ReferrersFetcher as input to puller/exporter etc. Ok if you wish to keep them separate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, when are the artifact types injected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The callbacks in client will always set it to empty (as containerd library should not be opinionated about what referrers should be included) but provider interface implementation can add its own filters. I you prefer to keep callback interface separate (and without the artifacttype), then that is fine by me.
| } | ||
| } | ||
|
|
||
| for i, host := range fallbackHosts { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally there should be a way to opt-out of this fallback mechanism as eventually this should die and polluting repositories with these tags should stop. Maybe an item in ResolverOptions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could just avoid populating the fallback hosts if there are any referrers hosts
core/remotes/docker/referrers.go
Outdated
| if err := json.NewDecoder(io.LimitReader(rc, size)).Decode(&index); err != nil { | ||
| return nil, fmt.Errorf("failed to decode referrers index: %w", err) | ||
| } | ||
| return index.Manifests, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As matching the artifactType is not guaranteed, then this should reapply the filter manually before returning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated, if artifact is missing from a descriptor, it will include
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why skip the filter the user asked for, if not defined? Btw, the spec defines some response headers for this as well https://github.com/opencontainers/distribution-spec/blob/main/spec.md#listing-referrers (I don't quite get what benefit they provide).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to omit empty artifact types when artifact filters provided
If filtering is requested and applied, the response MUST include a header OCI-Filters-Applied: artifactType denoting that an artifactType filter was applied. If multiple filters are applied, the header MUST contain a comma separated list of applied filters.
I don't think there is anything we would want to do with this on our side, maybe just useful for caching or head requests.
3570a21 to
ddf479c
Compare
ddf479c to
984b99a
Compare
estesp
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit about an error message, but otherwise LGTM
Adds an implementation of the referrers API from OCI distribution-spec 1.1. Signed-off-by: Derek McGowan <derek@mcg.dev>
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Signed-off-by: Derek McGowan <derek@mcg.dev>
Signed-off-by: Derek McGowan <derek@mcg.dev>
984b99a to
a7537cb
Compare
| ocispec "github.com/opencontainers/image-spec/specs-go/v1" | ||
| ) | ||
|
|
||
| func (r dockerFetcher) FetchReferrers(ctx context.Context, dgst digest.Digest, artifactTypes ...string) ([]ocispec.Descriptor, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dmcgowan Has the FetchReferrers function not been called yet? I don't see any references to it (except for the test function).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently being used by BuildKit. How we want to integrate it into transfer service and image validation still needs to be decided.
Adds an implementation of the referrers API from OCI distribution-spec 1.1.
Update from #7644