diff --git a/README.md b/README.md index 7af95119682..89a1b2f4d48 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ cat < $artifactFile "size": $signatureFileSize } ], - "subjectManifest": { + "subject": { "mediaType": "$manifestMediaType", "digest": "$manifestDigest", "size": $manifestFileSize diff --git a/go.mod b/go.mod index f495e1cd478..6355644b194 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( github.com/ncw/swift v1.0.47 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.0.1 - github.com/oras-project/artifacts-spec v0.0.0-20210826181006-68f2cefa34a6 + github.com/oras-project/artifacts-spec v0.0.0-20210910233110-813953a626ae github.com/satori/go.uuid v1.2.0 // indirect github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v0.0.3 diff --git a/go.sum b/go.sum index 4992ed45daf..66869067229 100644 --- a/go.sum +++ b/go.sum @@ -96,10 +96,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/oras-project/artifacts-spec v0.0.0-20210820222200-769b88c06428 h1:amnau8Czf7c+KCq14179DmXq9tLt0b/tGg+xusz2L2Q= -github.com/oras-project/artifacts-spec v0.0.0-20210820222200-769b88c06428/go.mod h1:Xch2aLzSwtkhbFFN6LUzTfLtukYvMMdXJ4oZ8O7BOdc= -github.com/oras-project/artifacts-spec v0.0.0-20210826181006-68f2cefa34a6 h1:BZYj7fsb3kZb2INlysMzTeLZ1ksxwwn4BreryzyI2KM= -github.com/oras-project/artifacts-spec v0.0.0-20210826181006-68f2cefa34a6/go.mod h1:Xch2aLzSwtkhbFFN6LUzTfLtukYvMMdXJ4oZ8O7BOdc= +github.com/oras-project/artifacts-spec v0.0.0-20210910233110-813953a626ae h1:vw1ccIckPxFFx3/wW8SaVLtvQ5viAduN+fuku8KbEfo= +github.com/oras-project/artifacts-spec v0.0.0-20210910233110-813953a626ae/go.mod h1:Xch2aLzSwtkhbFFN6LUzTfLtukYvMMdXJ4oZ8O7BOdc= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/manifest/orasartifact/manifest.go b/manifest/orasartifact/manifest.go index bdb080c1050..d3072d85c61 100644 --- a/manifest/orasartifact/manifest.go +++ b/manifest/orasartifact/manifest.go @@ -18,13 +18,6 @@ func init() { return nil, distribution.Descriptor{}, err } - if d.inner.MediaType != v1.MediaTypeArtifactManifest { - err = fmt.Errorf("if present, mediaType in ORAS artifact manifest should be '%s' not '%s'", - v1.MediaTypeArtifactManifest, d.inner.MediaType) - - return nil, distribution.Descriptor{}, err - } - dgst := digest.FromBytes(b) return d, distribution.Descriptor{Digest: dgst, Size: int64(len(b)), MediaType: v1.MediaTypeArtifactManifest}, err } @@ -57,12 +50,12 @@ func (a Manifest) References() []distribution.Descriptor { return blobs } -// SubjectManifest returns the the subject manifest this artifact references. -func (a Manifest) SubjectManifest() distribution.Descriptor { +// Subject returns the the subject manifest this artifact references. +func (a Manifest) Subject() distribution.Descriptor { return distribution.Descriptor{ - MediaType: a.inner.SubjectManifest.MediaType, - Digest: a.inner.SubjectManifest.Digest, - Size: a.inner.SubjectManifest.Size, + MediaType: a.inner.Subject.MediaType, + Digest: a.inner.Subject.Digest, + Size: a.inner.Subject.Size, } } @@ -83,6 +76,9 @@ func (d *DeserializedManifest) UnmarshalJSON(b []byte) error { if err := json.Unmarshal(d.raw, &man); err != nil { return err } + if man.ArtifactType == "" { + return errors.New("artifactType cannot be empty") + } d.inner = man return nil @@ -100,12 +96,6 @@ func (d *DeserializedManifest) MarshalJSON() ([]byte, error) { // Payload returns the raw content of the Artifact. The contents can be // used to calculate the content identifier. func (d DeserializedManifest) Payload() (string, []byte, error) { - var mediaType string - if d.inner.MediaType == "" { - mediaType = v1.MediaTypeArtifactManifest - } else { - mediaType = d.inner.MediaType - } - - return mediaType, d.raw, nil + // NOTE: This is a hack. The media type should be read from storage. + return v1.MediaTypeArtifactManifest, d.raw, nil } diff --git a/manifests.go b/manifests.go index 064f8ea3239..9bd97b7f711 100644 --- a/manifests.go +++ b/manifests.go @@ -6,6 +6,7 @@ import ( "mime" "github.com/opencontainers/go-digest" + orasartifact "github.com/oras-project/artifacts-spec/specs-go/v1" ) // Manifest represents a registry object specifying a set of @@ -47,23 +48,6 @@ type ManifestBuilder interface { AppendReference(dependency Describable) error } -// ArtifactDescriptor describes targeted reference type content. -type ArtifactDescriptor struct { - // MediaType describe the type of the content. All text based formats are - // encoded as utf-8. - MediaType string `json:"mediaType,omitempty"` - - // Size in bytes of content. - Size int64 `json:"size,omitempty"` - - // Digest uniquely identifies the content. A byte stream can be verified - // against this digest. - Digest string `json:"digest,omitempty"` - - // ArtifactType specifies the artifact type of the content. - ArtifactType string `json:"artifactType,omitempty"` -} - // ManifestService describes operations on image manifests. type ManifestService interface { // Exists returns true if the manifest exists. @@ -81,7 +65,7 @@ type ManifestService interface { // Referrers returns a collection of manifests which reference the given manifest, // filtered by artifactType. - Referrers(ctx context.Context, dgst digest.Digest, artifactType string) ([]ArtifactDescriptor, error) + Referrers(ctx context.Context, dgst digest.Digest, artifactType string) ([]orasartifact.Descriptor, error) } // ManifestEnumerator enables iterating over manifests diff --git a/registry/client/repository.go b/registry/client/repository.go index 4bcb518a2e6..b9b876a6dc8 100644 --- a/registry/client/repository.go +++ b/registry/client/repository.go @@ -21,6 +21,7 @@ import ( "github.com/distribution/distribution/v3/registry/storage/cache" "github.com/distribution/distribution/v3/registry/storage/cache/memory" "github.com/opencontainers/go-digest" + orasartifacts "github.com/oras-project/artifacts-spec/specs-go/v1" ) // Registry provides an interface for calling Repositories, which returns a catalog of repositories. @@ -397,7 +398,7 @@ type manifests struct { etags map[string]string } -func (ms *manifests) Referrers(_ context.Context, _ digest.Digest, _ string) ([]distribution.ArtifactDescriptor, error) { +func (ms *manifests) Referrers(_ context.Context, _ digest.Digest, _ string) ([]orasartifacts.Descriptor, error) { return nil, fmt.Errorf("not implemented") } diff --git a/registry/handlers/referrers.go b/registry/handlers/referrers.go index 1712668e2f7..7011bce05c4 100644 --- a/registry/handlers/referrers.go +++ b/registry/handlers/referrers.go @@ -5,11 +5,12 @@ import ( "net/http" "github.com/distribution/distribution/v3" + dcontext "github.com/distribution/distribution/v3/context" "github.com/distribution/distribution/v3/registry/api/errcode" v2 "github.com/distribution/distribution/v3/registry/api/v2" - dcontext "github.com/distribution/distribution/v3/context" "github.com/gorilla/handlers" "github.com/opencontainers/go-digest" + orasartifacts "github.com/oras-project/artifacts-spec/specs-go/v1" ) // referrersDispatcher takes the request context and builds the @@ -29,7 +30,7 @@ func referrersDispatcher(ctx *Context, r *http.Request) http.Handler { // referrersResponse describes the response body of the referrers API. type referrersResponse struct { - Referrers []distribution.ArtifactDescriptor `json:"references"` + Referrers []orasartifacts.Descriptor `json:"references"` } // referrersHandler handles http operations on manifest referrers. @@ -70,7 +71,7 @@ func (h *referrersHandler) Get(w http.ResponseWriter, r *http.Request) { } if referrers == nil { - referrers = []distribution.ArtifactDescriptor{} + referrers = []orasartifacts.Descriptor{} } response := referrersResponse{} diff --git a/registry/proxy/proxymanifeststore.go b/registry/proxy/proxymanifeststore.go index e9d52e9d1df..6af93dfe290 100644 --- a/registry/proxy/proxymanifeststore.go +++ b/registry/proxy/proxymanifeststore.go @@ -9,6 +9,7 @@ import ( "github.com/distribution/distribution/v3/reference" "github.com/distribution/distribution/v3/registry/proxy/scheduler" "github.com/opencontainers/go-digest" + orasartifacts "github.com/oras-project/artifacts-spec/specs-go/v1" ) // todo(richardscothern): from cache control header or config @@ -25,7 +26,7 @@ type proxyManifestStore struct { var _ distribution.ManifestService = &proxyManifestStore{} -func (pms proxyManifestStore) Referrers(_ context.Context, _ digest.Digest, _ string) ([]distribution.ArtifactDescriptor, error) { +func (pms proxyManifestStore) Referrers(_ context.Context, _ digest.Digest, _ string) ([]orasartifacts.Descriptor, error) { return nil, distribution.ErrUnsupported } diff --git a/registry/proxy/proxymanifeststore_test.go b/registry/proxy/proxymanifeststore_test.go index b0214071ec3..59f9521a2ae 100644 --- a/registry/proxy/proxymanifeststore_test.go +++ b/registry/proxy/proxymanifeststore_test.go @@ -19,6 +19,7 @@ import ( "github.com/distribution/distribution/v3/testutil" "github.com/docker/libtrust" "github.com/opencontainers/go-digest" + orasartifacts "github.com/oras-project/artifacts-spec/specs-go/v1" ) type statsManifest struct { @@ -61,7 +62,7 @@ func (sm statsManifest) Put(ctx context.Context, manifest distribution.Manifest, return sm.manifests.Put(ctx, manifest) } -func (sm statsManifest) Referrers(ctx context.Context, dgst digest.Digest, referrerType string) ([]distribution.ArtifactDescriptor, error) { +func (sm statsManifest) Referrers(ctx context.Context, dgst digest.Digest, referrerType string) ([]orasartifacts.Descriptor, error) { sm.stats["referrers"]++ return sm.Referrers(ctx, dgst, referrerType) } diff --git a/registry/storage/manifeststore.go b/registry/storage/manifeststore.go index 4b7a1aad1ed..ad2f674b93c 100644 --- a/registry/storage/manifeststore.go +++ b/registry/storage/manifeststore.go @@ -133,13 +133,9 @@ func (ms *manifestStore) Get(ctx context.Context, dgst digest.Digest, options .. return nil, distribution.ErrManifestVerification{fmt.Errorf("unrecognized manifest content type %s", versioned.MediaType)} } default: - switch versioned.MediaType { - case orasartifactv1.MediaTypeArtifactManifest: - return ms.orasArtifactHandler.Unmarshal(ctx, dgst, content) - } + // Assume it's an ORAS artifact manifest. + return ms.orasArtifactHandler.Unmarshal(ctx, dgst, content) } - - return nil, fmt.Errorf("unrecognized manifest schema version %d", versioned.SchemaVersion) } func (ms *manifestStore) Put(ctx context.Context, manifest distribution.Manifest, options ...distribution.ManifestServiceOption) (digest.Digest, error) { @@ -162,10 +158,10 @@ func (ms *manifestStore) Put(ctx context.Context, manifest distribution.Manifest } // Referrers returns referrer manifests filtered by the given referrerType. -func (ms *manifestStore) Referrers(ctx context.Context, revision digest.Digest, referrerType string) ([]distribution.ArtifactDescriptor, error) { +func (ms *manifestStore) Referrers(ctx context.Context, revision digest.Digest, referrerType string) ([]orasartifactv1.Descriptor, error) { dcontext.GetLogger(ms.ctx).Debug("(*manifestStore).Referrers") - var referrers []distribution.ArtifactDescriptor + var referrers []orasartifactv1.Descriptor err := ms.referrersStore(ctx, revision, referrerType).Enumerate(ctx, func(referrerRevision digest.Digest) error { man, err := ms.Get(ctx, referrerRevision) @@ -184,10 +180,10 @@ func (ms *manifestStore) Referrers(ctx context.Context, revision digest.Digest, return err } desc.MediaType, _, _ = man.Payload() - referrers = append(referrers, distribution.ArtifactDescriptor{ + referrers = append(referrers, orasartifactv1.Descriptor{ MediaType: desc.MediaType, Size: desc.Size, - Digest: desc.Digest.String(), + Digest: desc.Digest, ArtifactType: orasArtifactMan.ArtifactType(), }) return nil diff --git a/registry/storage/orasartifactmanifesthandler.go b/registry/storage/orasartifactmanifesthandler.go index b655e25a833..ffb8c65e1ee 100644 --- a/registry/storage/orasartifactmanifesthandler.go +++ b/registry/storage/orasartifactmanifesthandler.go @@ -94,7 +94,7 @@ func (oamh *orasArtifactManifestHandler) verifyManifest(ctx context.Context, dm } // Validate subject manifest. - subject := dm.SubjectManifest() + subject := dm.Subject() exists, err := ms.Exists(ctx, subject.Digest) if !exists || err == distribution.ErrBlobUnknown { errs = append(errs, distribution.ErrManifestBlobUnknown{Digest: subject.Digest}) @@ -113,7 +113,7 @@ func (oamh *orasArtifactManifestHandler) verifyManifest(ctx context.Context, dm // indexReferrers indexes the subject of the given revision in its referrers index store. func (oamh *orasArtifactManifestHandler) indexReferrers(ctx context.Context, dm orasartifact.DeserializedManifest, revision digest.Digest) error { artifactType := dm.ArtifactType() - subject := dm.SubjectManifest() + subject := dm.Subject() if err := oamh.referrersStore(ctx, subject.Digest, artifactType).linkBlob(ctx, distribution.Descriptor{Digest: revision}); err != nil { return err diff --git a/vendor/github.com/oras-project/artifacts-spec/specs-go/v1/descriptor.go b/vendor/github.com/oras-project/artifacts-spec/specs-go/v1/descriptor.go index a4e024088ea..7e4edfd0df9 100644 --- a/vendor/github.com/oras-project/artifacts-spec/specs-go/v1/descriptor.go +++ b/vendor/github.com/oras-project/artifacts-spec/specs-go/v1/descriptor.go @@ -1,40 +1,40 @@ -// Copyright 2021 ORAS Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package v1 - -import digest "github.com/opencontainers/go-digest" - -// Descriptor describes the disposition of targeted content. -type Descriptor struct { - // MediaType is the media type of the object this schema refers to. - MediaType string `json:"mediaType,omitempty"` - - // ArtifactType is the artifact type of the object this schema refers to. - // - // When the descriptor is used for blobs, this property must be empty. - ArtifactType string `json:"artifactType"` - - // Digest is the digest of the targeted content. - Digest digest.Digest `json:"digest"` - - // Size specifies the size in bytes of the blob. - Size int64 `json:"size"` - - // URLs specifies a list of URLs from which this object MAY be downloaded - URLs []string `json:"urls,omitempty"` - - // Annotations contains arbitrary metadata relating to the targeted content. - Annotations map[string]string `json:"annotations,omitempty"` -} +// Copyright 2021 ORAS Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +import digest "github.com/opencontainers/go-digest" + +// Descriptor describes the disposition of targeted content. +type Descriptor struct { + // MediaType is the media type of the object this schema refers to. + MediaType string `json:"mediaType,omitempty"` + + // ArtifactType is the artifact type of the object this schema refers to. + // + // When the descriptor is used for blobs, this property must be empty. + ArtifactType string `json:"artifactType,omitempty"` + + // Digest is the digest of the targeted content. + Digest digest.Digest `json:"digest"` + + // Size specifies the size in bytes of the blob. + Size int64 `json:"size"` + + // URLs specifies a list of URLs from which this object MAY be downloaded + URLs []string `json:"urls,omitempty"` + + // Annotations contains arbitrary metadata relating to the targeted content. + Annotations map[string]string `json:"annotations,omitempty"` +} diff --git a/vendor/github.com/oras-project/artifacts-spec/specs-go/v1/manifest.go b/vendor/github.com/oras-project/artifacts-spec/specs-go/v1/manifest.go index 341e7f4f678..67ded906fa1 100644 --- a/vendor/github.com/oras-project/artifacts-spec/specs-go/v1/manifest.go +++ b/vendor/github.com/oras-project/artifacts-spec/specs-go/v1/manifest.go @@ -1,35 +1,32 @@ -// Copyright 2021 ORAS Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package v1 - -// Manifest describes an ORAS artifact. -// This structure provides `application/vnd.oras.artifact.manifest.v1+json` mediatype when marshalled to JSON. -type Manifest struct { - // MediaType is the media type of the object this schema refers to. - MediaType string `json:"mediaType"` - - // ArtifactType is the artifact type of the object this schema refers to. - ArtifactType string `json:"artifactType"` - - // Blobs is a collection of blobs referenced by this manifest. - Blobs []Descriptor `json:"blobs"` - - // SubjectManifest is an optional reference to any existing manifest within the repository. - // When specified, the artifact is said to be dependent upon the referenced subject. - SubjectManifest Descriptor `json:"subject"` - - // Annotations contains arbitrary metadata for the artifact manifest. - Annotations map[string]string `json:"annotations,omitempty"` -} +// Copyright 2021 ORAS Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +// Manifest describes an ORAS artifact. +// This structure provides `application/vnd.oras.artifact.manifest.v1+json` mediatype when marshalled to JSON. +type Manifest struct { + // ArtifactType is the artifact type of the object this schema refers to. + ArtifactType string `json:"artifactType"` + + // Blobs is a collection of blobs referenced by this manifest. + Blobs []Descriptor `json:"blobs"` + + // Subject is an optional reference to any existing manifest within the repository. + // When specified, the artifact is said to be dependent upon the referenced subject. + Subject Descriptor `json:"subject"` + + // Annotations contains arbitrary metadata for the artifact manifest. + Annotations map[string]string `json:"annotations,omitempty"` +} diff --git a/vendor/github.com/oras-project/artifacts-spec/specs-go/v1/mediatype.go b/vendor/github.com/oras-project/artifacts-spec/specs-go/v1/mediatype.go index 52c1732325e..fd5767f7582 100644 --- a/vendor/github.com/oras-project/artifacts-spec/specs-go/v1/mediatype.go +++ b/vendor/github.com/oras-project/artifacts-spec/specs-go/v1/mediatype.go @@ -1,20 +1,20 @@ -// Copyright 2021 ORAS Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package v1 - -const ( - // MediaTypeArtifactManifest specifies the media type for an ORAS artifact reference type manifest. - MediaTypeArtifactManifest = "application/vnd.cncf.oras.artifact.manifest.v1+json" -) +// Copyright 2021 ORAS Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +const ( + // MediaTypeArtifactManifest specifies the media type for an ORAS artifact reference type manifest. + MediaTypeArtifactManifest = "application/vnd.cncf.oras.artifact.manifest.v1+json" +) diff --git a/vendor/modules.txt b/vendor/modules.txt index 730dad8c95d..971277623ba 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -139,7 +139,7 @@ github.com/opencontainers/go-digest ## explicit github.com/opencontainers/image-spec/specs-go github.com/opencontainers/image-spec/specs-go/v1 -# github.com/oras-project/artifacts-spec v0.0.0-20210826181006-68f2cefa34a6 +# github.com/oras-project/artifacts-spec v0.0.0-20210910233110-813953a626ae ## explicit github.com/oras-project/artifacts-spec/specs-go/v1 # github.com/prometheus/client_golang v1.1.0