diff --git a/README.md b/README.md index 3af0093ec49..7af95119682 100644 --- a/README.md +++ b/README.md @@ -1,73 +1,160 @@ # Distribution -The toolset to pack, ship, store, and deliver content. - -This repository's main product is the Open Source Registry implementation -for storing and distributing container images using the -[OCI Distribution Specification](https://github.com/opencontainers/distribution-spec). -The goal of this project is to provide a simple, secure, and scalable base -for building a large scale registry solution or running a simple private registry. -It is a core library for many registry operators including Docker Hub, GitHub Container Registry, -GitLab Container Registry and DigitalOcean Container Registry, as well as the CNCF Harbor -Project, and VMware Harbor Registry. - - - -[![Build Status](https://github.com/distribution/distribution/workflows/CI/badge.svg?branch=main&event=push)](https://github.com/distribution/distribution/actions?query=workflow%3ACI) -[![GoDoc](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/distribution/distribution) -[![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](LICENSE) -[![codecov](https://codecov.io/gh/distribution/distribution/branch/main/graph/badge.svg)](https://codecov.io/gh/distribution/distribution) -[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B162%2Fgithub.com%2Fdistribution%2Fdistribution.svg?type=shield)](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fdistribution%2Fdistribution?ref=badge_shield) -[![OCI Conformance](https://github.com/distribution/distribution/workflows/conformance/badge.svg)](https://github.com/distribution/distribution/actions?query=workflow%3Aconformance) - -This repository contains the following components: - -|**Component** |Description | -|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **registry** | An implementation of the [OCI Distribution Specification](https://github.com/opencontainers/distribution-spec). | -| **libraries** | A rich set of libraries for interacting with distribution components. Please see [godoc](https://pkg.go.dev/github.com/distribution/distribution) for details. **Note**: The interfaces for these libraries are **unstable**. | -| **documentation** | Docker's full documentation set is available at [docs.docker.com](https://docs.docker.com). This repository [contains the subset](docs/) related just to the registry. | - -### How does this integrate with Docker, containerd, and other OCI client? - -Clients implement against the OCI specification and communicate with the -registry using HTTP. This project contains a client implementation which -is currently in use by Docker, however, it is deprecated for the -[implementation in containerd](https://github.com/containerd/containerd/tree/master/remotes/docker) -and will not support new features. - -### What are the long term goals of the Distribution project? - -The _Distribution_ project has the further long term goal of providing a -secure tool chain for distributing content. The specifications, APIs and tools -should be as useful with Docker as they are without. - -Our goal is to design a professional grade and extensible content distribution -system that allow users to: - -* Enjoy an efficient, secured and reliable way to store, manage, package and - exchange content -* Hack/roll their own on top of healthy open-source components -* Implement their own home made solution through good specs, and solid - extensions mechanism. - -## Contribution - -Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute -issues, fixes, and patches to this project. If you are contributing code, see -the instructions for [building a development environment](BUILDING.md). - -## Communication - -For async communication and long running discussions please use issues and pull requests on the github repo. -This will be the best place to discuss design and implementation. - -For sync communication we have a #distribution channel in the [CNCF Slack](https://slack.cncf.io/) -that everyone is welcome to join and chat about development. - -## Licenses - -The distribution codebase is released under the [Apache 2.0 license](LICENSE). -The README.md file, and files in the "docs" folder are licensed under the -Creative Commons Attribution 4.0 International License. You may obtain a -copy of the license, titled CC-BY-4.0, at http://creativecommons.org/licenses/by/4.0/. +This fork of [distribution/distribution](distribution-distribution) provides +an experimental implementation of [reference types](reference-types). + +Features supported: + +- :heavy_check_mark: PUT ORAS Artifact Manifest +- :heavy_check_mark: GET ORAS Artifact Manifest +- :heavy_check_mark: LIST referrers + - [ ] Pagination support +- [ ] Garbage Collection of reference types + +To power the `/referrers` API, the implementation creates and uses an index. +See [referrers.md](docs/referrers.md) for details. + +## Usage - Push, Discover, Pull + +The following steps illustrate how ORAS artifacts can be stored and retrieved +from a registry. The artifact in this example is a Notary V2 +[signature](signature). + +### Prerequisites + +- Local registry prototype instance +- [docker-generate](https://github.com/shizhMSFT/docker-generate) +- [nv2](https://github.com/notaryproject/nv2) +- `curl` +- `jq` + +### Push an image to your registry + +```shell +# Initialize local registry variables +regIp="127.0.0.1" && \ + regPort="5000" && \ + registry="$regIp:$regPort" && \ + repo="busybox" && \ + tag="latest" && \ + image="$repo:$tag" && \ + reference="$registry/$image" + +# Pull an image from docker hub and push to local registry +docker pull $image && \ + docker tag $image $reference && \ + docker push $reference +``` + +### Generate image manifest and sign it + +```shell +# Generate self-signed certificates +openssl req \ + -x509 \ + -sha256 \ + -nodes \ + -newkey rsa:2048 \ + -days 365 \ + -subj "/CN=$regIp/O=example inc/C=IN/ST=Haryana/L=Gurgaon" \ + -addext "subjectAltName=IP:$regIp" \ + -keyout example.key \ + -out example.crt + +# Generate image manifest +manifestFile="manifest-to-sign.json" && \ + docker generate manifest $image > $manifestFile + +# Sign manifest +signatureFile="manifest-signature.jwt" && \ + nv2 sign --method x509 \ + -k example.key \ + -c example.crt \ + -r $reference \ + -o $signatureFile \ + file:$manifestFile +``` + +### Obtain manifest and signature digests + +```shell +manifestDigest="sha256:$(sha256sum $manifestFile | cut -d " " -f 1)" && \ + signatureDigest="sha256:$(sha256sum $signatureFile | cut -d " " -f 1)" +``` + +### Create an Artifact file referencing the manifest that was signed and its signature as blob + +```shell +artifactFile="artifact.json" && \ + artifactMediaType="application/vnd.cncf.oras.artifact.manifest.v1+json" && \ + artifactType="application/vnd.cncf.notary.v2" && \ + signatureMediaType="application/vnd.cncf.notary.signature.v2+jwt" && \ + signatureFileSize=`wc -c < $signatureFile` && \ + manifestMediaType="$(cat $manifestFile | jq -r '.mediaType')" && \ + manifestFileSize=`wc -c < $manifestFile` + +cat < $artifactFile +{ + "mediaType": "$artifactMediaType", + "artifactType": "$artifactType", + "blobs": [ + { + "mediaType": "$signatureMediaType", + "digest": "$signatureDigest", + "size": $signatureFileSize + } + ], + "subjectManifest": { + "mediaType": "$manifestMediaType", + "digest": "$manifestDigest", + "size": $manifestFileSize + } +} +EOF +``` + +### Obtain artifact digest + +```shell +artifactDigest="sha256:$(sha256sum $artifactFile | cut -d " " -f 1)" +``` + +### Push signature and artifact + +```shell +# Initiate blob upload and obtain PUT location +blobPutLocation=`curl -I -X POST -s http://$registry/v2/$repo/blobs/uploads/ | grep "Location: " | sed -e "s/Location: //;s/$/\&digest=$signatureDigest/;s/\r//"` + +# Push signature blob +curl -X PUT -H "Content-Type: application/octet-stream" --data-binary @"$signatureFile" $blobPutLocation + +# Push artifact +curl -X PUT --data-binary @"$artifactFile" -H "Content-Type: $artifactMediaType" "http://$registry/v2/$repo/manifests/$artifactDigest" +``` + +### List referrers + +```shell +# Retrieve referrers +curl -s "http://$registry/oras/artifacts/v1/$repo/manifests/$manifestDigest/referrers?artifactType=$artifactType" | jq +``` + +### Verify signature + +```shell +# Retrieve signature +artifactDigest=`curl -s "http://$registry/oras/artifacts/v1/$repo/manifests/$manifestDigest/referrers?artifactType=$artifactType" | jq -r '.references[0].digest'` && \ + signatureDigest=`curl -s "http://$registry/oras/artifacts/v1/$repo/manifests/$artifactDigest" | jq -r '.blobs[0].digest'` && \ + retrievedSignatureFile="retrieved-signature.json" && \ + curl -s http://$registry/v2/$repo/blobs/$signatureDigest > $retrievedSignatureFile + +# Verify signature +nv2 verify \ + -f $retrievedSignatureFile \ + -c example.crt \ + file:$manifestFile +``` + +[distribution-distribution]: https://github.com/distribution/distribution +[reference-types]: https://github.com/oras-project/artifacts-spec +[signature]: https://github.com/notaryproject/nv2/tree/prototype-2/docs/nv2 diff --git a/docs/referrers.md b/docs/referrers.md index bdc4b42934f..58ac9e8e2ce 100644 --- a/docs/referrers.md +++ b/docs/referrers.md @@ -5,146 +5,6 @@ This document describes an experimental prototype that implements the [ORAS Artifact Manifest](https://github.com/oras-project/artifacts-spec) spec. -## Usage - Push, Discover, Pull - -The following steps illustrate how ORAS artifacts can be stored and retrieved from a registry. -The artifact in this example is a Notary V2 [signature](https://github.com/notaryproject/nv2/tree/prototype-2/docs/nv2). - -### Prerequisites - -- Local registry prototype instance -- [docker-generate](https://github.com/shizhMSFT/docker-generate) -- [nv2](https://github.com/notaryproject/nv2) -- `curl` -- `jq` - -### Push an image to your registry - -```shell -# Initialize local registry variables -regIp="127.0.0.1" && \ - regPort="5000" && \ - registry="$regIp:$regPort" && \ - repo="busybox" && \ - tag="latest" && \ - image="$repo:$tag" && \ - reference="$registry/$image" - -# Pull an image from docker hub and push to local registry -docker pull $image && \ - docker tag $image $reference && \ - docker push $reference -``` - -### Generate image manifest and sign it - -```shell -# Generate self-signed certificates -openssl req \ - -x509 \ - -sha256 \ - -nodes \ - -newkey rsa:2048 \ - -days 365 \ - -subj "/CN=$regIp/O=example inc/C=IN/ST=Haryana/L=Gurgaon" \ - -addext "subjectAltName=IP:$regIp" \ - -keyout example.key \ - -out example.crt - -# Generate image manifest -manifestFile="manifest-to-sign.json" && \ - docker generate manifest $image > $manifestFile - -# Sign manifest -signatureFile="manifest-signature.jwt" && \ - nv2 sign --method x509 \ - -k example.key \ - -c example.crt \ - -r $reference \ - -o $signatureFile \ - file:$manifestFile -``` - -### Obtain manifest and signature digests - -```shell -manifestDigest="sha256:$(sha256sum $manifestFile | cut -d " " -f 1)" && \ - signatureDigest="sha256:$(sha256sum $signatureFile | cut -d " " -f 1)" -``` - -### Create an Artifact file referencing the manifest that was signed and its signature as blob - -```shell -artifactFile="artifact.json" && \ - artifactMediaType="application/vnd.cncf.oras.artifact.manifest.v1+json" && \ - artifactType="application/vnd.cncf.notary.v2" && \ - signatureMediaType="application/vnd.cncf.notary.signature.v2+jwt" && \ - signatureFileSize=`wc -c < $signatureFile` && \ - manifestMediaType="$(cat $manifestFile | jq -r '.mediaType')" && \ - manifestFileSize=`wc -c < $manifestFile` - -cat < $artifactFile -{ - "mediaType": "$artifactMediaType", - "artifactType": "$artifactType", - "blobs": [ - { - "mediaType": "$signatureMediaType", - "digest": "$signatureDigest", - "size": $signatureFileSize - } - ], - "subjectManifest": { - "mediaType": "$manifestMediaType", - "digest": "$manifestDigest", - "size": $manifestFileSize - } -} -EOF -``` - -### Obtain artifact digest - -```shell -artifactDigest="sha256:$(sha256sum $artifactFile | cut -d " " -f 1)" -``` - -### Push signature and artifact - -```shell -# Initiate blob upload and obtain PUT location -blobPutLocation=`curl -I -X POST -s http://$registry/v2/$repo/blobs/uploads/ | grep "Location: " | sed -e "s/Location: //;s/$/\&digest=$signatureDigest/;s/\r//"` - -# Push signature blob -curl -X PUT -H "Content-Type: application/octet-stream" --data-binary @"$signatureFile" $blobPutLocation - -# Push artifact -curl -X PUT --data-binary @"$artifactFile" -H "Content-Type: $artifactMediaType" "http://$registry/v2/$repo/manifests/$artifactDigest" -``` - -### List referrers - -```shell -# Retrieve referrers -curl -s "http://$registry/oras/artifacts/v1/$repo/manifests/$manifestDigest/referrers?artifactType=$artifactType" | jq -``` - -### Verify signature - -```shell -# Retrieve signature -artifactDigest=`curl -s "http://$registry/oras/artifacts/v1/$repo/manifests/$manifestDigest/referrers?artifactType=$artifactType" | jq -r '.references[0].digest'` && \ - signatureDigest=`curl -s "http://$registry/oras/artifacts/v1/$repo/manifests/$artifactDigest" | jq -r '.blobs[0].digest'` && \ - retrievedSignatureFile="retrieved-signature.json" && \ - curl -s http://$registry/v2/$repo/blobs/$signatureDigest > $retrievedSignatureFile - -# Verify signature -nv2 verify \ - -f $retrievedSignatureFile \ - -c example.crt \ - file:$manifestFile -``` - ## Implementation To power the [/referrers](https://github.com/oras-project/artifacts-spec/blob/main/manifest-referrers-api.md) API, the diff --git a/go.mod b/go.mod index dc5ea03cc81..3a1c01ef743 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,6 @@ module github.com/distribution/distribution/v3 go 1.15 -replace github.com/oras-project/artifacts-spec => github.com/aviral26/artifacts-spec v0.0.2 - require ( github.com/Azure/azure-sdk-for-go v16.2.1+incompatible github.com/Azure/go-autorest v10.8.1+incompatible // indirect @@ -32,7 +30,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-00010101000000-000000000000 + github.com/oras-project/artifacts-spec v0.0.0-20210830204616-bd9edb3a9b43 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 f2a1020226c..74b397bb4c4 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,6 @@ github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/O github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/aviral26/artifacts-spec v0.0.2 h1:uU5MIRT68TP4l2Elri9WoweDc9f8iSwe0G0ghDCxolQ= -github.com/aviral26/artifacts-spec v0.0.2/go.mod h1:Xch2aLzSwtkhbFFN6LUzTfLtukYvMMdXJ4oZ8O7BOdc= github.com/aws/aws-sdk-go v1.34.9 h1:cUGBW9CVdi0mS7K1hDzxIqTpfeWhpoQiguq81M1tjK0= github.com/aws/aws-sdk-go v1.34.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -96,6 +94,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-20210830204616-bd9edb3a9b43 h1:WDAdGkL9gSREKHLV3eyIWalP9Q7Nf+MTnDvXi1X6xR4= +github.com/oras-project/artifacts-spec v0.0.0-20210830204616-bd9edb3a9b43/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/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..a642818686c 100644 --- a/registry/storage/manifeststore.go +++ b/registry/storage/manifeststore.go @@ -162,10 +162,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 +184,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/releases/v0.0.1-alpha.toml b/releases/v0.0.1-alpha.toml new file mode 100644 index 00000000000..6f48fdf4471 --- /dev/null +++ b/releases/v0.0.1-alpha.toml @@ -0,0 +1,31 @@ +# commit to be tagged for new release +commit = "HEAD" + +project_name = "registry" +github_repo = "oras-project/distribution" + +# previous release +previous = "main" + +pre_release = true + +preface = """ +The v0.0.1-alpha registry experimental release provides basic support for phase 1 of +[reference types](phase-1-reference-types). Clients can push and pull manifests +of media type `application/vnd.cncf.oras.artifact.manifest.v1+json` (ORAS +Artifact Manifests) and discover existing reference types using the `/referrers` +[api](referrers-api). + +This release includes the following changes pertaining to reference types: + +* Adds CRUD operations for ORAS Artifact Manifests +* Adds support for `GET /referrers` API + * In this release candidate, pagination is not implemented + * The implementation uses a [reverse index](reverse-index) as an optimization + +The release **does not** implement garbage collection of reference types. + +[phase-1-reference-types]: https://github.com/oras-project/artifacts-spec/blob/main/scenarios.md#phase-1---reference-types +[referrers-api]: https://github.com/oras-project/artifacts-spec/blob/main/manifest-referrers-api.md +[reverse-index]: docs/referrers.md +""" 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..dae2accc687 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 @@ -24,7 +24,7 @@ type Descriptor struct { // 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"` + ArtifactType string `json:"artifactType,omitempty"` // Digest is the digest of the targeted content. Digest digest.Digest `json:"digest"` 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 854d0cca935..341e7f4f678 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 @@ -27,8 +27,8 @@ type Manifest struct { 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 subjectManifest. - SubjectManifest Descriptor `json:"subjectManifest"` + // 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"` diff --git a/vendor/modules.txt b/vendor/modules.txt index d9abb28cb3b..213d36e4af8 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-00010101000000-000000000000 => github.com/aviral26/artifacts-spec v0.0.2 +# github.com/oras-project/artifacts-spec v0.0.0-20210830204616-bd9edb3a9b43 ## explicit github.com/oras-project/artifacts-spec/specs-go/v1 # github.com/prometheus/client_golang v1.1.0 @@ -246,4 +246,3 @@ gopkg.in/check.v1 # gopkg.in/yaml.v2 v2.4.0 ## explicit gopkg.in/yaml.v2 -# github.com/oras-project/artifacts-spec => github.com/aviral26/artifacts-spec v0.0.2