From 0ab7f326e651981d0c73191b6e8f8fc671533c11 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 6 Sep 2024 11:59:19 +0200 Subject: [PATCH] replace uses of Descriptor alias Signed-off-by: Sebastiaan van Stijn --- blobs.go | 10 +-- internal/client/blob_writer.go | 9 +-- internal/client/repository.go | 67 ++++++++++--------- internal/client/repository_test.go | 14 ++-- manifest/manifestlist/manifestlist.go | 14 ++-- manifest/manifestlist/manifestlist_test.go | 11 ++- manifest/ocischema/builder.go | 8 +-- manifest/ocischema/builder_test.go | 16 ++--- manifest/ocischema/index.go | 20 +++--- manifest/ocischema/index_test.go | 10 +-- manifest/ocischema/manifest.go | 18 ++--- manifest/ocischema/manifest_test.go | 13 ++-- manifest/schema2/builder.go | 13 ++-- manifest/schema2/builder_test.go | 8 +-- manifest/schema2/manifest.go | 17 ++--- manifest/schema2/manifest_test.go | 5 +- manifests.go | 15 +++-- notifications/bridge.go | 11 +-- notifications/bridge_test.go | 2 +- notifications/event.go | 6 +- notifications/listener.go | 11 +-- notifications/listener_test.go | 13 ++-- registry/handlers/api_test.go | 15 +++-- registry/handlers/blobupload.go | 5 +- registry/handlers/manifests.go | 2 +- registry/proxy/proxyblobstore.go | 23 ++++--- registry/proxy/proxyblobstore_test.go | 9 +-- registry/proxy/proxymanifeststore_test.go | 3 +- registry/proxy/proxytagservice.go | 11 +-- registry/proxy/proxytagservice_test.go | 23 ++++--- registry/storage/blob_test.go | 17 ++--- registry/storage/blobstore.go | 23 ++++--- registry/storage/blobwriter.go | 35 +++++----- registry/storage/cache/cache.go | 3 +- registry/storage/cache/cache_test.go | 21 +++--- registry/storage/cache/cachecheck/suite.go | 9 +-- .../cache/cachedblobdescriptorstore.go | 5 +- registry/storage/cache/memory/memory.go | 21 +++--- registry/storage/cache/metrics/prom.go | 9 +-- registry/storage/cache/redis/redis.go | 41 ++++++------ registry/storage/garbagecollect.go | 3 +- registry/storage/garbagecollect_test.go | 19 +++--- registry/storage/linkedblobstore.go | 31 ++++----- registry/storage/linkedblobstore_test.go | 15 +++-- registry/storage/manifestlisthandler.go | 3 +- registry/storage/manifeststore_test.go | 28 ++++---- registry/storage/ocimanifesthandler_test.go | 32 ++++----- .../storage/schema2manifesthandler_test.go | 31 ++++----- registry/storage/tagstore.go | 17 ++--- registry/storage/tagstore_test.go | 15 +++-- tags.go | 7 +- testutil/manifests.go | 5 +- testutil/push.go | 3 +- testutil/tarfile.go | 3 +- 54 files changed, 417 insertions(+), 381 deletions(-) diff --git a/blobs.go b/blobs.go index bf6999706d0..3de30b59209 100644 --- a/blobs.go +++ b/blobs.go @@ -68,7 +68,7 @@ type Descriptor = v1.Descriptor type BlobStatter interface { // Stat provides metadata about a blob identified by the digest. If the // blob is unknown to the describer, ErrBlobUnknown will be returned. - Stat(ctx context.Context, dgst digest.Digest) (Descriptor, error) + Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) } // BlobDeleter enables deleting blobs from storage. @@ -97,7 +97,7 @@ type BlobDescriptorService interface { // Such a facility can be used to map blobs between digest domains, with // the restriction that the algorithm of the descriptor must match the // canonical algorithm (ie sha256) of the annotator. - SetDescriptor(ctx context.Context, dgst digest.Digest, desc Descriptor) error + SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error // Clear enables descriptors to be unlinked Clear(ctx context.Context, dgst digest.Digest) error @@ -139,7 +139,7 @@ type BlobServer interface { type BlobIngester interface { // Put inserts the content p into the blob service, returning a descriptor // or an error. - Put(ctx context.Context, mediaType string, p []byte) (Descriptor, error) + Put(ctx context.Context, mediaType string, p []byte) (v1.Descriptor, error) // Create allocates a new blob writer to add a blob to this service. The // returned handle can be written to and later resumed using an opaque @@ -168,7 +168,7 @@ type CreateOptions struct { From reference.Canonical // Stat allows to pass precalculated descriptor to link and return. // Blob access check will be skipped if set. - Stat *Descriptor + Stat *v1.Descriptor } } @@ -198,7 +198,7 @@ type BlobWriter interface { // stream" to the blob. The returned descriptor may have a different // digest depending on the blob store, referred to as the canonical // descriptor. - Commit(ctx context.Context, provisional Descriptor) (canonical Descriptor, err error) + Commit(ctx context.Context, provisional v1.Descriptor) (canonical v1.Descriptor, err error) // Cancel ends the blob write without storing any data and frees any // associated resources. Any data written thus far will be lost. Cancel diff --git a/internal/client/blob_writer.go b/internal/client/blob_writer.go index f85c84f7159..a4a9cdec544 100644 --- a/internal/client/blob_writer.go +++ b/internal/client/blob_writer.go @@ -9,6 +9,7 @@ import ( "time" "github.com/distribution/distribution/v3" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) type httpBlobUpload struct { @@ -120,11 +121,11 @@ func (hbu *httpBlobUpload) StartedAt() time.Time { return hbu.startedAt } -func (hbu *httpBlobUpload) Commit(ctx context.Context, desc distribution.Descriptor) (distribution.Descriptor, error) { +func (hbu *httpBlobUpload) Commit(ctx context.Context, desc v1.Descriptor) (v1.Descriptor, error) { // TODO(dmcgowan): Check if already finished, if so just fetch req, err := http.NewRequestWithContext(hbu.ctx, http.MethodPut, hbu.location, nil) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } values := req.URL.Query() @@ -133,12 +134,12 @@ func (hbu *httpBlobUpload) Commit(ctx context.Context, desc distribution.Descrip resp, err := hbu.client.Do(req) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } defer resp.Body.Close() if err := hbu.handleErrorResponse(resp); err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } return hbu.statter.Stat(ctx, desc.Digest) diff --git a/internal/client/repository.go b/internal/client/repository.go index 4080ec13483..4f86593068c 100644 --- a/internal/client/repository.go +++ b/internal/client/repository.go @@ -21,6 +21,7 @@ import ( "github.com/distribution/distribution/v3/registry/storage/cache/memory" "github.com/distribution/reference" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // Registry provides an interface for calling Repositories, which returns a catalog of repositories. @@ -249,13 +250,13 @@ func (t *tags) All(ctx context.Context) ([]string, error) { } } -func descriptorFromResponse(response *http.Response) (distribution.Descriptor, error) { - desc := distribution.Descriptor{} +func descriptorFromResponse(response *http.Response) (v1.Descriptor, error) { + desc := v1.Descriptor{} headers := response.Header ctHeader := headers.Get("Content-Type") if ctHeader == "" { - return distribution.Descriptor{}, errors.New("missing or empty Content-Type header") + return v1.Descriptor{}, errors.New("missing or empty Content-Type header") } desc.MediaType = ctHeader @@ -263,28 +264,28 @@ func descriptorFromResponse(response *http.Response) (distribution.Descriptor, e if digestHeader == "" { data, err := io.ReadAll(response.Body) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } _, desc, err := distribution.UnmarshalManifest(ctHeader, data) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } return desc, nil } dgst, err := digest.Parse(digestHeader) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } desc.Digest = dgst lengthHeader := headers.Get("Content-Length") if lengthHeader == "" { - return distribution.Descriptor{}, errors.New("missing or empty Content-Length header") + return v1.Descriptor{}, errors.New("missing or empty Content-Length header") } length, err := strconv.ParseInt(lengthHeader, 10, 64) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } desc.Size = length @@ -294,14 +295,14 @@ func descriptorFromResponse(response *http.Response) (distribution.Descriptor, e // Get issues a HEAD request for a Manifest against its named endpoint in order // to construct a descriptor for the tag. If the registry doesn't support HEADing // a manifest, fallback to GET. -func (t *tags) Get(ctx context.Context, tag string) (distribution.Descriptor, error) { +func (t *tags) Get(ctx context.Context, tag string) (v1.Descriptor, error) { ref, err := reference.WithTag(t.name, tag) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } u, err := t.ub.BuildManifestURL(ref) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } newRequest := func(method string) (*http.Response, error) { @@ -319,7 +320,7 @@ func (t *tags) Get(ctx context.Context, tag string) (distribution.Descriptor, er resp, err := newRequest(http.MethodHead) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } defer resp.Body.Close() @@ -334,22 +335,22 @@ func (t *tags) Get(ctx context.Context, tag string) (distribution.Descriptor, er // - to get error details in case of a failure resp, err = newRequest(http.MethodGet) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } defer resp.Body.Close() if resp.StatusCode >= 200 && resp.StatusCode < 400 { return descriptorFromResponse(resp) } - return distribution.Descriptor{}, HandleHTTPResponseError(resp) + return v1.Descriptor{}, HandleHTTPResponseError(resp) } } -func (t *tags) Lookup(ctx context.Context, digest distribution.Descriptor) ([]string, error) { +func (t *tags) Lookup(ctx context.Context, digest v1.Descriptor) ([]string, error) { panic("not implemented") } -func (t *tags) Tag(ctx context.Context, tag string, desc distribution.Descriptor) error { +func (t *tags) Tag(ctx context.Context, tag string, desc v1.Descriptor) error { panic("not implemented") } @@ -654,7 +655,7 @@ func sanitizeLocation(location, base string) (string, error) { return baseURL.ResolveReference(locationURL).String(), nil } -func (bs *blobs) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (bs *blobs) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { return bs.statter.Stat(ctx, dgst) } @@ -711,21 +712,21 @@ func (bs *blobs) ServeBlob(ctx context.Context, w http.ResponseWriter, r *http.R return err } -func (bs *blobs) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) { +func (bs *blobs) Put(ctx context.Context, mediaType string, p []byte) (v1.Descriptor, error) { writer, err := bs.Create(ctx) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } dgstr := digest.Canonical.Digester() n, err := io.Copy(writer, io.TeeReader(bytes.NewReader(p), dgstr.Hash())) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } if n < int64(len(p)) { - return distribution.Descriptor{}, fmt.Errorf("short copy: wrote %d of %d", n, len(p)) + return v1.Descriptor{}, fmt.Errorf("short copy: wrote %d of %d", n, len(p)) } - return writer.Commit(ctx, distribution.Descriptor{ + return writer.Commit(ctx, v1.Descriptor{ MediaType: mediaType, Size: int64(len(p)), Digest: dgstr.Digest(), @@ -848,45 +849,45 @@ type blobStatter struct { client *http.Client } -func (bs *blobStatter) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (bs *blobStatter) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { ref, err := reference.WithDigest(bs.name, dgst) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } u, err := bs.ub.BuildBlobURL(ref) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } req, err := http.NewRequestWithContext(ctx, http.MethodHead, u, nil) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } resp, err := bs.client.Do(req) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } defer resp.Body.Close() if resp.StatusCode == http.StatusNotFound { - return distribution.Descriptor{}, distribution.ErrBlobUnknown + return v1.Descriptor{}, distribution.ErrBlobUnknown } if err := HandleHTTPResponseError(resp); err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } lengthHeader := resp.Header.Get("Content-Length") if lengthHeader == "" { - return distribution.Descriptor{}, fmt.Errorf("missing content-length header for request: %s", u) + return v1.Descriptor{}, fmt.Errorf("missing content-length header for request: %s", u) } length, err := strconv.ParseInt(lengthHeader, 10, 64) if err != nil { - return distribution.Descriptor{}, fmt.Errorf("error parsing content-length: %v", err) + return v1.Descriptor{}, fmt.Errorf("error parsing content-length: %v", err) } - return distribution.Descriptor{ + return v1.Descriptor{ MediaType: resp.Header.Get("Content-Type"), Size: length, Digest: dgst, @@ -931,6 +932,6 @@ func (bs *blobStatter) Clear(ctx context.Context, dgst digest.Digest) error { return HandleHTTPResponseError(resp) } -func (bs *blobStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error { +func (bs *blobStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error { return nil } diff --git a/internal/client/repository_test.go b/internal/client/repository_test.go index 1859edc9efc..2135121f333 100644 --- a/internal/client/repository_test.go +++ b/internal/client/repository_test.go @@ -274,7 +274,7 @@ func TestBlobResume(t *testing.T) { t.Fatalf("Unexpected ReadFrom length: %d; expected: %d", n, len(b1)) } - blob, err := upload.Commit(ctx, distribution.Descriptor{ + blob, err := upload.Commit(ctx, v1.Descriptor{ Digest: dgst, Size: int64(len(b1)), }) @@ -538,7 +538,7 @@ func TestBlobUploadChunked(t *testing.T) { } } - blob, err := upload.Commit(ctx, distribution.Descriptor{ + blob, err := upload.Commit(ctx, v1.Descriptor{ Digest: dgst, Size: int64(len(b1)), }) @@ -646,7 +646,7 @@ func TestBlobUploadMonolithic(t *testing.T) { t.Fatalf("Unexpected ReadFrom length: %d; expected: %d", n, len(b1)) } - blob, err := upload.Commit(ctx, distribution.Descriptor{ + blob, err := upload.Commit(ctx, v1.Descriptor{ Digest: dgst, Size: int64(len(b1)), }) @@ -752,7 +752,7 @@ func TestBlobUploadMonolithicDockerUploadUUIDFromURL(t *testing.T) { t.Fatalf("Unexpected ReadFrom length: %d; expected: %d", n, len(b1)) } - blob, err := upload.Commit(ctx, distribution.Descriptor{ + blob, err := upload.Commit(ctx, v1.Descriptor{ Digest: dgst, Size: int64(len(b1)), }) @@ -917,10 +917,10 @@ func TestBlobMount(t *testing.T) { } func newRandomOCIManifest(t *testing.T, blobCount int) (*ocischema.Manifest, digest.Digest, []byte) { - layers := make([]distribution.Descriptor, blobCount) + layers := make([]v1.Descriptor, blobCount) for i := 0; i < blobCount; i++ { dgst, blob := newRandomBlob((i % 5) * 16) - layers[i] = distribution.Descriptor{ + layers[i] = v1.Descriptor{ MediaType: v1.MediaTypeImageLayer, Digest: dgst, Size: int64(len(blob)), @@ -930,7 +930,7 @@ func newRandomOCIManifest(t *testing.T, blobCount int) (*ocischema.Manifest, dig m := ocischema.Manifest{ Versioned: specs.Versioned{SchemaVersion: 2}, MediaType: v1.MediaTypeImageManifest, - Config: distribution.Descriptor{ + Config: v1.Descriptor{ Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Size: 123, MediaType: v1.MediaTypeImageConfig, diff --git a/manifest/manifestlist/manifestlist.go b/manifest/manifestlist/manifestlist.go index 1fcd7bf3458..4752331ab1f 100644 --- a/manifest/manifestlist/manifestlist.go +++ b/manifest/manifestlist/manifestlist.go @@ -35,17 +35,17 @@ func init() { } } -func unmarshalManifestList(b []byte) (distribution.Manifest, distribution.Descriptor, error) { +func unmarshalManifestList(b []byte) (distribution.Manifest, v1.Descriptor, error) { m := &DeserializedManifestList{} if err := m.UnmarshalJSON(b); err != nil { - return nil, distribution.Descriptor{}, err + return nil, v1.Descriptor{}, err } if m.MediaType != MediaTypeManifestList { - return nil, distribution.Descriptor{}, fmt.Errorf("mediaType in manifest list should be '%s' not '%s'", MediaTypeManifestList, m.MediaType) + return nil, v1.Descriptor{}, fmt.Errorf("mediaType in manifest list should be '%s' not '%s'", MediaTypeManifestList, m.MediaType) } - return m, distribution.Descriptor{ + return m, v1.Descriptor{ Digest: digest.FromBytes(b), Size: int64(len(b)), MediaType: MediaTypeManifestList, @@ -81,7 +81,7 @@ type PlatformSpec struct { // A ManifestDescriptor references a platform-specific manifest. type ManifestDescriptor struct { - distribution.Descriptor + v1.Descriptor // Platform specifies which platform the manifest pointed to by the // descriptor runs on. @@ -101,8 +101,8 @@ type ManifestList struct { // References returns the distribution descriptors for the referenced image // manifests. -func (m ManifestList) References() []distribution.Descriptor { - dependencies := make([]distribution.Descriptor, len(m.Manifests)) +func (m ManifestList) References() []v1.Descriptor { + dependencies := make([]v1.Descriptor, len(m.Manifests)) for i := range m.Manifests { dependencies[i] = m.Manifests[i].Descriptor dependencies[i].Platform = &v1.Platform{ diff --git a/manifest/manifestlist/manifestlist_test.go b/manifest/manifestlist/manifestlist_test.go index 7ef5603ca50..ba8fb005597 100644 --- a/manifest/manifestlist/manifestlist_test.go +++ b/manifest/manifestlist/manifestlist_test.go @@ -8,7 +8,6 @@ import ( "github.com/distribution/distribution/v3" "github.com/distribution/distribution/v3/manifest/schema2" - v1 "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -43,7 +42,7 @@ const expectedManifestListSerialization = `{ func makeTestManifestList(t *testing.T, mediaType string) ([]ManifestDescriptor, *DeserializedManifestList) { manifestDescriptors := []ManifestDescriptor{ { - Descriptor: distribution.Descriptor{ + Descriptor: v1.Descriptor{ MediaType: "application/vnd.docker.distribution.manifest.v2+json", Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Size: 985, @@ -55,7 +54,7 @@ func makeTestManifestList(t *testing.T, mediaType string) ([]ManifestDescriptor, }, }, { - Descriptor: distribution.Descriptor{ + Descriptor: v1.Descriptor{ MediaType: "application/vnd.docker.distribution.manifest.v2+json", Digest: "sha256:6346340964309634683409684360934680934608934608934608934068934608", Size: 2392, @@ -178,12 +177,12 @@ func TestMediaTypes(t *testing.T) { func TestValidateManifestList(t *testing.T) { manifest := schema2.Manifest{ - Config: distribution.Descriptor{Size: 1}, - Layers: []distribution.Descriptor{{Size: 2}}, + Config: v1.Descriptor{Size: 1}, + Layers: []v1.Descriptor{{Size: 2}}, } manifestList := ManifestList{ Manifests: []ManifestDescriptor{ - {Descriptor: distribution.Descriptor{Size: 3}}, + {Descriptor: v1.Descriptor{Size: 3}}, }, } t.Run("valid", func(t *testing.T) { diff --git a/manifest/ocischema/builder.go b/manifest/ocischema/builder.go index b0e8bf117a8..584b620f8c4 100644 --- a/manifest/ocischema/builder.go +++ b/manifest/ocischema/builder.go @@ -20,7 +20,7 @@ type Builder struct { // layers is a list of layer descriptors that gets built by successive // calls to AppendReference. - layers []distribution.Descriptor + layers []v1.Descriptor // Annotations contains arbitrary metadata relating to the targeted content. annotations map[string]string @@ -60,7 +60,7 @@ func (mb *Builder) Build(ctx context.Context) (distribution.Manifest, error) { m := Manifest{ Versioned: specs.Versioned{SchemaVersion: 2}, MediaType: mb.mediaType, - Layers: make([]distribution.Descriptor, len(mb.layers)), + Layers: make([]v1.Descriptor, len(mb.layers)), Annotations: mb.annotations, } copy(m.Layers, mb.layers) @@ -94,12 +94,12 @@ func (mb *Builder) Build(ctx context.Context) (distribution.Manifest, error) { } // AppendReference adds a reference to the current ManifestBuilder. -func (mb *Builder) AppendReference(ref distribution.Descriptor) error { +func (mb *Builder) AppendReference(ref v1.Descriptor) error { mb.layers = append(mb.layers, ref) return nil } // References returns the current references added to this builder. -func (mb *Builder) References() []distribution.Descriptor { +func (mb *Builder) References() []v1.Descriptor { return mb.layers } diff --git a/manifest/ocischema/builder_test.go b/manifest/ocischema/builder_test.go index b147111cbba..aa90df4c95d 100644 --- a/manifest/ocischema/builder_test.go +++ b/manifest/ocischema/builder_test.go @@ -11,19 +11,19 @@ import ( ) type mockBlobService struct { - descriptors map[digest.Digest]distribution.Descriptor + descriptors map[digest.Digest]v1.Descriptor distribution.BlobService } -func (bs *mockBlobService) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (bs *mockBlobService) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { if descriptor, ok := bs.descriptors[dgst]; ok { return descriptor, nil } - return distribution.Descriptor{}, distribution.ErrBlobUnknown + return v1.Descriptor{}, distribution.ErrBlobUnknown } -func (bs *mockBlobService) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) { - d := distribution.Descriptor{ +func (bs *mockBlobService) Put(ctx context.Context, mediaType string, p []byte) (v1.Descriptor, error) { + d := v1.Descriptor{ Digest: digest.FromBytes(p), Size: int64(len(p)), MediaType: "application/octet-stream", @@ -90,7 +90,7 @@ func TestBuilder(t *testing.T) { }`) configDigest := digest.FromBytes(imgJSON) - descriptors := []distribution.Descriptor{ + descriptors := []v1.Descriptor{ { MediaType: v1.MediaTypeImageLayerGzip, Digest: digest.Digest("sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"), @@ -110,7 +110,7 @@ func TestBuilder(t *testing.T) { } annotations := map[string]string{"hot": "potato"} - bs := &mockBlobService{descriptors: make(map[digest.Digest]distribution.Descriptor)} + bs := &mockBlobService{descriptors: make(map[digest.Digest]v1.Descriptor)} builder := NewManifestBuilder(bs, imgJSON, annotations) for _, d := range descriptors { @@ -151,7 +151,7 @@ func TestBuilder(t *testing.T) { } references := manifest.References() - expected := append([]distribution.Descriptor{manifest.Target()}, descriptors...) + expected := append([]v1.Descriptor{manifest.Target()}, descriptors...) if !reflect.DeepEqual(references, expected) { t.Fatal("References() does not match the descriptors added") } diff --git a/manifest/ocischema/index.go b/manifest/ocischema/index.go index 6dffdcd32ce..add766f3e18 100644 --- a/manifest/ocischema/index.go +++ b/manifest/ocischema/index.go @@ -30,21 +30,21 @@ func init() { } } -func unmarshalImageIndex(b []byte) (distribution.Manifest, distribution.Descriptor, error) { +func unmarshalImageIndex(b []byte) (distribution.Manifest, v1.Descriptor, error) { if err := validateIndex(b); err != nil { - return nil, distribution.Descriptor{}, err + return nil, v1.Descriptor{}, err } m := &DeserializedImageIndex{} if err := m.UnmarshalJSON(b); err != nil { - return nil, distribution.Descriptor{}, err + return nil, v1.Descriptor{}, err } if m.MediaType != "" && m.MediaType != v1.MediaTypeImageIndex { - return nil, distribution.Descriptor{}, fmt.Errorf("if present, mediaType in image index should be '%s' not '%s'", v1.MediaTypeImageIndex, m.MediaType) + return nil, v1.Descriptor{}, fmt.Errorf("if present, mediaType in image index should be '%s' not '%s'", v1.MediaTypeImageIndex, m.MediaType) } - return m, distribution.Descriptor{ + return m, v1.Descriptor{ MediaType: v1.MediaTypeImageIndex, Digest: digest.FromBytes(b), Size: int64(len(b)), @@ -60,7 +60,7 @@ type ImageIndex struct { MediaType string `json:"mediaType,omitempty"` // Manifests references a list of manifests - Manifests []distribution.Descriptor `json:"manifests"` + Manifests []v1.Descriptor `json:"manifests"` // Annotations is an optional field that contains arbitrary metadata for the // image index @@ -69,7 +69,7 @@ type ImageIndex struct { // References returns the distribution descriptors for the referenced image // manifests. -func (ii ImageIndex) References() []distribution.Descriptor { +func (ii ImageIndex) References() []v1.Descriptor { return ii.Manifests } @@ -86,19 +86,19 @@ type DeserializedImageIndex struct { // returns a DeserializedManifestList which contains the resulting manifest list // and its JSON representation. If annotations is nil or empty then the // annotations property will be omitted from the JSON representation. -func FromDescriptors(descriptors []distribution.Descriptor, annotations map[string]string) (*DeserializedImageIndex, error) { +func FromDescriptors(descriptors []v1.Descriptor, annotations map[string]string) (*DeserializedImageIndex, error) { return fromDescriptorsWithMediaType(descriptors, annotations, v1.MediaTypeImageIndex) } // fromDescriptorsWithMediaType is for testing purposes, it's useful to be able to specify the media type explicitly -func fromDescriptorsWithMediaType(descriptors []distribution.Descriptor, annotations map[string]string, mediaType string) (_ *DeserializedImageIndex, err error) { +func fromDescriptorsWithMediaType(descriptors []v1.Descriptor, annotations map[string]string, mediaType string) (_ *DeserializedImageIndex, err error) { m := ImageIndex{ Versioned: specs.Versioned{SchemaVersion: 2}, MediaType: mediaType, Annotations: annotations, } - m.Manifests = make([]distribution.Descriptor, len(descriptors)) + m.Manifests = make([]v1.Descriptor, len(descriptors)) copy(m.Manifests, descriptors) deserialized := DeserializedImageIndex{ diff --git a/manifest/ocischema/index_test.go b/manifest/ocischema/index_test.go index 5979e60ff77..e5485c51edb 100644 --- a/manifest/ocischema/index_test.go +++ b/manifest/ocischema/index_test.go @@ -52,8 +52,8 @@ const expectedOCIImageIndexSerialization = `{ } }` -func makeTestOCIImageIndex(t *testing.T, mediaType string) ([]distribution.Descriptor, *DeserializedImageIndex) { - manifestDescriptors := []distribution.Descriptor{ +func makeTestOCIImageIndex(t *testing.T, mediaType string) ([]v1.Descriptor, *DeserializedImageIndex) { + manifestDescriptors := []v1.Descriptor{ { MediaType: "application/vnd.oci.image.manifest.v1+json", Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", @@ -207,11 +207,11 @@ func TestIndexMediaTypes(t *testing.T) { func TestValidateIndex(t *testing.T) { manifest := schema2.Manifest{ - Config: distribution.Descriptor{Size: 1}, - Layers: []distribution.Descriptor{{Size: 2}}, + Config: v1.Descriptor{Size: 1}, + Layers: []v1.Descriptor{{Size: 2}}, } index := ImageIndex{ - Manifests: []distribution.Descriptor{{Size: 3}}, + Manifests: []v1.Descriptor{{Size: 3}}, } t.Run("valid", func(t *testing.T) { b, err := json.Marshal(index) diff --git a/manifest/ocischema/manifest.go b/manifest/ocischema/manifest.go index db0896cd049..2009e2f5ac6 100644 --- a/manifest/ocischema/manifest.go +++ b/manifest/ocischema/manifest.go @@ -30,17 +30,17 @@ func init() { } } -func unmarshalOCISchema(b []byte) (distribution.Manifest, distribution.Descriptor, error) { +func unmarshalOCISchema(b []byte) (distribution.Manifest, v1.Descriptor, error) { if err := validateManifest(b); err != nil { - return nil, distribution.Descriptor{}, err + return nil, v1.Descriptor{}, err } m := &DeserializedManifest{} if err := m.UnmarshalJSON(b); err != nil { - return nil, distribution.Descriptor{}, err + return nil, v1.Descriptor{}, err } - return m, distribution.Descriptor{ + return m, v1.Descriptor{ MediaType: v1.MediaTypeImageManifest, Digest: digest.FromBytes(b), Size: int64(len(b)), @@ -56,26 +56,26 @@ type Manifest struct { MediaType string `json:"mediaType,omitempty"` // Config references the image configuration as a blob. - Config distribution.Descriptor `json:"config"` + Config v1.Descriptor `json:"config"` // Layers lists descriptors for the layers referenced by the // configuration. - Layers []distribution.Descriptor `json:"layers"` + Layers []v1.Descriptor `json:"layers"` // Annotations contains arbitrary metadata for the image manifest. Annotations map[string]string `json:"annotations,omitempty"` } // References returns the descriptors of this manifests references. -func (m Manifest) References() []distribution.Descriptor { - references := make([]distribution.Descriptor, 0, 1+len(m.Layers)) +func (m Manifest) References() []v1.Descriptor { + references := make([]v1.Descriptor, 0, 1+len(m.Layers)) references = append(references, m.Config) references = append(references, m.Layers...) return references } // Target returns the target of this manifest. -func (m Manifest) Target() distribution.Descriptor { +func (m Manifest) Target() v1.Descriptor { return m.Config } diff --git a/manifest/ocischema/manifest_test.go b/manifest/ocischema/manifest_test.go index 8d22d8709b4..59d7ca38928 100644 --- a/manifest/ocischema/manifest_test.go +++ b/manifest/ocischema/manifest_test.go @@ -8,9 +8,8 @@ import ( "github.com/distribution/distribution/v3" "github.com/distribution/distribution/v3/manifest/manifestlist" - "github.com/opencontainers/image-spec/specs-go" - "github.com/opencontainers/go-digest" + "github.com/opencontainers/image-spec/specs-go" v1 "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -44,13 +43,13 @@ func makeTestManifest(mediaType string) Manifest { return Manifest{ Versioned: specs.Versioned{SchemaVersion: 2}, MediaType: mediaType, - Config: distribution.Descriptor{ + Config: v1.Descriptor{ MediaType: v1.MediaTypeImageConfig, Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Size: 985, Annotations: map[string]string{"apple": "orange"}, }, - Layers: []distribution.Descriptor{ + Layers: []v1.Descriptor{ { MediaType: v1.MediaTypeImageLayerGzip, Digest: "sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b", @@ -217,12 +216,12 @@ func TestManifestMediaTypes(t *testing.T) { func TestValidateManifest(t *testing.T) { mfst := Manifest{ - Config: distribution.Descriptor{Size: 1}, - Layers: []distribution.Descriptor{{Size: 2}}, + Config: v1.Descriptor{Size: 1}, + Layers: []v1.Descriptor{{Size: 2}}, } index := manifestlist.ManifestList{ Manifests: []manifestlist.ManifestDescriptor{ - {Descriptor: distribution.Descriptor{Size: 3}}, + {Descriptor: v1.Descriptor{Size: 3}}, }, } t.Run("valid", func(t *testing.T) { diff --git a/manifest/schema2/builder.go b/manifest/schema2/builder.go index 771014e2da9..7db31431127 100644 --- a/manifest/schema2/builder.go +++ b/manifest/schema2/builder.go @@ -5,25 +5,26 @@ import ( "github.com/distribution/distribution/v3" "github.com/opencontainers/image-spec/specs-go" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // Builder is a type for constructing manifests. type Builder struct { // configDescriptor is used to describe configuration - configDescriptor distribution.Descriptor + configDescriptor v1.Descriptor // configJSON references configJSON []byte // dependencies is a list of descriptors that gets built by successive // calls to AppendReference. In case of image configuration these are layers. - dependencies []distribution.Descriptor + dependencies []v1.Descriptor } // NewManifestBuilder is used to build new manifests for the current schema // version. It takes a BlobService so it can publish the configuration blob // as part of the Build process. -func NewManifestBuilder(configDescriptor distribution.Descriptor, configJSON []byte) *Builder { +func NewManifestBuilder(configDescriptor v1.Descriptor, configJSON []byte) *Builder { mb := &Builder{ configDescriptor: configDescriptor, configJSON: make([]byte, len(configJSON)), @@ -38,7 +39,7 @@ func (mb *Builder) Build(ctx context.Context) (distribution.Manifest, error) { m := Manifest{ Versioned: specs.Versioned{SchemaVersion: defaultSchemaVersion}, MediaType: defaultMediaType, - Layers: make([]distribution.Descriptor, len(mb.dependencies)), + Layers: make([]v1.Descriptor, len(mb.dependencies)), } copy(m.Layers, mb.dependencies) @@ -48,12 +49,12 @@ func (mb *Builder) Build(ctx context.Context) (distribution.Manifest, error) { } // AppendReference adds a reference to the current ManifestBuilder. -func (mb *Builder) AppendReference(ref distribution.Descriptor) error { +func (mb *Builder) AppendReference(ref v1.Descriptor) error { mb.dependencies = append(mb.dependencies, ref) return nil } // References returns the current references added to this builder. -func (mb *Builder) References() []distribution.Descriptor { +func (mb *Builder) References() []v1.Descriptor { return mb.dependencies } diff --git a/manifest/schema2/builder_test.go b/manifest/schema2/builder_test.go index 039246a36e3..0131c73f905 100644 --- a/manifest/schema2/builder_test.go +++ b/manifest/schema2/builder_test.go @@ -5,8 +5,8 @@ import ( "reflect" "testing" - "github.com/distribution/distribution/v3" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) func TestBuilder(t *testing.T) { @@ -110,7 +110,7 @@ func TestBuilder(t *testing.T) { }`) configDigest := digest.FromBytes(imgJSON) - descriptors := []distribution.Descriptor{ + descriptors := []v1.Descriptor{ { MediaType: MediaTypeLayer, Digest: digest.Digest("sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"), @@ -128,7 +128,7 @@ func TestBuilder(t *testing.T) { }, } - d := distribution.Descriptor{ + d := v1.Descriptor{ Digest: digest.FromBytes(imgJSON), Size: int64(len(imgJSON)), MediaType: MediaTypeImageConfig, @@ -165,7 +165,7 @@ func TestBuilder(t *testing.T) { } references := manifest.References() - expected := append([]distribution.Descriptor{manifest.Target()}, descriptors...) + expected := append([]v1.Descriptor{manifest.Target()}, descriptors...) if !reflect.DeepEqual(references, expected) { t.Fatal("References() does not match the descriptors added") } diff --git a/manifest/schema2/manifest.go b/manifest/schema2/manifest.go index 2b8e4413eae..6df2fa552b1 100644 --- a/manifest/schema2/manifest.go +++ b/manifest/schema2/manifest.go @@ -9,6 +9,7 @@ import ( "github.com/distribution/distribution/v3/manifest" "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/specs-go" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) const ( @@ -57,13 +58,13 @@ func init() { } } -func unmarshalSchema2(b []byte) (distribution.Manifest, distribution.Descriptor, error) { +func unmarshalSchema2(b []byte) (distribution.Manifest, v1.Descriptor, error) { m := &DeserializedManifest{} if err := m.UnmarshalJSON(b); err != nil { - return nil, distribution.Descriptor{}, err + return nil, v1.Descriptor{}, err } - return m, distribution.Descriptor{ + return m, v1.Descriptor{ Digest: digest.FromBytes(b), Size: int64(len(b)), MediaType: defaultMediaType, @@ -78,23 +79,23 @@ type Manifest struct { MediaType string `json:"mediaType,omitempty"` // Config references the image configuration as a blob. - Config distribution.Descriptor `json:"config"` + Config v1.Descriptor `json:"config"` // Layers lists descriptors for the layers referenced by the // configuration. - Layers []distribution.Descriptor `json:"layers"` + Layers []v1.Descriptor `json:"layers"` } // References returns the descriptors of this manifests references. -func (m Manifest) References() []distribution.Descriptor { - references := make([]distribution.Descriptor, 0, 1+len(m.Layers)) +func (m Manifest) References() []v1.Descriptor { + references := make([]v1.Descriptor, 0, 1+len(m.Layers)) references = append(references, m.Config) references = append(references, m.Layers...) return references } // Target returns the target of this manifest. -func (m Manifest) Target() distribution.Descriptor { +func (m Manifest) Target() v1.Descriptor { return m.Config } diff --git a/manifest/schema2/manifest_test.go b/manifest/schema2/manifest_test.go index 9ff9c5e9c05..22a5c884718 100644 --- a/manifest/schema2/manifest_test.go +++ b/manifest/schema2/manifest_test.go @@ -8,6 +8,7 @@ import ( "github.com/distribution/distribution/v3" "github.com/opencontainers/image-spec/specs-go" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) const expectedManifestSerialization = `{ @@ -31,12 +32,12 @@ func makeTestManifest(mediaType string) Manifest { return Manifest{ Versioned: specs.Versioned{SchemaVersion: 2}, MediaType: mediaType, - Config: distribution.Descriptor{ + Config: v1.Descriptor{ MediaType: MediaTypeImageConfig, Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Size: 985, }, - Layers: []distribution.Descriptor{ + Layers: []v1.Descriptor{ { MediaType: MediaTypeLayer, Digest: "sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b", diff --git a/manifests.go b/manifests.go index 97b246d2027..290558dabea 100644 --- a/manifests.go +++ b/manifests.go @@ -6,6 +6,7 @@ import ( "mime" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // Manifest represents a registry object specifying a set of @@ -13,13 +14,13 @@ import ( type Manifest interface { // References returns a list of objects which make up this manifest. // A reference is anything which can be represented by a - // distribution.Descriptor. These can consist of layers, resources or other + // Descriptor. These can consist of layers, resources or other // manifests. // // While no particular order is required, implementations should return // them from highest to lowest priority. For example, one might want to // return the base layer before the top layer. - References() []Descriptor + References() []v1.Descriptor // Payload provides the serialized format of the manifest, in addition to // the media type. @@ -54,7 +55,7 @@ type ManifestEnumerator interface { // described, not simply descriptors. type Describable interface { // Descriptor returns the descriptor. - Descriptor() Descriptor + Descriptor() v1.Descriptor } // ManifestMediaTypes returns the supported media types for manifests. @@ -68,13 +69,13 @@ func ManifestMediaTypes() (mediaTypes []string) { } // UnmarshalFunc implements manifest unmarshalling a given MediaType -type UnmarshalFunc func([]byte) (Manifest, Descriptor, error) +type UnmarshalFunc func([]byte) (Manifest, v1.Descriptor, error) var mappings = make(map[string]UnmarshalFunc) // UnmarshalManifest looks up manifest unmarshal functions based on // MediaType -func UnmarshalManifest(ctHeader string, p []byte) (Manifest, Descriptor, error) { +func UnmarshalManifest(ctHeader string, p []byte) (Manifest, v1.Descriptor, error) { // Need to look up by the actual media type, not the raw contents of // the header. Strip semicolons and anything following them. var mediaType string @@ -82,7 +83,7 @@ func UnmarshalManifest(ctHeader string, p []byte) (Manifest, Descriptor, error) var err error mediaType, _, err = mime.ParseMediaType(ctHeader) if err != nil { - return nil, Descriptor{}, err + return nil, v1.Descriptor{}, err } } @@ -90,7 +91,7 @@ func UnmarshalManifest(ctHeader string, p []byte) (Manifest, Descriptor, error) if !ok { unmarshalFunc, ok = mappings[""] if !ok { - return nil, Descriptor{}, fmt.Errorf("unsupported manifest media type and no default available: %s", mediaType) + return nil, v1.Descriptor{}, fmt.Errorf("unsupported manifest media type and no default available: %s", mediaType) } } diff --git a/notifications/bridge.go b/notifications/bridge.go index 8b594774bc1..81b5409cce4 100644 --- a/notifications/bridge.go +++ b/notifications/bridge.go @@ -10,6 +10,7 @@ import ( events "github.com/docker/go-events" "github.com/google/uuid" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) type bridge struct { @@ -90,15 +91,15 @@ func (b *bridge) ManifestDeleted(repo reference.Named, dgst digest.Digest) error return b.createManifestDeleteEventAndWrite(EventActionDelete, repo, dgst) } -func (b *bridge) BlobPushed(repo reference.Named, desc distribution.Descriptor) error { +func (b *bridge) BlobPushed(repo reference.Named, desc v1.Descriptor) error { return b.createBlobEventAndWrite(EventActionPush, repo, desc) } -func (b *bridge) BlobPulled(repo reference.Named, desc distribution.Descriptor) error { +func (b *bridge) BlobPulled(repo reference.Named, desc v1.Descriptor) error { return b.createBlobEventAndWrite(EventActionPull, repo, desc) } -func (b *bridge) BlobMounted(repo reference.Named, desc distribution.Descriptor, fromRepo reference.Named) error { +func (b *bridge) BlobMounted(repo reference.Named, desc v1.Descriptor, fromRepo reference.Named) error { event, err := b.createBlobEvent(EventActionMount, repo, desc) if err != nil { return err @@ -178,7 +179,7 @@ func (b *bridge) createBlobDeleteEventAndWrite(action string, repo reference.Nam return b.sink.Write(*event) } -func (b *bridge) createBlobEventAndWrite(action string, repo reference.Named, desc distribution.Descriptor) error { +func (b *bridge) createBlobEventAndWrite(action string, repo reference.Named, desc v1.Descriptor) error { event, err := b.createBlobEvent(action, repo, desc) if err != nil { return err @@ -187,7 +188,7 @@ func (b *bridge) createBlobEventAndWrite(action string, repo reference.Named, de return b.sink.Write(*event) } -func (b *bridge) createBlobEvent(action string, repo reference.Named, desc distribution.Descriptor) (*Event, error) { +func (b *bridge) createBlobEvent(action string, repo reference.Named, desc v1.Descriptor) (*Event, error) { event := b.createEvent(action) event.Target.Descriptor = desc event.Target.Length = desc.Size diff --git a/notifications/bridge_test.go b/notifications/bridge_test.go index 5fc2e4c4f18..a864e649027 100644 --- a/notifications/bridge_test.go +++ b/notifications/bridge_test.go @@ -30,7 +30,7 @@ var ( request = RequestRecord{} tag = "latest" artifactType = "application/vnd.example.sbom.v1" - cfg = distribution.Descriptor{ + cfg = v1.Descriptor{ MediaType: artifactType, Size: 100, Digest: "cfgdgst", diff --git a/notifications/event.go b/notifications/event.go index 82c7ba2cd2d..98dd9faf0af 100644 --- a/notifications/event.go +++ b/notifications/event.go @@ -4,8 +4,8 @@ import ( "fmt" "time" - "github.com/distribution/distribution/v3" events "github.com/docker/go-events" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // EventAction constants used in action field of Event. @@ -54,7 +54,7 @@ type Event struct { Target struct { // TODO(stevvooe): Use http.DetectContentType for layers, maybe. - distribution.Descriptor + v1.Descriptor // Length in bytes of content. Same as Size field in Descriptor. // Provided for backwards compatibility. @@ -74,7 +74,7 @@ type Event struct { Tag string `json:"tag,omitempty"` // References provides the references descriptors. - References []distribution.Descriptor `json:"references,omitempty"` + References []v1.Descriptor `json:"references,omitempty"` } `json:"target,omitempty"` // Request covers the request that generated the event. diff --git a/notifications/listener.go b/notifications/listener.go index 563c13928f9..8a36067ef35 100644 --- a/notifications/listener.go +++ b/notifications/listener.go @@ -10,6 +10,7 @@ import ( "github.com/distribution/distribution/v3/internal/dcontext" "github.com/distribution/reference" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // ManifestListener describes a set of methods for listening to events related to manifests. @@ -21,9 +22,9 @@ type ManifestListener interface { // BlobListener describes a listener that can respond to layer related events. type BlobListener interface { - BlobPushed(repo reference.Named, desc distribution.Descriptor) error - BlobPulled(repo reference.Named, desc distribution.Descriptor) error - BlobMounted(repo reference.Named, desc distribution.Descriptor, fromRepo reference.Named) error + BlobPushed(repo reference.Named, desc v1.Descriptor) error + BlobPulled(repo reference.Named, desc v1.Descriptor) error + BlobMounted(repo reference.Named, desc v1.Descriptor, fromRepo reference.Named) error BlobDeleted(repo reference.Named, desc digest.Digest) error } @@ -178,7 +179,7 @@ func (bsl *blobServiceListener) ServeBlob(ctx context.Context, w http.ResponseWr return err } -func (bsl *blobServiceListener) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) { +func (bsl *blobServiceListener) Put(ctx context.Context, mediaType string, p []byte) (v1.Descriptor, error) { desc, err := bsl.BlobStore.Put(ctx, mediaType, p) if err == nil { if err := bsl.parent.listener.BlobPushed(bsl.parent.Repository.Named(), desc); err != nil { @@ -229,7 +230,7 @@ type blobWriterListener struct { parent *blobServiceListener } -func (bwl *blobWriterListener) Commit(ctx context.Context, desc distribution.Descriptor) (distribution.Descriptor, error) { +func (bwl *blobWriterListener) Commit(ctx context.Context, desc v1.Descriptor) (v1.Descriptor, error) { committed, err := bwl.BlobWriter.Commit(ctx, desc) if err == nil { if err := bwl.parent.parent.listener.BlobPushed(bwl.parent.parent.Repository.Named(), committed); err != nil { diff --git a/notifications/listener_test.go b/notifications/listener_test.go index 80f034e4a3a..aa053f806c0 100644 --- a/notifications/listener_test.go +++ b/notifications/listener_test.go @@ -15,6 +15,7 @@ import ( "github.com/distribution/reference" "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/specs-go" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) func TestListener(t *testing.T) { @@ -80,17 +81,17 @@ func (tl *testListener) ManifestDeleted(repo reference.Named, d digest.Digest) e return nil } -func (tl *testListener) BlobPushed(repo reference.Named, desc distribution.Descriptor) error { +func (tl *testListener) BlobPushed(repo reference.Named, desc v1.Descriptor) error { tl.ops["layer:push"]++ return nil } -func (tl *testListener) BlobPulled(repo reference.Named, desc distribution.Descriptor) error { +func (tl *testListener) BlobPulled(repo reference.Named, desc v1.Descriptor) error { tl.ops["layer:pull"]++ return nil } -func (tl *testListener) BlobMounted(repo reference.Named, desc distribution.Descriptor, fromRepo reference.Named) error { +func (tl *testListener) BlobMounted(repo reference.Named, desc v1.Descriptor, fromRepo reference.Named) error { tl.ops["layer:mount"]++ return nil } @@ -146,7 +147,7 @@ func checkTestRepository(t *testing.T, repository distribution.Repository, remov m := schema2.Manifest{ Versioned: specs.Versioned{SchemaVersion: 2}, MediaType: schema2.MediaTypeManifest, - Config: distribution.Descriptor{ + Config: v1.Descriptor{ MediaType: "foo/bar", Digest: configDgst, }, @@ -163,7 +164,7 @@ func checkTestRepository(t *testing.T, repository distribution.Repository, remov t.Fatal(err) } - m.Layers = append(m.Layers, distribution.Descriptor{ + m.Layers = append(m.Layers, v1.Descriptor{ MediaType: "application/octet-stream", Digest: dgst, }) @@ -201,7 +202,7 @@ func checkTestRepository(t *testing.T, repository distribution.Repository, remov t.Fatal("mismatching digest from payload and put") } - if err := repository.Tags(ctx).Tag(ctx, tag, distribution.Descriptor{Digest: dgst}); err != nil { + if err := repository.Tags(ctx).Tag(ctx, tag, v1.Descriptor{Digest: dgst}); err != nil { t.Fatalf("unexpected error tagging manifest: %v", err) } diff --git a/registry/handlers/api_test.go b/registry/handlers/api_test.go index 29a48a70ce0..754def6c494 100644 --- a/registry/handlers/api_test.go +++ b/registry/handlers/api_test.go @@ -33,6 +33,7 @@ import ( "github.com/gorilla/handlers" "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/specs-go" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) var headerConfig = http.Header{ @@ -1579,12 +1580,12 @@ func testManifestAPISchema2(t *testing.T, env *testEnv, imageName reference.Name manifest := &schema2.Manifest{ Versioned: specs.Versioned{SchemaVersion: 2}, MediaType: schema2.MediaTypeManifest, - Config: distribution.Descriptor{ + Config: v1.Descriptor{ Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Size: 3253, MediaType: schema2.MediaTypeImageConfig, }, - Layers: []distribution.Descriptor{ + Layers: []v1.Descriptor{ { Digest: "sha256:463434349086340864309863409683460843608348608934092322395278926a", Size: 6323, @@ -1902,7 +1903,7 @@ func testManifestAPIManifestList(t *testing.T, env *testEnv, args manifestArgs) MediaType: manifestlist.MediaTypeManifestList, Manifests: []manifestlist.ManifestDescriptor{ { - Descriptor: distribution.Descriptor{ + Descriptor: v1.Descriptor{ Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Size: 3253, MediaType: schema2.MediaTypeManifest, @@ -2637,12 +2638,12 @@ func createRepository(env *testEnv, t *testing.T, imageName string, tag string) manifest := &schema2.Manifest{ Versioned: specs.Versioned{SchemaVersion: 2}, MediaType: schema2.MediaTypeManifest, - Config: distribution.Descriptor{ + Config: v1.Descriptor{ Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Size: 3253, MediaType: schema2.MediaTypeImageConfig, }, - Layers: []distribution.Descriptor{ + Layers: []v1.Descriptor{ { Digest: "sha256:463434349086340864309863409683460843608348608934092322395278926a", Size: 6323, @@ -2732,12 +2733,12 @@ func TestRegistryAsCacheMutationAPIs(t *testing.T) { manifest := &schema2.Manifest{ Versioned: specs.Versioned{SchemaVersion: 2}, MediaType: schema2.MediaTypeManifest, - Config: distribution.Descriptor{ + Config: v1.Descriptor{ Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Size: 3253, MediaType: schema2.MediaTypeImageConfig, }, - Layers: []distribution.Descriptor{ + Layers: []v1.Descriptor{ { Digest: "sha256:463434349086340864309863409683460843608348608934092322395278926a", Size: 6323, diff --git a/registry/handlers/blobupload.go b/registry/handlers/blobupload.go index 6b6c640da81..5d5385367d1 100644 --- a/registry/handlers/blobupload.go +++ b/registry/handlers/blobupload.go @@ -13,6 +13,7 @@ import ( "github.com/distribution/reference" "github.com/gorilla/handlers" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // blobUploadDispatcher constructs and returns the blob upload handler for the @@ -210,7 +211,7 @@ func (buh *blobUploadHandler) PutBlobUploadComplete(w http.ResponseWriter, r *ht return } - desc, err := buh.Upload.Commit(buh, distribution.Descriptor{ + desc, err := buh.Upload.Commit(buh, v1.Descriptor{ Digest: dgst, // TODO(stevvooe): This isn't wildly important yet, but we should @@ -384,7 +385,7 @@ func (buh *blobUploadHandler) createBlobMountOption(fromRepo, mountDigest string // writeBlobCreatedHeaders writes the standard headers describing a newly // created blob. A 201 Created is written as well as the canonical URL and // blob digest. -func (buh *blobUploadHandler) writeBlobCreatedHeaders(w http.ResponseWriter, desc distribution.Descriptor) error { +func (buh *blobUploadHandler) writeBlobCreatedHeaders(w http.ResponseWriter, desc v1.Descriptor) error { ref, err := reference.WithDigest(buh.Repository.Named(), desc.Digest) if err != nil { return err diff --git a/registry/handlers/manifests.go b/registry/handlers/manifests.go index 144c04482e7..6b7648c2bf5 100644 --- a/registry/handlers/manifests.go +++ b/registry/handlers/manifests.go @@ -478,7 +478,7 @@ func (imh *manifestHandler) DeleteManifest(w http.ResponseWriter, r *http.Reques } tagService := imh.Repository.Tags(imh) - referencedTags, err := tagService.Lookup(imh, distribution.Descriptor{Digest: imh.Digest}) + referencedTags, err := tagService.Lookup(imh, v1.Descriptor{Digest: imh.Digest}) if err != nil { imh.Errors = append(imh.Errors, err) return diff --git a/registry/proxy/proxyblobstore.go b/registry/proxy/proxyblobstore.go index 7dc3a1c422b..7726f428042 100644 --- a/registry/proxy/proxyblobstore.go +++ b/registry/proxy/proxyblobstore.go @@ -9,6 +9,7 @@ import ( "time" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/distribution/distribution/v3" "github.com/distribution/distribution/v3/internal/dcontext" @@ -40,24 +41,24 @@ func setResponseHeaders(h http.Header, length int64, mediaType string, digest di h.Set("Etag", digest.String()) } -func (pbs *proxyBlobStore) copyContent(ctx context.Context, dgst digest.Digest, writer io.Writer, h http.Header) (distribution.Descriptor, error) { +func (pbs *proxyBlobStore) copyContent(ctx context.Context, dgst digest.Digest, writer io.Writer, h http.Header) (v1.Descriptor, error) { desc, err := pbs.remoteStore.Stat(ctx, dgst) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } setResponseHeaders(h, desc.Size, desc.MediaType, dgst) remoteReader, err := pbs.remoteStore.Open(ctx, dgst) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } defer remoteReader.Close() _, err = io.CopyN(writer, remoteReader, desc.Size) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } proxyMetrics.BlobPull(uint64(desc.Size)) @@ -146,18 +147,18 @@ func (pbs *proxyBlobStore) ServeBlob(ctx context.Context, w http.ResponseWriter, return nil } -func (pbs *proxyBlobStore) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (pbs *proxyBlobStore) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { desc, err := pbs.localStore.Stat(ctx, dgst) if err == nil { return desc, err } if err != distribution.ErrBlobUnknown { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } if err := pbs.authChallenger.tryEstablishChallenges(ctx); err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } return pbs.remoteStore.Stat(ctx, dgst) @@ -186,8 +187,8 @@ func (pbs *proxyBlobStore) Get(ctx context.Context, dgst digest.Digest) ([]byte, } // Unsupported functions -func (pbs *proxyBlobStore) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) { - return distribution.Descriptor{}, distribution.ErrUnsupported +func (pbs *proxyBlobStore) Put(ctx context.Context, mediaType string, p []byte) (v1.Descriptor, error) { + return v1.Descriptor{}, distribution.ErrUnsupported } func (pbs *proxyBlobStore) Create(ctx context.Context, options ...distribution.BlobCreateOption) (distribution.BlobWriter, error) { @@ -198,8 +199,8 @@ func (pbs *proxyBlobStore) Resume(ctx context.Context, id string) (distribution. return nil, distribution.ErrUnsupported } -func (pbs *proxyBlobStore) Mount(ctx context.Context, sourceRepo reference.Named, dgst digest.Digest) (distribution.Descriptor, error) { - return distribution.Descriptor{}, distribution.ErrUnsupported +func (pbs *proxyBlobStore) Mount(ctx context.Context, sourceRepo reference.Named, dgst digest.Digest) (v1.Descriptor, error) { + return v1.Descriptor{}, distribution.ErrUnsupported } func (pbs *proxyBlobStore) Open(ctx context.Context, dgst digest.Digest) (io.ReadSeekCloser, error) { diff --git a/registry/proxy/proxyblobstore_test.go b/registry/proxy/proxyblobstore_test.go index 52589305383..1485cefa091 100644 --- a/registry/proxy/proxyblobstore_test.go +++ b/registry/proxy/proxyblobstore_test.go @@ -18,6 +18,7 @@ import ( "github.com/distribution/distribution/v3/registry/storage/driver/inmemory" "github.com/distribution/reference" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) var ( @@ -34,7 +35,7 @@ func init() { randSource = *rand.New(rand.NewSource(42)) } -func (sbs statsBlobStore) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) { +func (sbs statsBlobStore) Put(ctx context.Context, mediaType string, p []byte) (v1.Descriptor, error) { sbsMu.Lock() sbs.stats["put"]++ sbsMu.Unlock() @@ -82,7 +83,7 @@ func (sbs statsBlobStore) ServeBlob(ctx context.Context, w http.ResponseWriter, return sbs.blobs.ServeBlob(ctx, w, r, dgst) } -func (sbs statsBlobStore) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (sbs statsBlobStore) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { sbsMu.Lock() sbs.stats["stat"]++ sbsMu.Unlock() @@ -100,7 +101,7 @@ func (sbs statsBlobStore) Delete(ctx context.Context, dgst digest.Digest) error type testEnv struct { numUnique int - inRemote []distribution.Descriptor + inRemote []v1.Descriptor store proxyBlobStore ctx context.Context } @@ -202,7 +203,7 @@ func makeBlob(size int) []byte { } func populate(t *testing.T, te *testEnv, blobCount, size, numUnique int) { - var inRemote []distribution.Descriptor + var inRemote []v1.Descriptor for i := 0; i < numUnique; i++ { bytes := makeBlob(size) diff --git a/registry/proxy/proxymanifeststore_test.go b/registry/proxy/proxymanifeststore_test.go index e3dbce1b7a2..fdf56317318 100644 --- a/registry/proxy/proxymanifeststore_test.go +++ b/registry/proxy/proxymanifeststore_test.go @@ -18,6 +18,7 @@ import ( "github.com/distribution/reference" "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/specs-go" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) type statsManifest struct { @@ -158,7 +159,7 @@ func populateRepo(ctx context.Context, t *testing.T, repository distribution.Rep m := schema2.Manifest{ Versioned: specs.Versioned{SchemaVersion: 2}, MediaType: schema2.MediaTypeManifest, - Config: distribution.Descriptor{ + Config: v1.Descriptor{ MediaType: "foo/bar", Digest: configDigest, }, diff --git a/registry/proxy/proxytagservice.go b/registry/proxy/proxytagservice.go index 6bc08dba32b..a55f22bb1fd 100644 --- a/registry/proxy/proxytagservice.go +++ b/registry/proxy/proxytagservice.go @@ -4,6 +4,7 @@ import ( "context" "github.com/distribution/distribution/v3" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // proxyTagService supports local and remote lookup of tags. @@ -18,14 +19,14 @@ var _ distribution.TagService = proxyTagService{} // Get attempts to get the most recent digest for the tag by checking the remote // tag service first and then caching it locally. If the remote is unavailable // the local association is returned -func (pt proxyTagService) Get(ctx context.Context, tag string) (distribution.Descriptor, error) { +func (pt proxyTagService) Get(ctx context.Context, tag string) (v1.Descriptor, error) { err := pt.authChallenger.tryEstablishChallenges(ctx) if err == nil { desc, err := pt.remoteTags.Get(ctx, tag) if err == nil { err := pt.localTags.Tag(ctx, tag, desc) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } return desc, nil } @@ -33,12 +34,12 @@ func (pt proxyTagService) Get(ctx context.Context, tag string) (distribution.Des desc, err := pt.localTags.Get(ctx, tag) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } return desc, nil } -func (pt proxyTagService) Tag(ctx context.Context, tag string, desc distribution.Descriptor) error { +func (pt proxyTagService) Tag(ctx context.Context, tag string, desc v1.Descriptor) error { return distribution.ErrUnsupported } @@ -61,6 +62,6 @@ func (pt proxyTagService) All(ctx context.Context) ([]string, error) { return pt.localTags.All(ctx) } -func (pt proxyTagService) Lookup(ctx context.Context, digest distribution.Descriptor) ([]string, error) { +func (pt proxyTagService) Lookup(ctx context.Context, digest v1.Descriptor) ([]string, error) { return []string{}, distribution.ErrUnsupported } diff --git a/registry/proxy/proxytagservice_test.go b/registry/proxy/proxytagservice_test.go index 9cf2462dbaf..b297488ae4d 100644 --- a/registry/proxy/proxytagservice_test.go +++ b/registry/proxy/proxytagservice_test.go @@ -8,25 +8,26 @@ import ( "testing" "github.com/distribution/distribution/v3" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) type mockTagStore struct { - mapping map[string]distribution.Descriptor + mapping map[string]v1.Descriptor sync.Mutex distribution.TagService } -func (m *mockTagStore) Get(ctx context.Context, tag string) (distribution.Descriptor, error) { +func (m *mockTagStore) Get(ctx context.Context, tag string) (v1.Descriptor, error) { m.Lock() defer m.Unlock() if d, ok := m.mapping[tag]; ok { return d, nil } - return distribution.Descriptor{}, distribution.ErrTagUnknown{} + return v1.Descriptor{}, distribution.ErrTagUnknown{} } -func (m *mockTagStore) Tag(ctx context.Context, tag string, desc distribution.Descriptor) error { +func (m *mockTagStore) Tag(ctx context.Context, tag string, desc v1.Descriptor) error { m.Lock() defer m.Unlock() @@ -57,12 +58,12 @@ func (m *mockTagStore) All(ctx context.Context) ([]string, error) { return tags, nil } -func testProxyTagService(local, remote map[string]distribution.Descriptor) *proxyTagService { +func testProxyTagService(local, remote map[string]v1.Descriptor) *proxyTagService { if local == nil { - local = make(map[string]distribution.Descriptor) + local = make(map[string]v1.Descriptor) } if remote == nil { - remote = make(map[string]distribution.Descriptor) + remote = make(map[string]v1.Descriptor) } return &proxyTagService{ localTags: &mockTagStore{mapping: local}, @@ -72,9 +73,9 @@ func testProxyTagService(local, remote map[string]distribution.Descriptor) *prox } func TestGet(t *testing.T) { - remoteDesc := distribution.Descriptor{Size: 42} + remoteDesc := v1.Descriptor{Size: 42} remoteTag := "remote" - proxyTags := testProxyTagService(map[string]distribution.Descriptor{remoteTag: remoteDesc}, nil) + proxyTags := testProxyTagService(map[string]v1.Descriptor{remoteTag: remoteDesc}, nil) ctx := context.Background() @@ -102,7 +103,7 @@ func TestGet(t *testing.T) { } // Manually overwrite remote tag - newRemoteDesc := distribution.Descriptor{Size: 43} + newRemoteDesc := v1.Descriptor{Size: 43} err = proxyTags.remoteTags.Tag(ctx, remoteTag, newRemoteDesc) if err != nil { t.Fatal(err) @@ -152,7 +153,7 @@ func TestGet(t *testing.T) { } // Add another tag. Ensure both tags appear in 'All' - err = proxyTags.remoteTags.Tag(ctx, "funtag", distribution.Descriptor{Size: 42}) + err = proxyTags.remoteTags.Tag(ctx, "funtag", v1.Descriptor{Size: 42}) if err != nil { t.Fatal(err) } diff --git a/registry/storage/blob_test.go b/registry/storage/blob_test.go index 1464c47c79f..0cea438934d 100644 --- a/registry/storage/blob_test.go +++ b/registry/storage/blob_test.go @@ -16,6 +16,7 @@ import ( "github.com/distribution/distribution/v3/testutil" "github.com/distribution/reference" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // TestWriteSeek tests that the current file size can be @@ -133,7 +134,7 @@ func TestSimpleBlobUpload(t *testing.T) { } sha256Digest := digest.NewDigest("sha256", h) - desc, err := blobUpload.Commit(ctx, distribution.Descriptor{Digest: dgst}) + desc, err := blobUpload.Commit(ctx, v1.Descriptor{Digest: dgst}) if err != nil { t.Fatalf("unexpected error finishing layer upload: %v", err) } @@ -285,7 +286,7 @@ func TestSimpleBlobRead(t *testing.T) { t.Fatalf("error getting seeker size for random layer: %v", err) } - descBefore := distribution.Descriptor{Digest: dgst, MediaType: "application/octet-stream", Size: randomLayerSize} + descBefore := v1.Descriptor{Digest: dgst, MediaType: "application/octet-stream", Size: randomLayerSize} t.Logf("desc: %v", descBefore) desc, err = addBlob(ctx, bs, descBefore, randomLayerReader) @@ -398,7 +399,7 @@ func TestBlobMount(t *testing.T) { t.Fatalf("unexpected error uploading layer data: %v", err) } - desc, err := blobUpload.Commit(ctx, distribution.Descriptor{Digest: dgst}) + desc, err := blobUpload.Commit(ctx, v1.Descriptor{Digest: dgst}) if err != nil { t.Fatalf("unexpected error finishing layer upload: %v", err) } @@ -555,7 +556,7 @@ func simpleUpload(t *testing.T, bs distribution.BlobIngester, blob []byte, expec t.Fatalf("digest not as expected: %v != %v", dgst, expectedDigest) } - desc, err := wr.Commit(ctx, distribution.Descriptor{Digest: dgst}) + desc, err := wr.Commit(ctx, v1.Descriptor{Digest: dgst}) if err != nil { t.Fatalf("unexpected error committing write: %v", err) } @@ -593,18 +594,18 @@ func seekerSize(seeker io.ReadSeeker) (int64, error) { // addBlob simply consumes the reader and inserts into the blob service, // returning a descriptor on success. -func addBlob(ctx context.Context, bs distribution.BlobIngester, desc distribution.Descriptor, rd io.Reader) (distribution.Descriptor, error) { +func addBlob(ctx context.Context, bs distribution.BlobIngester, desc v1.Descriptor, rd io.Reader) (v1.Descriptor, error) { wr, err := bs.Create(ctx) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } // nolint:errcheck defer wr.Cancel(ctx) if nn, err := io.Copy(wr, rd); err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } else if nn != desc.Size { - return distribution.Descriptor{}, fmt.Errorf("incorrect number of bytes copied: %v != %v", nn, desc.Size) + return v1.Descriptor{}, fmt.Errorf("incorrect number of bytes copied: %v != %v", nn, desc.Size) } return wr.Commit(ctx, desc) diff --git a/registry/storage/blobstore.go b/registry/storage/blobstore.go index c03736ea331..c36bd7e9ef3 100644 --- a/registry/storage/blobstore.go +++ b/registry/storage/blobstore.go @@ -9,6 +9,7 @@ import ( "github.com/distribution/distribution/v3/internal/dcontext" "github.com/distribution/distribution/v3/registry/storage/driver" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // blobStore implements the read side of the blob store interface over a @@ -59,7 +60,7 @@ func (bs *blobStore) Open(ctx context.Context, dgst digest.Digest) (io.ReadSeekC // Put stores the content p in the blob store, calculating the digest. If the // content is already present, only the digest will be returned. This should // only be used for small objects, such as manifests. This implemented as a convenience for other Put implementations -func (bs *blobStore) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) { +func (bs *blobStore) Put(ctx context.Context, mediaType string, p []byte) (v1.Descriptor, error) { dgst := digest.FromBytes(p) desc, err := bs.statter.Stat(ctx, dgst) if err == nil { @@ -68,16 +69,16 @@ func (bs *blobStore) Put(ctx context.Context, mediaType string, p []byte) (distr } else if err != distribution.ErrBlobUnknown { dcontext.GetLogger(ctx).Errorf("blobStore: error stating content (%v): %v", dgst, err) // real error, return it - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } bp, err := bs.path(dgst) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } // TODO(stevvooe): Write out mediatype here, as well. - return distribution.Descriptor{ + return v1.Descriptor{ Size: int64(len(p)), // NOTE(stevvooe): The central blob store firewalls media types from @@ -161,21 +162,21 @@ var _ distribution.BlobDescriptorService = &blobStatter{} // Stat implements BlobStatter.Stat by returning the descriptor for the blob // in the main blob store. If this method returns successfully, there is // strong guarantee that the blob exists and is available. -func (bs *blobStatter) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (bs *blobStatter) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { path, err := pathFor(blobDataPathSpec{ digest: dgst, }) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } fi, err := bs.driver.Stat(ctx, path) if err != nil { switch err := err.(type) { case driver.PathNotFoundError: - return distribution.Descriptor{}, distribution.ErrBlobUnknown + return v1.Descriptor{}, distribution.ErrBlobUnknown default: - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } } @@ -184,14 +185,14 @@ func (bs *blobStatter) Stat(ctx context.Context, dgst digest.Digest) (distributi // calculated a blob path and then detected a directory. We log the // error and then error on the side of not knowing about the blob. dcontext.GetLogger(ctx).Warnf("blob path should not be a directory: %q", path) - return distribution.Descriptor{}, distribution.ErrBlobUnknown + return v1.Descriptor{}, distribution.ErrBlobUnknown } // TODO(stevvooe): Add method to resolve the mediatype. We can store and // cache a "global" media type for the blob, even if a specific repo has a // mediatype that overrides the main one. - return distribution.Descriptor{ + return v1.Descriptor{ Size: fi.Size(), // NOTE(stevvooe): The central blob store firewalls media types from @@ -206,6 +207,6 @@ func (bs *blobStatter) Clear(ctx context.Context, dgst digest.Digest) error { return distribution.ErrUnsupported } -func (bs *blobStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error { +func (bs *blobStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error { return distribution.ErrUnsupported } diff --git a/registry/storage/blobwriter.go b/registry/storage/blobwriter.go index 6240981270e..e3c7fe6158a 100644 --- a/registry/storage/blobwriter.go +++ b/registry/storage/blobwriter.go @@ -12,6 +12,7 @@ import ( "github.com/distribution/distribution/v3/internal/dcontext" storagedriver "github.com/distribution/distribution/v3/registry/storage/driver" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/sirupsen/logrus" ) @@ -54,11 +55,11 @@ func (bw *blobWriter) StartedAt() time.Time { // Commit marks the upload as completed, returning a valid descriptor. The // final size and digest are checked against the first descriptor provided. -func (bw *blobWriter) Commit(ctx context.Context, desc distribution.Descriptor) (distribution.Descriptor, error) { +func (bw *blobWriter) Commit(ctx context.Context, desc v1.Descriptor) (v1.Descriptor, error) { dcontext.GetLogger(ctx).Debug("(*blobWriter).Commit") if err := bw.fileWriter.Commit(ctx); err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } bw.Close() @@ -66,24 +67,24 @@ func (bw *blobWriter) Commit(ctx context.Context, desc distribution.Descriptor) canonical, err := bw.validateBlob(ctx, desc) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } if err := bw.moveBlob(ctx, canonical); err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } if err := bw.blobStore.linkBlob(ctx, canonical, desc.Digest); err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } if err := bw.removeResources(ctx); err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } err = bw.blobStore.blobAccessController.SetDescriptor(ctx, canonical.Digest, canonical) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } bw.committed = true @@ -160,7 +161,7 @@ func (bw *blobWriter) Close() error { // validateBlob checks the data against the digest, returning an error if it // does not match. The canonical descriptor is returned. -func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descriptor) (distribution.Descriptor, error) { +func (bw *blobWriter) validateBlob(ctx context.Context, desc v1.Descriptor) (v1.Descriptor, error) { var ( verified, fullHash bool canonical digest.Digest @@ -169,7 +170,7 @@ func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descri if desc.Digest == "" { // if no descriptors are provided, we have nothing to validate // against. We don't really want to support this for the registry. - return distribution.Descriptor{}, distribution.ErrBlobInvalidDigest{ + return v1.Descriptor{}, distribution.ErrBlobInvalidDigest{ Reason: fmt.Errorf("cannot validate against empty digest"), } } @@ -186,11 +187,11 @@ func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descri desc.Size = 0 default: // Any other error we want propagated up the stack. - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } } else { if fi.IsDir() { - return distribution.Descriptor{}, fmt.Errorf("unexpected directory at upload location %q", bw.path) + return v1.Descriptor{}, fmt.Errorf("unexpected directory at upload location %q", bw.path) } size = fi.Size() @@ -198,7 +199,7 @@ func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descri if desc.Size > 0 { if desc.Size != size { - return distribution.Descriptor{}, distribution.ErrBlobInvalidLength + return v1.Descriptor{}, distribution.ErrBlobInvalidLength } } else { // if provided 0 or negative length, we can assume caller doesn't know or @@ -226,7 +227,7 @@ func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descri // Not using resumable digests, so we need to hash the entire layer. fullHash = true } else { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } if fullHash { @@ -249,14 +250,14 @@ func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descri // Read the file from the backend driver and validate it. fr, err := newFileReader(ctx, bw.driver, bw.path, desc.Size) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } defer fr.Close() tr := io.TeeReader(fr, digester.Hash()) if _, err := io.Copy(verifier, tr); err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } canonical = digester.Digest() @@ -271,7 +272,7 @@ func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descri "provided": desc.Digest, }, "canonical", "provided"). Errorf("canonical digest does match provided digest") - return distribution.Descriptor{}, distribution.ErrBlobInvalidDigest{ + return v1.Descriptor{}, distribution.ErrBlobInvalidDigest{ Digest: desc.Digest, Reason: fmt.Errorf("content does not match digest"), } @@ -290,7 +291,7 @@ func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descri // moveBlob moves the data into its final, hash-qualified destination, // identified by dgst. The layer should be validated before commencing the // move. -func (bw *blobWriter) moveBlob(ctx context.Context, desc distribution.Descriptor) error { +func (bw *blobWriter) moveBlob(ctx context.Context, desc v1.Descriptor) error { blobPath, err := pathFor(blobDataPathSpec{ digest: desc.Digest, }) diff --git a/registry/storage/cache/cache.go b/registry/storage/cache/cache.go index 0aa9dd4a80e..8cf9b2b04da 100644 --- a/registry/storage/cache/cache.go +++ b/registry/storage/cache/cache.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/distribution/distribution/v3" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // BlobDescriptorCacheProvider provides repository scoped @@ -18,7 +19,7 @@ type BlobDescriptorCacheProvider interface { // ValidateDescriptor provides a helper function to ensure that caches have // common criteria for admitting descriptors. -func ValidateDescriptor(desc distribution.Descriptor) error { +func ValidateDescriptor(desc v1.Descriptor) error { if err := desc.Digest.Validate(); err != nil { return err } diff --git a/registry/storage/cache/cache_test.go b/registry/storage/cache/cache_test.go index 2b0624918fb..5a18696a0b8 100644 --- a/registry/storage/cache/cache_test.go +++ b/registry/storage/cache/cache_test.go @@ -7,6 +7,7 @@ import ( "github.com/distribution/distribution/v3" digest "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) func TestCacheSet(t *testing.T) { @@ -21,7 +22,7 @@ func TestCacheSet(t *testing.T) { t.Fatalf("Unexpected error %v, expected %v", err, distribution.ErrBlobUnknown) } - desc := distribution.Descriptor{ + desc := v1.Descriptor{ Digest: dgst, } if err := backend.SetDescriptor(ctx, dgst, desc); err != nil { @@ -43,7 +44,7 @@ func TestCacheSet(t *testing.T) { t.Fatalf("Unexpected descriptor %v, expected %v", cache.sets[dgst][0], desc) } - desc2 := distribution.Descriptor{ + desc2 := v1.Descriptor{ Digest: digest.Digest("dontvalidate 2"), } cache.sets[dgst] = append(cache.sets[dgst], desc2) @@ -69,7 +70,7 @@ func TestCacheError(t *testing.T) { t.Fatalf("Unexpected error %v, expected %v", err, distribution.ErrBlobUnknown) } - desc := distribution.Descriptor{ + desc := v1.Descriptor{ Digest: dgst, } if err := backend.SetDescriptor(ctx, dgst, desc); err != nil { @@ -92,36 +93,36 @@ func TestCacheError(t *testing.T) { func newTestStatter() *testStatter { return &testStatter{ stats: []digest.Digest{}, - sets: map[digest.Digest][]distribution.Descriptor{}, + sets: map[digest.Digest][]v1.Descriptor{}, } } func newErrTestStatter(err error) *testStatter { return &testStatter{ - sets: map[digest.Digest][]distribution.Descriptor{}, + sets: map[digest.Digest][]v1.Descriptor{}, err: err, } } type testStatter struct { stats []digest.Digest - sets map[digest.Digest][]distribution.Descriptor + sets map[digest.Digest][]v1.Descriptor err error } -func (s *testStatter) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (s *testStatter) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { if s.err != nil { - return distribution.Descriptor{}, s.err + return v1.Descriptor{}, s.err } if set := s.sets[dgst]; len(set) > 0 { return set[len(set)-1], nil } - return distribution.Descriptor{}, distribution.ErrBlobUnknown + return v1.Descriptor{}, distribution.ErrBlobUnknown } -func (s *testStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error { +func (s *testStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error { s.sets[dgst] = append(s.sets[dgst], desc) return s.err } diff --git a/registry/storage/cache/cachecheck/suite.go b/registry/storage/cache/cachecheck/suite.go index 2afff5bbc7d..6cbe49be586 100644 --- a/registry/storage/cache/cachecheck/suite.go +++ b/registry/storage/cache/cachecheck/suite.go @@ -8,6 +8,7 @@ import ( "github.com/distribution/distribution/v3" "github.com/distribution/distribution/v3/registry/storage/cache" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // CheckBlobDescriptorCache takes a cache implementation through a common set @@ -36,7 +37,7 @@ func checkBlobDescriptorCacheEmptyRepository(ctx context.Context, t *testing.T, t.Fatalf("unexpected error getting repository: %v", err) } - if err := cache.SetDescriptor(ctx, "", distribution.Descriptor{ + if err := cache.SetDescriptor(ctx, "", v1.Descriptor{ Digest: "sha384:abc", Size: 10, MediaType: "application/octet-stream", @@ -44,7 +45,7 @@ func checkBlobDescriptorCacheEmptyRepository(ctx context.Context, t *testing.T, t.Fatalf("expected error with invalid digest: %v", err) } - if err := cache.SetDescriptor(ctx, "sha384:abc111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", distribution.Descriptor{ + if err := cache.SetDescriptor(ctx, "sha384:abc111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", v1.Descriptor{ Digest: "", Size: 10, MediaType: "application/octet-stream", @@ -67,7 +68,7 @@ func checkBlobDescriptorCacheEmptyRepository(ctx context.Context, t *testing.T, func checkBlobDescriptorCacheSetAndRead(ctx context.Context, t *testing.T, provider cache.BlobDescriptorCacheProvider) { localDigest := digest.Digest("sha384:abc111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111") - expected := distribution.Descriptor{ + expected := v1.Descriptor{ Digest: "sha256:abc1111111111111111111111111111111111111111111111111111111111111", Size: 10, MediaType: "application/octet-stream", @@ -152,7 +153,7 @@ func checkBlobDescriptorCacheSetAndRead(ctx context.Context, t *testing.T, provi func checkBlobDescriptorCacheClear(ctx context.Context, t *testing.T, provider cache.BlobDescriptorCacheProvider) { localDigest := digest.Digest("sha384:def111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111") - expected := distribution.Descriptor{ + expected := v1.Descriptor{ Digest: "sha256:def1111111111111111111111111111111111111111111111111111111111111", Size: 10, MediaType: "application/octet-stream", diff --git a/registry/storage/cache/cachedblobdescriptorstore.go b/registry/storage/cache/cachedblobdescriptorstore.go index 38dd1dcff60..d3f708449c4 100644 --- a/registry/storage/cache/cachedblobdescriptorstore.go +++ b/registry/storage/cache/cachedblobdescriptorstore.go @@ -7,6 +7,7 @@ import ( "github.com/distribution/distribution/v3/internal/dcontext" prometheus "github.com/distribution/distribution/v3/metrics" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) type cachedBlobStatter struct { @@ -32,7 +33,7 @@ func NewCachedBlobStatter(cache distribution.BlobDescriptorService, backend dist } } -func (cbds *cachedBlobStatter) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (cbds *cachedBlobStatter) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { cacheRequestCount.Inc(1) // try getting from cache @@ -75,7 +76,7 @@ func (cbds *cachedBlobStatter) Clear(ctx context.Context, dgst digest.Digest) er return nil } -func (cbds *cachedBlobStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error { +func (cbds *cachedBlobStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error { if err := cbds.cache.SetDescriptor(ctx, dgst, desc); err != nil { dcontext.GetLoggerWithField(ctx, "blob", dgst).WithError(err).Error("error from cache setting desc") } diff --git a/registry/storage/cache/memory/memory.go b/registry/storage/cache/memory/memory.go index f83894bf54c..8bf996ad7e5 100644 --- a/registry/storage/cache/memory/memory.go +++ b/registry/storage/cache/memory/memory.go @@ -9,6 +9,7 @@ import ( "github.com/distribution/reference" "github.com/hashicorp/golang-lru/arc/v2" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) const ( @@ -26,7 +27,7 @@ type descriptorCacheKey struct { } type inMemoryBlobDescriptorCacheProvider struct { - lru *arc.ARCCache[descriptorCacheKey, distribution.Descriptor] + lru *arc.ARCCache[descriptorCacheKey, v1.Descriptor] } // NewInMemoryBlobDescriptorCacheProvider returns a new mapped-based cache for @@ -35,7 +36,7 @@ func NewInMemoryBlobDescriptorCacheProvider(size int) cache.BlobDescriptorCacheP if size <= 0 { size = math.MaxInt } - lruCache, err := arc.NewARC[descriptorCacheKey, distribution.Descriptor](size) + lruCache, err := arc.NewARC[descriptorCacheKey, v1.Descriptor](size) if err != nil { // NewARC can only fail if size is <= 0, so this unreachable panic(err) @@ -62,9 +63,9 @@ func (imbdcp *inMemoryBlobDescriptorCacheProvider) RepositoryScoped(repo string) }, nil } -func (imbdcp *inMemoryBlobDescriptorCacheProvider) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (imbdcp *inMemoryBlobDescriptorCacheProvider) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { if err := dgst.Validate(); err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } key := descriptorCacheKey{ @@ -74,7 +75,7 @@ func (imbdcp *inMemoryBlobDescriptorCacheProvider) Stat(ctx context.Context, dgs if ok { return descriptor, nil } - return distribution.Descriptor{}, distribution.ErrBlobUnknown + return v1.Descriptor{}, distribution.ErrBlobUnknown } func (imbdcp *inMemoryBlobDescriptorCacheProvider) Clear(ctx context.Context, dgst digest.Digest) error { @@ -85,7 +86,7 @@ func (imbdcp *inMemoryBlobDescriptorCacheProvider) Clear(ctx context.Context, dg return nil } -func (imbdcp *inMemoryBlobDescriptorCacheProvider) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error { +func (imbdcp *inMemoryBlobDescriptorCacheProvider) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error { _, err := imbdcp.Stat(ctx, dgst) if err == distribution.ErrBlobUnknown { if dgst.Algorithm() != desc.Digest.Algorithm() && dgst != desc.Digest { @@ -121,9 +122,9 @@ type repositoryScopedInMemoryBlobDescriptorCache struct { parent *inMemoryBlobDescriptorCacheProvider // allows lazy allocation of repo's map } -func (rsimbdcp *repositoryScopedInMemoryBlobDescriptorCache) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (rsimbdcp *repositoryScopedInMemoryBlobDescriptorCache) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { if err := dgst.Validate(); err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } key := descriptorCacheKey{ @@ -134,7 +135,7 @@ func (rsimbdcp *repositoryScopedInMemoryBlobDescriptorCache) Stat(ctx context.Co if ok { return descriptor, nil } - return distribution.Descriptor{}, distribution.ErrBlobUnknown + return v1.Descriptor{}, distribution.ErrBlobUnknown } func (rsimbdcp *repositoryScopedInMemoryBlobDescriptorCache) Clear(ctx context.Context, dgst digest.Digest) error { @@ -146,7 +147,7 @@ func (rsimbdcp *repositoryScopedInMemoryBlobDescriptorCache) Clear(ctx context.C return nil } -func (rsimbdcp *repositoryScopedInMemoryBlobDescriptorCache) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error { +func (rsimbdcp *repositoryScopedInMemoryBlobDescriptorCache) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error { if err := dgst.Validate(); err != nil { return err } diff --git a/registry/storage/cache/metrics/prom.go b/registry/storage/cache/metrics/prom.go index 5401e12f08b..f08ea8fa737 100644 --- a/registry/storage/cache/metrics/prom.go +++ b/registry/storage/cache/metrics/prom.go @@ -9,6 +9,7 @@ import ( "github.com/distribution/distribution/v3/registry/storage/cache" "github.com/docker/go-metrics" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) type prometheusCacheProvider struct { @@ -24,14 +25,14 @@ func NewPrometheusCacheProvider(wrap cache.BlobDescriptorCacheProvider, name, he } } -func (p *prometheusCacheProvider) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (p *prometheusCacheProvider) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { start := time.Now() d, e := p.BlobDescriptorCacheProvider.Stat(ctx, dgst) p.latencyTimer.WithValues("Stat").UpdateSince(start) return d, e } -func (p *prometheusCacheProvider) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error { +func (p *prometheusCacheProvider) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error { start := time.Now() e := p.BlobDescriptorCacheProvider.SetDescriptor(ctx, dgst, desc) p.latencyTimer.WithValues("SetDescriptor").UpdateSince(start) @@ -43,14 +44,14 @@ type prometheusRepoCacheProvider struct { latencyTimer metrics.LabeledTimer } -func (p *prometheusRepoCacheProvider) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (p *prometheusRepoCacheProvider) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { start := time.Now() d, e := p.BlobDescriptorService.Stat(ctx, dgst) p.latencyTimer.WithValues("RepoStat").UpdateSince(start) return d, e } -func (p *prometheusRepoCacheProvider) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error { +func (p *prometheusRepoCacheProvider) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error { start := time.Now() e := p.BlobDescriptorService.SetDescriptor(ctx, dgst, desc) p.latencyTimer.WithValues("RepoSetDescriptor").UpdateSince(start) diff --git a/registry/storage/cache/redis/redis.go b/registry/storage/cache/redis/redis.go index baae8e1be6b..3aee5c9a87a 100644 --- a/registry/storage/cache/redis/redis.go +++ b/registry/storage/cache/redis/redis.go @@ -10,6 +10,7 @@ import ( "github.com/distribution/distribution/v3/registry/storage/cache/metrics" "github.com/distribution/reference" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/redis/go-redis/v9" ) @@ -66,9 +67,9 @@ func (rbds *redisBlobDescriptorService) RepositoryScoped(repo string) (distribut } // Stat retrieves the descriptor data from the redis hash entry. -func (rbds *redisBlobDescriptorService) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (rbds *redisBlobDescriptorService) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { if err := dgst.Validate(); err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } return rbds.stat(ctx, dgst) @@ -91,33 +92,33 @@ func (rbds *redisBlobDescriptorService) Clear(ctx context.Context, dgst digest.D return nil } -func (rbds *redisBlobDescriptorService) stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (rbds *redisBlobDescriptorService) stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { cmd := rbds.pool.HMGet(ctx, rbds.blobDescriptorHashKey(dgst), "digest", "size", "mediatype") reply, err := cmd.Result() if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } // NOTE(stevvooe): The "size" field used to be "length". We treat a // missing "size" field here as an unknown blob, which causes a cache // miss, effectively migrating the field. if len(reply) < 3 || reply[0] == nil || reply[1] == nil { // don't care if mediatype is nil - return distribution.Descriptor{}, distribution.ErrBlobUnknown + return v1.Descriptor{}, distribution.ErrBlobUnknown } - var desc distribution.Descriptor + var desc v1.Descriptor digestString, ok := reply[0].(string) if !ok { - return distribution.Descriptor{}, fmt.Errorf("digest is not a string") + return v1.Descriptor{}, fmt.Errorf("digest is not a string") } desc.Digest = digest.Digest(digestString) sizeString, ok := reply[1].(string) if !ok { - return distribution.Descriptor{}, fmt.Errorf("size is not a string") + return v1.Descriptor{}, fmt.Errorf("size is not a string") } size, err := strconv.ParseInt(sizeString, 10, 64) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } desc.Size = size if reply[2] != nil { @@ -132,7 +133,7 @@ func (rbds *redisBlobDescriptorService) stat(ctx context.Context, dgst digest.Di // SetDescriptor sets the descriptor data for the given digest using a redis // hash. A hash is used here since we may store unrelated fields about a layer // in the future. -func (rbds *redisBlobDescriptorService) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error { +func (rbds *redisBlobDescriptorService) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error { if err := dgst.Validate(); err != nil { return err } @@ -144,7 +145,7 @@ func (rbds *redisBlobDescriptorService) SetDescriptor(ctx context.Context, dgst return rbds.setDescriptor(ctx, dgst, desc) } -func (rbds *redisBlobDescriptorService) setDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error { +func (rbds *redisBlobDescriptorService) setDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error { cmd := rbds.pool.HMSet(ctx, rbds.blobDescriptorHashKey(dgst), "digest", desc.Digest.String(), "size", desc.Size) if cmd.Err() != nil { return cmd.Err() @@ -171,33 +172,33 @@ var _ distribution.BlobDescriptorService = &repositoryScopedRedisBlobDescriptorS // Stat ensures that the digest is a member of the specified repository and // forwards the descriptor request to the global blob store. If the media type // differs for the repository, we override it. -func (rsrbds *repositoryScopedRedisBlobDescriptorService) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (rsrbds *repositoryScopedRedisBlobDescriptorService) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { if err := dgst.Validate(); err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } pool := rsrbds.upstream.pool // Check membership to repository first member, err := pool.SIsMember(ctx, rsrbds.repositoryBlobSetKey(rsrbds.repo), dgst.String()).Result() if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } if !member { - return distribution.Descriptor{}, distribution.ErrBlobUnknown + return v1.Descriptor{}, distribution.ErrBlobUnknown } upstream, err := rsrbds.upstream.stat(ctx, dgst) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } // We allow a per repository mediatype, let's look it up here. mediatype, err := pool.HGet(ctx, rsrbds.blobDescriptorHashKey(dgst), "mediatype").Result() if err != nil { if err == redis.Nil { - return distribution.Descriptor{}, distribution.ErrBlobUnknown + return v1.Descriptor{}, distribution.ErrBlobUnknown } - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } if mediatype != "" { @@ -225,7 +226,7 @@ func (rsrbds *repositoryScopedRedisBlobDescriptorService) Clear(ctx context.Cont return rsrbds.upstream.Clear(ctx, dgst) } -func (rsrbds *repositoryScopedRedisBlobDescriptorService) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error { +func (rsrbds *repositoryScopedRedisBlobDescriptorService) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error { if err := dgst.Validate(); err != nil { return err } @@ -243,7 +244,7 @@ func (rsrbds *repositoryScopedRedisBlobDescriptorService) SetDescriptor(ctx cont return rsrbds.setDescriptor(ctx, dgst, desc) } -func (rsrbds *repositoryScopedRedisBlobDescriptorService) setDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error { +func (rsrbds *repositoryScopedRedisBlobDescriptorService) setDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error { conn := rsrbds.upstream.pool _, err := conn.SAdd(ctx, rsrbds.repositoryBlobSetKey(rsrbds.repo), dgst.String()).Result() if err != nil { diff --git a/registry/storage/garbagecollect.go b/registry/storage/garbagecollect.go index 49f53541d4d..d909f93adc3 100644 --- a/registry/storage/garbagecollect.go +++ b/registry/storage/garbagecollect.go @@ -9,6 +9,7 @@ import ( "github.com/distribution/distribution/v3/registry/storage/driver" "github.com/distribution/reference" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) func emit(format string, a ...interface{}) { @@ -65,7 +66,7 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis err = manifestEnumerator.Enumerate(ctx, func(dgst digest.Digest) error { if opts.RemoveUntagged { // fetch all tags where this manifest is the latest one - tags, err := repository.Tags(ctx).Lookup(ctx, distribution.Descriptor{Digest: dgst}) + tags, err := repository.Tags(ctx).Lookup(ctx, v1.Descriptor{Digest: dgst}) if err != nil { return fmt.Errorf("failed to retrieve tags for digest %v: %v", dgst, err) } diff --git a/registry/storage/garbagecollect_test.go b/registry/storage/garbagecollect_test.go index ea36d6dab8d..103758e245e 100644 --- a/registry/storage/garbagecollect_test.go +++ b/registry/storage/garbagecollect_test.go @@ -14,6 +14,7 @@ import ( "github.com/distribution/distribution/v3/testutil" "github.com/distribution/reference" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) type image struct { @@ -250,7 +251,7 @@ func TestDeleteManifestIfTagNotFound(t *testing.T) { manifestEnumerator, _ := manifestService.(distribution.ManifestEnumerator) err = manifestEnumerator.Enumerate(ctx, func(dgst digest.Digest) error { - return repo.Tags(ctx).Tag(ctx, "test", distribution.Descriptor{Digest: dgst}) + return repo.Tags(ctx).Tag(ctx, "test", v1.Descriptor{Digest: dgst}) }) if err != nil { t.Fatalf("manifest enumeration failed: %v", err) @@ -306,7 +307,7 @@ func TestDeleteManifestIndexWithDanglingReferences(t *testing.T) { image1 := uploadRandomOCIImage(t, repo) image2 := uploadRandomOCIImage(t, repo) - ii, _ := ocischema.FromDescriptors([]distribution.Descriptor{ + ii, _ := ocischema.FromDescriptors([]v1.Descriptor{ {Digest: image1.manifestDigest}, {Digest: image2.manifestDigest}, }, map[string]string{}) @@ -315,7 +316,7 @@ func TestDeleteManifestIndexWithDanglingReferences(t *testing.T) { t.Fatalf("manifest upload failed: %v", err) } - err = repo.Tags(ctx).Tag(ctx, "test", distribution.Descriptor{Digest: id}) + err = repo.Tags(ctx).Tag(ctx, "test", v1.Descriptor{Digest: id}) if err != nil { t.Fatalf("Failed to delete tag: %v", err) } @@ -359,7 +360,7 @@ func TestDeleteManifestIndexIfTagNotFound(t *testing.T) { image1 := uploadRandomOCIImage(t, repo) image2 := uploadRandomOCIImage(t, repo) - ii, _ := ocischema.FromDescriptors([]distribution.Descriptor{ + ii, _ := ocischema.FromDescriptors([]v1.Descriptor{ {Digest: image1.manifestDigest}, {Digest: image2.manifestDigest}, }, map[string]string{}) @@ -368,7 +369,7 @@ func TestDeleteManifestIndexIfTagNotFound(t *testing.T) { t.Fatalf("manifest upload failed: %v", err) } - err = repo.Tags(ctx).Tag(ctx, "test", distribution.Descriptor{Digest: d4}) + err = repo.Tags(ctx).Tag(ctx, "test", v1.Descriptor{Digest: d4}) if err != nil { t.Fatalf("Failed to delete tag: %v", err) } @@ -466,7 +467,7 @@ func TestGCWithUnknownRepository(t *testing.T) { repo := makeRepository(t, registry, "nonexistentrepo") image := uploadRandomSchema2Image(t, repo) - err := repo.Tags(ctx).Tag(ctx, "image", distribution.Descriptor{Digest: image.manifestDigest}) + err := repo.Tags(ctx).Tag(ctx, "image", v1.Descriptor{Digest: image.manifestDigest}) if err != nil { t.Fatalf("Failed to tag descriptor: %v", err) } @@ -729,7 +730,7 @@ func TestTaggedManifestlistWithUntaggedManifest(t *testing.T) { t.Fatalf("Failed to add manifest list: %v", err) } - err = repo.Tags(ctx).Tag(ctx, "test", distribution.Descriptor{Digest: dgst}) + err = repo.Tags(ctx).Tag(ctx, "test", v1.Descriptor{Digest: dgst}) if err != nil { t.Fatalf("Failed to delete tag: %v", err) } @@ -821,12 +822,12 @@ func TestUnTaggedManifestlistWithTaggedManifest(t *testing.T) { image1 := uploadRandomSchema2Image(t, repo) image2 := uploadRandomSchema2Image(t, repo) - err = repo.Tags(ctx).Tag(ctx, "image1", distribution.Descriptor{Digest: image1.manifestDigest}) + err = repo.Tags(ctx).Tag(ctx, "image1", v1.Descriptor{Digest: image1.manifestDigest}) if err != nil { t.Fatalf("Failed to delete tag: %v", err) } - err = repo.Tags(ctx).Tag(ctx, "image2", distribution.Descriptor{Digest: image2.manifestDigest}) + err = repo.Tags(ctx).Tag(ctx, "image2", v1.Descriptor{Digest: image2.manifestDigest}) if err != nil { t.Fatalf("Failed to delete tag: %v", err) } diff --git a/registry/storage/linkedblobstore.go b/registry/storage/linkedblobstore.go index 18d40d27832..fc5e98c7a21 100644 --- a/registry/storage/linkedblobstore.go +++ b/registry/storage/linkedblobstore.go @@ -14,6 +14,7 @@ import ( "github.com/distribution/reference" "github.com/google/uuid" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // linkPathFunc describes a function that can resolve a link based on the @@ -45,7 +46,7 @@ type linkedBlobStore struct { var _ distribution.BlobStore = &linkedBlobStore{} -func (lbs *linkedBlobStore) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (lbs *linkedBlobStore) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { return lbs.blobAccessController.Stat(ctx, dgst) } @@ -81,17 +82,17 @@ func (lbs *linkedBlobStore) ServeBlob(ctx context.Context, w http.ResponseWriter return lbs.blobServer.ServeBlob(ctx, w, r, canonical.Digest) } -func (lbs *linkedBlobStore) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) { +func (lbs *linkedBlobStore) Put(ctx context.Context, mediaType string, p []byte) (v1.Descriptor, error) { dgst := digest.FromBytes(p) // Place the data in the blob store first. desc, err := lbs.blobStore.Put(ctx, mediaType, p) if err != nil { dcontext.GetLogger(ctx).Errorf("error putting into main store: %v", err) - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } if err := lbs.blobAccessController.SetDescriptor(ctx, dgst, desc); err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } // TODO(stevvooe): Write out mediatype if incoming differs from what is @@ -270,24 +271,24 @@ func (lbs *linkedBlobStore) Enumerate(ctx context.Context, ingestor func(digest. }) } -func (lbs *linkedBlobStore) mount(ctx context.Context, sourceRepo reference.Named, dgst digest.Digest, sourceStat *distribution.Descriptor) (distribution.Descriptor, error) { - var stat distribution.Descriptor +func (lbs *linkedBlobStore) mount(ctx context.Context, sourceRepo reference.Named, dgst digest.Digest, sourceStat *v1.Descriptor) (v1.Descriptor, error) { + var stat v1.Descriptor if sourceStat == nil { // look up the blob info from the sourceRepo if not already provided repo, err := lbs.registry.Repository(ctx, sourceRepo) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } stat, err = repo.Blobs(ctx).Stat(ctx, dgst) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } } else { // use the provided blob info stat = *sourceStat } - desc := distribution.Descriptor{ + desc := v1.Descriptor{ Size: stat.Size, // NOTE(stevvooe): The central blob store firewalls media types from @@ -323,7 +324,7 @@ func (lbs *linkedBlobStore) newBlobUpload(ctx context.Context, uuid, path string // linkBlob links a valid, written blob into the registry under the named // repository for the upload controller. -func (lbs *linkedBlobStore) linkBlob(ctx context.Context, canonical distribution.Descriptor, aliases ...digest.Digest) error { +func (lbs *linkedBlobStore) linkBlob(ctx context.Context, canonical v1.Descriptor, aliases ...digest.Digest) error { dgsts := append([]digest.Digest{canonical.Digest}, aliases...) // TODO(stevvooe): Need to write out mediatype for only canonical hash @@ -365,19 +366,19 @@ type linkedBlobStatter struct { var _ distribution.BlobDescriptorService = &linkedBlobStatter{} -func (lbs *linkedBlobStatter) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (lbs *linkedBlobStatter) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { blobLinkPath, err := lbs.linkPath(lbs.repository.Named().Name(), dgst) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } target, err := lbs.blobStore.readlink(ctx, blobLinkPath) if err != nil { switch err := err.(type) { case driver.PathNotFoundError: - return distribution.Descriptor{}, distribution.ErrBlobUnknown + return v1.Descriptor{}, distribution.ErrBlobUnknown default: - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } } @@ -401,7 +402,7 @@ func (lbs *linkedBlobStatter) Clear(ctx context.Context, dgst digest.Digest) (er return lbs.blobStore.driver.Delete(ctx, blobLinkPath) } -func (lbs *linkedBlobStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error { +func (lbs *linkedBlobStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error { // The canonical descriptor for a blob is set at the commit phase of upload return nil } diff --git a/registry/storage/linkedblobstore_test.go b/registry/storage/linkedblobstore_test.go index 32a20d4103f..0c61e084806 100644 --- a/registry/storage/linkedblobstore_test.go +++ b/registry/storage/linkedblobstore_test.go @@ -13,6 +13,7 @@ import ( "github.com/distribution/distribution/v3/testutil" "github.com/distribution/reference" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) func TestLinkedBlobStoreEnumerator(t *testing.T) { @@ -38,7 +39,7 @@ func TestLinkedBlobStoreEnumerator(t *testing.T) { t.Fatalf("unexpected error copying to upload: %v", err) } - if _, err := wr.Commit(fooEnv.ctx, distribution.Descriptor{Digest: dgst}); err != nil { + if _, err := wr.Commit(fooEnv.ctx, v1.Descriptor{Digest: dgst}); err != nil { t.Fatalf("unexpected error finishing upload: %v", err) } } @@ -95,7 +96,7 @@ func TestLinkedBlobStoreCreateWithMountFrom(t *testing.T) { t.Fatalf("unexpected error copying to upload: %v", err) } - if _, err := wr.Commit(fooEnv.ctx, distribution.Descriptor{Digest: dgst}); err != nil { + if _, err := wr.Commit(fooEnv.ctx, v1.Descriptor{Digest: dgst}); err != nil { t.Fatalf("unexpected error finishing upload: %v", err) } } @@ -154,7 +155,7 @@ func TestLinkedBlobStoreCreateWithMountFrom(t *testing.T) { if err != nil { t.Fatal(err) } - prepolutatedDescriptor := distribution.Descriptor{ + prepolutatedDescriptor := v1.Descriptor{ Digest: dgst, Size: size, MediaType: "application/octet-stream", @@ -223,16 +224,16 @@ type mockBlobDescriptorService struct { var _ distribution.BlobDescriptorService = &mockBlobDescriptorService{} -func (bs *mockBlobDescriptorService) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { +func (bs *mockBlobDescriptorService) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) { statter, ok := bs.BlobDescriptorService.(*linkedBlobStatter) if !ok { - return distribution.Descriptor{}, fmt.Errorf("unexpected blob descriptor service: %T", bs.BlobDescriptorService) + return v1.Descriptor{}, fmt.Errorf("unexpected blob descriptor service: %T", bs.BlobDescriptorService) } name := statter.repository.Named() canonical, err := reference.WithDigest(name, dgst) if err != nil { - return distribution.Descriptor{}, fmt.Errorf("failed to make canonical reference: %v", err) + return v1.Descriptor{}, fmt.Errorf("failed to make canonical reference: %v", err) } bs.stats[canonical.String()]++ @@ -243,7 +244,7 @@ func (bs *mockBlobDescriptorService) Stat(ctx context.Context, dgst digest.Diges // statCrossMountCreateOptions ensures the expected options type is passed, and optionally pre-fills the cross-mount stat info type statCrossMountCreateOption struct { - desc distribution.Descriptor + desc v1.Descriptor } var _ distribution.BlobCreateOption = statCrossMountCreateOption{} diff --git a/registry/storage/manifestlisthandler.go b/registry/storage/manifestlisthandler.go index f7ded4333e4..052707394f5 100644 --- a/registry/storage/manifestlisthandler.go +++ b/registry/storage/manifestlisthandler.go @@ -9,6 +9,7 @@ import ( "github.com/distribution/distribution/v3/manifest/manifestlist" "github.com/distribution/distribution/v3/manifest/ocischema" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // manifestListHandler is a ManifestHandler that covers schema2 manifest lists. @@ -104,7 +105,7 @@ func (ms *manifestListHandler) verifyManifest(ctx context.Context, mnfst distrib } // platformMustExist checks if a descriptor within an index should be validated as existing before accepting the manifest into the registry. -func (ms *manifestListHandler) platformMustExist(descriptor distribution.Descriptor) bool { +func (ms *manifestListHandler) platformMustExist(descriptor v1.Descriptor) bool { // If there are no image platforms configured to validate, we must check the existence of all child images. if len(ms.validateImageIndexes.imagePlatforms) == 0 { return true diff --git a/registry/storage/manifeststore_test.go b/registry/storage/manifeststore_test.go index 9f258c3db0a..57c9fa83f8d 100644 --- a/registry/storage/manifeststore_test.go +++ b/registry/storage/manifeststore_test.go @@ -96,12 +96,12 @@ func testManifestStorage(t *testing.T, options ...RegistryOption) { m := &schema2.Manifest{ Versioned: specs.Versioned{SchemaVersion: 2}, MediaType: schema2.MediaTypeManifest, - Config: distribution.Descriptor{ + Config: v1.Descriptor{ Digest: digest.FromBytes(sampleConfig), Size: int64(len(sampleConfig)), MediaType: schema2.MediaTypeImageConfig, }, - Layers: []distribution.Descriptor{}, + Layers: []v1.Descriptor{}, } // Build up some test layers and add them to the manifest, saving the @@ -114,7 +114,7 @@ func testManifestStorage(t *testing.T, options ...RegistryOption) { } testLayers[dgst] = rs - layer := distribution.Descriptor{ + layer := v1.Descriptor{ Digest: dgst, Size: 6323, MediaType: schema2.MediaTypeLayer, @@ -133,10 +133,10 @@ func testManifestStorage(t *testing.T, options ...RegistryOption) { t.Fatalf("unexpected error copying to upload: %v", err) } - if _, err := wr.Commit(env.ctx, distribution.Descriptor{Digest: dgst}); err != nil { + if _, err := wr.Commit(env.ctx, v1.Descriptor{Digest: dgst}); err != nil { t.Fatalf("unexpected error finishing upload: %v", err) } - if err := builder.AppendReference(distribution.Descriptor{Digest: dgst, MediaType: schema2.MediaTypeLayer}); err != nil { + if err := builder.AppendReference(v1.Descriptor{Digest: dgst, MediaType: schema2.MediaTypeLayer}); err != nil { t.Fatalf("unexpected error appending references: %v", err) } } @@ -336,7 +336,7 @@ func testOCIManifestStorage(t *testing.T, testname string, includeMediaTypes boo OS: "CP/M", } - mfstDescriptors := []distribution.Descriptor{ + mfstDescriptors := []v1.Descriptor{ createOciManifestDescriptor(t, testname, mfst, platformSpec), } @@ -460,7 +460,7 @@ func TestIndexManifestStorageWithoutImageCheck(t *testing.T) { OS: "CP/M", } - ociManifestDescriptors := []distribution.Descriptor{ + ociManifestDescriptors := []v1.Descriptor{ createOciManifestDescriptor(t, t.Name(), manifest, ociPlatformSpec), } @@ -547,7 +547,7 @@ func TestIndexManifestStorageWithSelectivePlatforms(t *testing.T) { OS: "CP/M", } - manifestDescriptors := []distribution.Descriptor{ + manifestDescriptors := []v1.Descriptor{ createOciManifestDescriptor(t, t.Name(), amdManifest, amdPlatformSpec), createOciManifestDescriptor(t, t.Name(), armManifest, armPlatformSpec), createOciManifestDescriptor(t, t.Name(), atariManifest, atariPlatformSpec), @@ -616,11 +616,11 @@ func createRandomImage(t *testing.T, testname string, imageMediaType string, blo t.Fatalf("%s: unexpected error copying to upload: %v", testname, err) } - if _, err := wr.Commit(ctx, distribution.Descriptor{Digest: dgst}); err != nil { + if _, err := wr.Commit(ctx, v1.Descriptor{Digest: dgst}); err != nil { t.Fatalf("%s: unexpected error finishing upload: %v", testname, err) } - if err := builder.AppendReference(distribution.Descriptor{Digest: dgst, MediaType: v1.MediaTypeImageLayer}); err != nil { + if err := builder.AppendReference(v1.Descriptor{Digest: dgst, MediaType: v1.MediaTypeImageLayer}); err != nil { t.Fatalf("%s unexpected error appending references: %v", testname, err) } } @@ -629,14 +629,14 @@ func createRandomImage(t *testing.T, testname string, imageMediaType string, blo } // createOciManifestDescriptor builds a manifest descriptor from a manifest and a platform descriptor -func createOciManifestDescriptor(t *testing.T, testname string, manifest distribution.Manifest, platformSpec *v1.Platform) distribution.Descriptor { +func createOciManifestDescriptor(t *testing.T, testname string, manifest distribution.Manifest, platformSpec *v1.Platform) v1.Descriptor { manifestMediaType, manifestPayload, err := manifest.Payload() if err != nil { t.Fatalf("%s: unexpected error getting manifest payload: %v", testname, err) } manifestDigest := digest.FromBytes(manifestPayload) - return distribution.Descriptor{ + return v1.Descriptor{ Digest: manifestDigest, Size: int64(len(manifestPayload)), MediaType: manifestMediaType, @@ -656,7 +656,7 @@ func createManifestListDescriptor(t *testing.T, testname string, manifest distri manifestDigest := digest.FromBytes(manifestPayload) return manifestlist.ManifestDescriptor{ - Descriptor: distribution.Descriptor{ + Descriptor: v1.Descriptor{ Digest: manifestDigest, Size: int64(len(manifestPayload)), MediaType: manifestMediaType, @@ -701,7 +701,7 @@ func TestLinkPathFuncs(t *testing.T) { } } -func ociIndexFromDesriptorsWithMediaType(descriptors []distribution.Descriptor, mediaType string) (*ocischema.DeserializedImageIndex, error) { +func ociIndexFromDesriptorsWithMediaType(descriptors []v1.Descriptor, mediaType string) (*ocischema.DeserializedImageIndex, error) { manifest, err := ocischema.FromDescriptors(descriptors, nil) if err != nil { return nil, err diff --git a/registry/storage/ocimanifesthandler_test.go b/registry/storage/ocimanifesthandler_test.go index c70f4b33fc5..c8e3b5efbda 100644 --- a/registry/storage/ocimanifesthandler_test.go +++ b/registry/storage/ocimanifesthandler_test.go @@ -33,17 +33,17 @@ func TestVerifyOCIManifestNonDistributableLayer(t *testing.T) { t.Fatal(err) } - nonDistributableLayer := distribution.Descriptor{ + nonDistributableLayer := v1.Descriptor{ Digest: "sha256:463435349086340864309863409683460843608348608934092322395278926a", Size: 6323, MediaType: v1.MediaTypeImageLayerNonDistributableGzip, //nolint:staticcheck // ignore A1019: v1.MediaTypeImageLayerNonDistributableGzip is deprecated: Non-distributable layers are deprecated, and not recommended for future use } - emptyLayer := distribution.Descriptor{ + emptyLayer := v1.Descriptor{ Digest: "", } - emptyGzipLayer := distribution.Descriptor{ + emptyGzipLayer := v1.Descriptor{ Digest: "", MediaType: v1.MediaTypeImageLayerGzip, } @@ -55,7 +55,7 @@ func TestVerifyOCIManifestNonDistributableLayer(t *testing.T) { } type testcase struct { - BaseLayer distribution.Descriptor + BaseLayer v1.Descriptor URLs []string Err error } @@ -142,7 +142,7 @@ func TestVerifyOCIManifestNonDistributableLayer(t *testing.T) { m := template l := c.BaseLayer l.URLs = c.URLs - m.Layers = []distribution.Descriptor{l} + m.Layers = []v1.Descriptor{l} dm, err := ocischema.FromStruct(m) if err != nil { t.Error(err) @@ -215,7 +215,7 @@ func TestVerifyOCIManifestBlobLayerAndConfig(t *testing.T) { } type testcase struct { - Desc distribution.Descriptor + Desc v1.Descriptor URLs []string Err error } @@ -223,25 +223,25 @@ func TestVerifyOCIManifestBlobLayerAndConfig(t *testing.T) { layercases := []testcase{ // empty media type { - distribution.Descriptor{}, + v1.Descriptor{}, []string{"http://foo/bar"}, digest.ErrDigestInvalidFormat, }, { - distribution.Descriptor{}, + v1.Descriptor{}, nil, digest.ErrDigestInvalidFormat, }, // unknown media type, but blob is present { - distribution.Descriptor{ + v1.Descriptor{ Digest: layer.Digest, }, nil, nil, }, { - distribution.Descriptor{ + v1.Descriptor{ Digest: layer.Digest, }, []string{"http://foo/bar"}, @@ -249,21 +249,21 @@ func TestVerifyOCIManifestBlobLayerAndConfig(t *testing.T) { }, // gzip layer, but invalid digest { - distribution.Descriptor{ + v1.Descriptor{ MediaType: v1.MediaTypeImageLayerGzip, }, nil, digest.ErrDigestInvalidFormat, }, { - distribution.Descriptor{ + v1.Descriptor{ MediaType: v1.MediaTypeImageLayerGzip, }, []string{"https://foo/bar"}, digest.ErrDigestInvalidFormat, }, { - distribution.Descriptor{ + v1.Descriptor{ MediaType: v1.MediaTypeImageLayerGzip, Digest: digest.Digest("invalid"), }, @@ -290,7 +290,7 @@ func TestVerifyOCIManifestBlobLayerAndConfig(t *testing.T) { l := c.Desc l.URLs = c.URLs - m.Layers = []distribution.Descriptor{l} + m.Layers = []v1.Descriptor{l} checkFn(m, c.Err) } @@ -304,14 +304,14 @@ func TestVerifyOCIManifestBlobLayerAndConfig(t *testing.T) { }, // invalid digest { - distribution.Descriptor{ + v1.Descriptor{ MediaType: v1.MediaTypeImageConfig, }, []string{"https://foo/bar"}, digest.ErrDigestInvalidFormat, }, { - distribution.Descriptor{ + v1.Descriptor{ MediaType: v1.MediaTypeImageConfig, Digest: digest.Digest("invalid"), }, diff --git a/registry/storage/schema2manifesthandler_test.go b/registry/storage/schema2manifesthandler_test.go index 4f92ef7a755..610f6f4835b 100644 --- a/registry/storage/schema2manifesthandler_test.go +++ b/registry/storage/schema2manifesthandler_test.go @@ -11,6 +11,7 @@ import ( "github.com/distribution/distribution/v3/registry/storage/driver/inmemory" "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/specs-go" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) func TestVerifyManifestForeignLayer(t *testing.T) { @@ -34,13 +35,13 @@ func TestVerifyManifestForeignLayer(t *testing.T) { t.Fatal(err) } - foreignLayer := distribution.Descriptor{ + foreignLayer := v1.Descriptor{ Digest: "sha256:463435349086340864309863409683460843608348608934092322395278926a", Size: 6323, MediaType: schema2.MediaTypeForeignLayer, } - emptyLayer := distribution.Descriptor{ + emptyLayer := v1.Descriptor{ Digest: "", } @@ -51,7 +52,7 @@ func TestVerifyManifestForeignLayer(t *testing.T) { } type testcase struct { - BaseLayer distribution.Descriptor + BaseLayer v1.Descriptor URLs []string Err error } @@ -129,7 +130,7 @@ func TestVerifyManifestForeignLayer(t *testing.T) { m := template l := c.BaseLayer l.URLs = c.URLs - m.Layers = []distribution.Descriptor{l} + m.Layers = []v1.Descriptor{l} dm, err := schema2.FromStruct(m) if err != nil { t.Error(err) @@ -202,7 +203,7 @@ func TestVerifyManifestBlobLayerAndConfig(t *testing.T) { } type testcase struct { - Desc distribution.Descriptor + Desc v1.Descriptor URLs []string Err error } @@ -210,25 +211,25 @@ func TestVerifyManifestBlobLayerAndConfig(t *testing.T) { layercases := []testcase{ // empty media type { - distribution.Descriptor{}, + v1.Descriptor{}, []string{"http://foo/bar"}, digest.ErrDigestInvalidFormat, }, { - distribution.Descriptor{}, + v1.Descriptor{}, nil, digest.ErrDigestInvalidFormat, }, // unknown media type, but blob is present { - distribution.Descriptor{ + v1.Descriptor{ Digest: layer.Digest, }, nil, nil, }, { - distribution.Descriptor{ + v1.Descriptor{ Digest: layer.Digest, }, []string{"http://foo/bar"}, @@ -236,21 +237,21 @@ func TestVerifyManifestBlobLayerAndConfig(t *testing.T) { }, // gzip layer, but invalid digest { - distribution.Descriptor{ + v1.Descriptor{ MediaType: schema2.MediaTypeLayer, }, nil, digest.ErrDigestInvalidFormat, }, { - distribution.Descriptor{ + v1.Descriptor{ MediaType: schema2.MediaTypeLayer, }, []string{"https://foo/bar"}, digest.ErrDigestInvalidFormat, }, { - distribution.Descriptor{ + v1.Descriptor{ MediaType: schema2.MediaTypeLayer, Digest: digest.Digest("invalid"), }, @@ -277,7 +278,7 @@ func TestVerifyManifestBlobLayerAndConfig(t *testing.T) { l := c.Desc l.URLs = c.URLs - m.Layers = []distribution.Descriptor{l} + m.Layers = []v1.Descriptor{l} checkFn(m, c.Err) } @@ -291,14 +292,14 @@ func TestVerifyManifestBlobLayerAndConfig(t *testing.T) { }, // invalid digest { - distribution.Descriptor{ + v1.Descriptor{ MediaType: schema2.MediaTypeImageConfig, }, []string{"https://foo/bar"}, digest.ErrDigestInvalidFormat, }, { - distribution.Descriptor{ + v1.Descriptor{ MediaType: schema2.MediaTypeImageConfig, Digest: digest.Digest("invalid"), }, diff --git a/registry/storage/tagstore.go b/registry/storage/tagstore.go index a481df94df2..3639e2d9c1b 100644 --- a/registry/storage/tagstore.go +++ b/registry/storage/tagstore.go @@ -7,6 +7,7 @@ import ( "sync" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" "golang.org/x/sync/errgroup" "github.com/distribution/distribution/v3" @@ -18,7 +19,7 @@ var _ distribution.TagService = &tagStore{} // tagStore provides methods to manage manifest tags in a backend storage driver. // This implementation uses the same on-disk layout as the (now deleted) tag // store. This provides backward compatibility with current registry deployments -// which only makes use of the Digest field of the returned distribution.Descriptor +// which only makes use of the Digest field of the returned v1.Descriptor // but does not enable full roundtripping of Descriptor objects type tagStore struct { repository *repository @@ -60,7 +61,7 @@ func (ts *tagStore) All(ctx context.Context) ([]string, error) { // Tag tags the digest with the given tag, updating the store to point at // the current tag. The digest must point to a manifest. -func (ts *tagStore) Tag(ctx context.Context, tag string, desc distribution.Descriptor) error { +func (ts *tagStore) Tag(ctx context.Context, tag string, desc v1.Descriptor) error { currentPath, err := pathFor(manifestTagCurrentPathSpec{ name: ts.repository.Named().Name(), tag: tag, @@ -81,26 +82,26 @@ func (ts *tagStore) Tag(ctx context.Context, tag string, desc distribution.Descr } // resolve the current revision for name and tag. -func (ts *tagStore) Get(ctx context.Context, tag string) (distribution.Descriptor, error) { +func (ts *tagStore) Get(ctx context.Context, tag string) (v1.Descriptor, error) { currentPath, err := pathFor(manifestTagCurrentPathSpec{ name: ts.repository.Named().Name(), tag: tag, }) if err != nil { - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } revision, err := ts.blobStore.readlink(ctx, currentPath) if err != nil { switch err.(type) { case storagedriver.PathNotFoundError: - return distribution.Descriptor{}, distribution.ErrTagUnknown{Tag: tag} + return v1.Descriptor{}, distribution.ErrTagUnknown{Tag: tag} } - return distribution.Descriptor{}, err + return v1.Descriptor{}, err } - return distribution.Descriptor{Digest: revision}, nil + return v1.Descriptor{Digest: revision}, nil } // Untag removes the tag association @@ -137,7 +138,7 @@ func (ts *tagStore) linkedBlobStore(ctx context.Context, tag string) *linkedBlob // Lookup recovers a list of tags which refer to this digest. When a manifest is deleted by // digest, tag entries which point to it need to be recovered to avoid dangling tags. -func (ts *tagStore) Lookup(ctx context.Context, desc distribution.Descriptor) ([]string, error) { +func (ts *tagStore) Lookup(ctx context.Context, desc v1.Descriptor) ([]string, error) { allTags, err := ts.All(ctx) switch err.(type) { case distribution.ErrRepositoryUnknown: diff --git a/registry/storage/tagstore_test.go b/registry/storage/tagstore_test.go index 6e8f96c1e05..c4c89163b5f 100644 --- a/registry/storage/tagstore_test.go +++ b/registry/storage/tagstore_test.go @@ -11,6 +11,7 @@ import ( "github.com/distribution/reference" digest "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/specs-go" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) type tagsTestEnv struct { @@ -53,7 +54,7 @@ func TestTagStoreTag(t *testing.T) { tags := env.ts ctx := env.ctx - d := distribution.Descriptor{} + d := v1.Descriptor{} err := tags.Tag(ctx, "latest", d) if err == nil { t.Errorf("unexpected error putting malformed descriptor : %s", err) @@ -95,7 +96,7 @@ func TestTagStoreUnTag(t *testing.T) { env := testTagStore(t) tags := env.ts ctx := env.ctx - desc := distribution.Descriptor{Digest: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"} + desc := v1.Descriptor{Digest: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"} err := tags.Untag(ctx, "latest") if err == nil { @@ -127,7 +128,7 @@ func TestTagStoreAll(t *testing.T) { alpha := "abcdefghijklmnopqrstuvwxyz" for i := 0; i < len(alpha); i++ { tag := alpha[i] - desc := distribution.Descriptor{Digest: "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"} + desc := v1.Descriptor{Digest: "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"} err := tagStore.Tag(ctx, string(tag), desc) if err != nil { t.Error(err) @@ -170,8 +171,8 @@ func TestTagLookup(t *testing.T) { tagStore := env.ts ctx := env.ctx - descA := distribution.Descriptor{Digest: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"} - desc0 := distribution.Descriptor{Digest: "sha256:0000000000000000000000000000000000000000000000000000000000000000"} + descA := v1.Descriptor{Digest: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"} + desc0 := v1.Descriptor{Digest: "sha256:0000000000000000000000000000000000000000000000000000000000000000"} tags, err := tagStore.Lookup(ctx, descA) if err != nil { @@ -245,12 +246,12 @@ func TestTagIndexes(t *testing.T) { m := schema2.Manifest{ Versioned: specs.Versioned{SchemaVersion: 2}, MediaType: schema2.MediaTypeManifest, - Config: distribution.Descriptor{ + Config: v1.Descriptor{ Digest: conf.Digest, Size: 1, MediaType: schema2.MediaTypeImageConfig, }, - Layers: []distribution.Descriptor{ + Layers: []v1.Descriptor{ { Digest: layer.Digest, Size: 1, diff --git a/tags.go b/tags.go index 6033575ce30..ed94a51a0ca 100644 --- a/tags.go +++ b/tags.go @@ -4,6 +4,7 @@ import ( "context" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // TagService provides access to information about tagged objects. @@ -12,11 +13,11 @@ type TagService interface { // implementations may differentiate between "trusted" tags and // "untrusted" tags. If a tag is "untrusted", the mapping will be returned // as an ErrTagUntrusted error, with the target descriptor. - Get(ctx context.Context, tag string) (Descriptor, error) + Get(ctx context.Context, tag string) (v1.Descriptor, error) // Tag associates the tag with the provided descriptor, updating the // current association, if needed. - Tag(ctx context.Context, tag string, desc Descriptor) error + Tag(ctx context.Context, tag string, desc v1.Descriptor) error // Untag removes the given tag association Untag(ctx context.Context, tag string) error @@ -25,7 +26,7 @@ type TagService interface { All(ctx context.Context) ([]string, error) // Lookup returns the set of tags referencing the given digest. - Lookup(ctx context.Context, digest Descriptor) ([]string, error) + Lookup(ctx context.Context, digest v1.Descriptor) ([]string, error) } // TagManifestsProvider provides method to retrieve the digests of manifests that a tag historically diff --git a/testutil/manifests.go b/testutil/manifests.go index 271e0ac3738..2bd9c7d7f85 100644 --- a/testutil/manifests.go +++ b/testutil/manifests.go @@ -9,6 +9,7 @@ import ( "github.com/distribution/distribution/v3/manifest/ocischema" "github.com/distribution/distribution/v3/manifest/schema2" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // MakeManifestList constructs a manifest list out of a list of manifest digests @@ -51,7 +52,7 @@ func MakeSchema2Manifest(repository distribution.Repository, digests []digest.Di } builder := schema2.NewManifestBuilder(d, configJSON) for _, dgst := range digests { - if err := builder.AppendReference(distribution.Descriptor{Digest: dgst}); err != nil { + if err := builder.AppendReference(v1.Descriptor{Digest: dgst}); err != nil { return nil, fmt.Errorf("unexpected error building schema2 manifest: %v", err) } } @@ -72,7 +73,7 @@ func MakeOCIManifest(repository distribution.Repository, digests []digest.Digest builder := ocischema.NewManifestBuilder(blobStore, configJSON, make(map[string]string)) for _, dgst := range digests { - if err := builder.AppendReference(distribution.Descriptor{Digest: dgst}); err != nil { + if err := builder.AppendReference(v1.Descriptor{Digest: dgst}); err != nil { return nil, fmt.Errorf("unexpected error building OCI manifest: %v", err) } } diff --git a/testutil/push.go b/testutil/push.go index 17f2230e185..aae34fb1dde 100644 --- a/testutil/push.go +++ b/testutil/push.go @@ -7,6 +7,7 @@ import ( "github.com/distribution/distribution/v3" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // PushBlob pushes a blob with the given digest to the given repository. @@ -28,7 +29,7 @@ func PushBlob(ctx context.Context, repository distribution.Repository, blobReade return fmt.Errorf("unexpected error uploading: %v", err) } - if _, err := wr.Commit(ctx, distribution.Descriptor{Digest: dgst}); err != nil { + if _, err := wr.Commit(ctx, v1.Descriptor{Digest: dgst}); err != nil { return fmt.Errorf("unexpected error finishing upload: %v", err) } diff --git a/testutil/tarfile.go b/testutil/tarfile.go index d4bc7e2a18a..84634cdbbda 100644 --- a/testutil/tarfile.go +++ b/testutil/tarfile.go @@ -12,6 +12,7 @@ import ( "github.com/distribution/distribution/v3" "github.com/distribution/distribution/v3/internal/dcontext" "github.com/opencontainers/go-digest" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // CreateRandomTarFile creates a random tarfile, returning it as an @@ -107,7 +108,7 @@ func UploadBlobs(repository distribution.Repository, layers map[digest.Digest]io return fmt.Errorf("unexpected error copying to upload: %v", err) } - if _, err := wr.Commit(ctx, distribution.Descriptor{Digest: dgst}); err != nil { + if _, err := wr.Commit(ctx, v1.Descriptor{Digest: dgst}); err != nil { return fmt.Errorf("unexpected error committinng upload: %v", err) } }