Skip to content

Commit

Permalink
Change return type of remote.Referrers (#1652)
Browse files Browse the repository at this point in the history
* Change return type of remote.Referrers

Actually using this was cumbersome because it just returns a struct.
This is a breaking change, but I don't think it's a huge deal because
not too many people should be using this yet (and we're < 1.0.0).

* go mod tidy k8schain?
  • Loading branch information
jonjohnsonjr committed Apr 17, 2023
1 parent bc990d6 commit 9aa45a1
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 39 deletions.
2 changes: 2 additions & 0 deletions pkg/authn/k8schain/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.18.5 // indirect
github.com/aws/smithy-go v1.13.5 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
github.com/docker/cli v23.0.1+incompatible // indirect
Expand Down Expand Up @@ -73,6 +74,7 @@ require (
github.com/opencontainers/image-spec v1.1.0-rc2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/vbatts/tar-split v0.11.2 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/oauth2 v0.6.0 // indirect
Expand Down
9 changes: 9 additions & 0 deletions pkg/authn/k8schain/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkg/v1/empty/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,6 @@ func base() *v1.IndexManifest {
return &v1.IndexManifest{
SchemaVersion: 2,
MediaType: types.OCIImageIndex,
Manifests: []v1.Descriptor{},
}
}
2 changes: 1 addition & 1 deletion pkg/v1/mutate/mutate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ func TestAnnotations(t *testing.T) {
}, {
desc: "index",
in: empty.Index,
want: `{"schemaVersion":2,"mediaType":"application/vnd.oci.image.index.v1+json","manifests":null,"annotations":{"foo":"bar"}}`,
want: `{"schemaVersion":2,"mediaType":"application/vnd.oci.image.index.v1+json","manifests":[],"annotations":{"foo":"bar"}}`,
}, {
desc: "arbitrary",
in: arbitrary{},
Expand Down
67 changes: 36 additions & 31 deletions pkg/v1/remote/descriptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package remote
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
Expand All @@ -31,6 +30,8 @@ import (
"github.com/google/go-containerregistry/pkg/logs"
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/empty"
"github.com/google/go-containerregistry/pkg/v1/mutate"
"github.com/google/go-containerregistry/pkg/v1/partial"
"github.com/google/go-containerregistry/pkg/v1/remote/transport"
"github.com/google/go-containerregistry/pkg/v1/types"
Expand Down Expand Up @@ -301,7 +302,7 @@ func fallbackTag(d name.Digest) name.Tag {
return d.Context().Tag(strings.Replace(d.DigestStr(), ":", "-", 1))
}

func (f *fetcher) fetchReferrers(ctx context.Context, filter map[string]string, d name.Digest) (*v1.IndexManifest, error) {
func (f *fetcher) fetchReferrers(ctx context.Context, filter map[string]string, d name.Digest) (v1.ImageIndex, error) {
// Check the Referrers API endpoint first.
u := f.url("referrers", d.DigestStr())
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
Expand All @@ -319,32 +320,40 @@ func (f *fetcher) fetchReferrers(ctx context.Context, filter map[string]string,
if err := transport.CheckError(resp, http.StatusOK, http.StatusNotFound, http.StatusBadRequest); err != nil {
return nil, err
}

var b []byte
if resp.StatusCode == http.StatusOK {
var im v1.IndexManifest
if err := json.NewDecoder(resp.Body).Decode(&im); err != nil {
b, err = io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return filterReferrersResponse(filter, &im), nil
}

// The registry doesn't support the Referrers API endpoint, so we'll use the fallback tag scheme.
b, _, err := f.fetchManifest(ctx, fallbackTag(d), []types.MediaType{types.OCIImageIndex})
if err != nil {
} else {
// The registry doesn't support the Referrers API endpoint, so we'll use the fallback tag scheme.
b, _, err = f.fetchManifest(ctx, fallbackTag(d), []types.MediaType{types.OCIImageIndex})
var terr *transport.Error
if ok := errors.As(err, &terr); ok && terr.StatusCode == http.StatusNotFound {
if errors.As(err, &terr) && terr.StatusCode == http.StatusNotFound {
// Not found just means there are no attachments yet. Start with an empty manifest.
return &v1.IndexManifest{MediaType: types.OCIImageIndex}, nil
return empty.Index, nil
} else if err != nil {
return nil, err
}

return nil, err
}

var im v1.IndexManifest
if err := json.Unmarshal(b, &im); err != nil {
h, sz, err := v1.SHA256(bytes.NewReader(b))
if err != nil {
return nil, err
}

return filterReferrersResponse(filter, &im), nil
idx := &remoteIndex{
fetcher: *f,
manifest: b,
mediaType: types.OCIImageIndex,
descriptor: &v1.Descriptor{
Digest: h,
MediaType: types.OCIImageIndex,
Size: sz,
},
}
return filterReferrersResponse(filter, idx), nil
}

func (f *fetcher) fetchManifest(ctx context.Context, ref name.Reference, acceptable []types.MediaType) ([]byte, *v1.Descriptor, error) {
Expand Down Expand Up @@ -551,19 +560,15 @@ func (f *fetcher) blobExists(h v1.Hash) (bool, error) {

// If filter applied, filter out by artifactType.
// See https://github.com/opencontainers/distribution-spec/blob/main/spec.md#listing-referrers
func filterReferrersResponse(filter map[string]string, origIndex *v1.IndexManifest) *v1.IndexManifest {
newIndex := origIndex
func filterReferrersResponse(filter map[string]string, in v1.ImageIndex) v1.ImageIndex {
if filter == nil {
return newIndex
}
if v, ok := filter["artifactType"]; ok {
tmp := []v1.Descriptor{}
for _, desc := range newIndex.Manifests {
if desc.ArtifactType == v {
tmp = append(tmp, desc)
}
}
newIndex.Manifests = tmp
return in
}
v, ok := filter["artifactType"]
if !ok {
return in
}
return newIndex
return mutate.RemoveManifests(in, func(desc v1.Descriptor) bool {
return desc.ArtifactType != v
})
}
2 changes: 1 addition & 1 deletion pkg/v1/remote/referrers.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
// Referrers returns a list of descriptors that refer to the given manifest digest.
//
// The subject manifest doesn't have to exist in the registry for there to be descriptors that refer to it.
func Referrers(d name.Digest, options ...Option) (*v1.IndexManifest, error) {
func Referrers(d name.Digest, options ...Option) (v1.ImageIndex, error) {
o, err := makeOptions(options...)
if err != nil {
return nil, err
Expand Down
37 changes: 31 additions & 6 deletions pkg/v1/remote/referrers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,11 @@ func TestReferrers(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if numManifests := len(index.Manifests); numManifests != 0 {
m, err := index.IndexManifest()
if err != nil {
t.Fatal(err)
}
if numManifests := len(m.Manifests); numManifests != 0 {
t.Fatalf("expected index to contain 0 manifests, but had %d", numManifests)
}

Expand All @@ -126,7 +130,12 @@ func TestReferrers(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if d := cmp.Diff([]v1.Descriptor{leafDesc}, index.Manifests); d != "" {
m2, err := index.IndexManifest()
if err != nil {
t.Fatal(err)
}
if d := cmp.Diff([]v1.Descriptor{leafDesc}, m2.Manifests); d != "" {
t.Logf("m2.Manifests: %v", m2.Manifests)
t.Fatalf("referrers diff (-want,+got): %s", d)
}

Expand All @@ -144,7 +153,11 @@ func TestReferrers(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if d := cmp.Diff(index.Manifests, mf.Manifests); d != "" {
m2, err := index.IndexManifest()
if err != nil {
t.Fatal(err)
}
if d := cmp.Diff(m2.Manifests, mf.Manifests); d != "" {
t.Fatalf("fallback tag diff (-want,+got): %s", d)
}
}
Expand All @@ -166,7 +179,11 @@ func TestReferrers(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if d := cmp.Diff([]v1.Descriptor{leafDesc}, index.Manifests); d != "" {
m3, err := index.IndexManifest()
if err != nil {
t.Fatal(err)
}
if d := cmp.Diff([]v1.Descriptor{leafDesc}, m3.Manifests); d != "" {
t.Fatalf("referrers diff after second push (-want,+got): %s", d)
}

Expand All @@ -176,7 +193,11 @@ func TestReferrers(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if numManifests := len(index.Manifests); numManifests == 0 {
m4, err := index.IndexManifest()
if err != nil {
t.Fatal(err)
}
if numManifests := len(m4.Manifests); numManifests == 0 {
t.Fatal("index contained 0 manifests")
}

Expand All @@ -185,7 +206,11 @@ func TestReferrers(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if numManifests := len(index.Manifests); numManifests != 0 {
m5, err := index.IndexManifest()
if err != nil {
t.Fatal(err)
}
if numManifests := len(m5.Manifests); numManifests != 0 {
t.Fatalf("expected index to contain 0 manifests, but had %d", numManifests)
}
}
Expand Down

0 comments on commit 9aa45a1

Please sign in to comment.