Skip to content

Commit 863398c

Browse files
committed
imagetools: pass referrer filter opts to oci-layout path
FetchReferrers accepted FetchReferrersOpt but dropped them when resolving OCI layout referrers. Forward the options and apply ArtifactTypes filtering so callers can narrow results consistently for both registry and local layout sources. Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
1 parent 6eb48d9 commit 863398c

3 files changed

Lines changed: 77 additions & 3 deletions

File tree

util/imagetools/inspect.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ func (r *Resolver) localStore(path string) (content.Store, error) {
172172

173173
func (r *Resolver) FetchReferrers(ctx context.Context, loc *Location, dgst digest.Digest, opts ...remotes.FetchReferrersOpt) ([]ocispecs.Descriptor, error) {
174174
if loc.IsOCILayout() {
175-
return fetchOCILayoutReferrers(ctx, r.GetDescriptor, loc, dgst)
175+
return fetchOCILayoutReferrers(ctx, r.GetDescriptor, loc, dgst, opts...)
176176
}
177177
f, err := r.registryResolver().Fetcher(ctx, loc.String())
178178
if err != nil {

util/imagetools/inspect_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package imagetools
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/containerd/containerd/v2/core/images"
8+
"github.com/containerd/containerd/v2/core/remotes"
9+
"github.com/moby/buildkit/client/ociindex"
10+
"github.com/opencontainers/go-digest"
11+
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
12+
"github.com/stretchr/testify/require"
13+
)
14+
15+
func TestFetchReferrersOCILayoutArtifactTypeFilter(t *testing.T) {
16+
t.Parallel()
17+
18+
dir := t.TempDir()
19+
idx := ociindex.NewStoreIndex(dir)
20+
subject := digest.FromString("subject")
21+
22+
attestation := ocispecs.Descriptor{
23+
MediaType: ocispecs.MediaTypeImageManifest,
24+
ArtifactType: artifactTypeAttestationManifest,
25+
Digest: digest.FromString("attestation"),
26+
Size: 123,
27+
Annotations: map[string]string{
28+
images.AnnotationManifestSubject: subject.String(),
29+
},
30+
}
31+
require.NoError(t, idx.Put(attestation))
32+
33+
signature := ocispecs.Descriptor{
34+
MediaType: ocispecs.MediaTypeImageManifest,
35+
ArtifactType: "application/vnd.dev.sigstore.bundle.v0.3+json",
36+
Digest: digest.FromString("signature"),
37+
Size: 456,
38+
Annotations: map[string]string{
39+
images.AnnotationManifestSubject: subject.String(),
40+
},
41+
}
42+
require.NoError(t, idx.Put(signature))
43+
44+
loc, err := ParseLocation("oci-layout://" + dir + ":latest")
45+
require.NoError(t, err)
46+
47+
r := New(Opt{})
48+
refs, err := r.FetchReferrers(context.Background(), loc, subject, remotes.WithReferrerArtifactTypes(artifactTypeAttestationManifest))
49+
require.NoError(t, err)
50+
require.Len(t, refs, 1)
51+
require.Equal(t, attestation.Digest, refs[0].Digest)
52+
require.Equal(t, attestation.ArtifactType, refs[0].ArtifactType)
53+
}

util/imagetools/ocilayout_referrers.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ package imagetools
33
import (
44
"context"
55
"encoding/json"
6+
"slices"
67
"sync"
78

89
"github.com/containerd/containerd/v2/core/images"
10+
"github.com/containerd/containerd/v2/core/remotes"
911
"github.com/containerd/errdefs"
1012
"github.com/moby/buildkit/client/ociindex"
1113
"github.com/moby/buildkit/util/attestation"
@@ -54,7 +56,7 @@ func hasSubjectAnnotation(desc ocispecs.Descriptor) bool {
5456
// fetchOCILayoutReferrers resolves referrers for a subject from an OCI layout by
5557
// combining directly indexed subject entries with referrers reachable from the
5658
// regular named roots in index.json.
57-
func fetchOCILayoutReferrers(ctx context.Context, getDescriptor func(context.Context, *Location, ocispecs.Descriptor) ([]byte, error), loc *Location, subject digest.Digest) ([]ocispecs.Descriptor, error) {
59+
func fetchOCILayoutReferrers(ctx context.Context, getDescriptor func(context.Context, *Location, ocispecs.Descriptor) ([]byte, error), loc *Location, subject digest.Digest, opts ...remotes.FetchReferrersOpt) ([]ocispecs.Descriptor, error) {
5860
idx, err := ociindex.NewStoreIndex(loc.OCILayout().Path).Read()
5961
if err != nil {
6062
return nil, err
@@ -84,7 +86,26 @@ func fetchOCILayoutReferrers(ctx context.Context, getDescriptor func(context.Con
8486
for _, desc := range out {
8587
refs = append(refs, desc)
8688
}
87-
return refs, nil
89+
return filterOCILayoutReferrers(ctx, refs, opts...)
90+
}
91+
92+
func filterOCILayoutReferrers(ctx context.Context, refs []ocispecs.Descriptor, opts ...remotes.FetchReferrersOpt) ([]ocispecs.Descriptor, error) {
93+
var cfg remotes.FetchReferrersConfig
94+
for _, opt := range opts {
95+
if err := opt(ctx, &cfg); err != nil {
96+
return nil, err
97+
}
98+
}
99+
if len(cfg.ArtifactTypes) == 0 {
100+
return refs, nil
101+
}
102+
out := make([]ocispecs.Descriptor, 0, len(refs))
103+
for _, ref := range refs {
104+
if slices.Contains(cfg.ArtifactTypes, ref.ArtifactType) {
105+
out = append(out, ref)
106+
}
107+
}
108+
return out, nil
88109
}
89110

90111
// collectReachableOCILayoutReferrers walks a regular OCI layout root and records

0 commit comments

Comments
 (0)