Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: upgrade to distribution-spec v1.1.0 #720

Merged
merged 3 commits into from Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions content/oci/oci.go
Expand Up @@ -14,7 +14,7 @@ limitations under the License.
*/

// Package oci provides access to an OCI content store.
// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0-rc6/image-layout.md
// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0/image-layout.md
package oci

import (
Expand Down Expand Up @@ -43,7 +43,7 @@ import (

// Store implements `oras.Target`, and represents a content store
// based on file system with the OCI-Image layout.
// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0-rc6/image-layout.md
// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0/image-layout.md
type Store struct {
// AutoSaveIndex controls if the OCI store will automatically save the index
// file when needed.
Expand Down Expand Up @@ -221,7 +221,7 @@ func (s *Store) delete(ctx context.Context, target ocispec.Descriptor) ([]ocispe

// Tag tags a descriptor with a reference string.
// reference should be a valid tag (e.g. "latest").
// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0-rc6/image-layout.md#indexjson-file
// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0/image-layout.md#indexjson-file
func (s *Store) Tag(ctx context.Context, desc ocispec.Descriptor, reference string) error {
s.sync.RLock()
defer s.sync.RUnlock()
Expand Down
2 changes: 1 addition & 1 deletion content/oci/readonlyoci.go
Expand Up @@ -36,7 +36,7 @@ import (

// ReadOnlyStore implements `oras.ReadonlyTarget`, and represents a read-only
// content store based on file system with the OCI-Image layout.
// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0-rc4/image-layout.md
// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0/image-layout.md
type ReadOnlyStore struct {
fsys fs.FS
storage content.ReadOnlyStorage
Expand Down
2 changes: 1 addition & 1 deletion content/oci/readonlystorage.go
Expand Up @@ -31,7 +31,7 @@ import (

// ReadOnlyStorage is a read-only CAS based on file system with the OCI-Image
// layout.
// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0-rc4/image-layout.md
// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0/image-layout.md
type ReadOnlyStorage struct {
fsys fs.FS
}
Expand Down
2 changes: 1 addition & 1 deletion content/oci/storage.go
Expand Up @@ -43,7 +43,7 @@ var bufPool = sync.Pool{
}

// Storage is a CAS based on file system with the OCI-Image layout.
// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0-rc4/image-layout.md
// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0/image-layout.md
type Storage struct {
*ReadOnlyStorage
// root is the root directory of the OCI layout.
Expand Down
8 changes: 4 additions & 4 deletions example_pack_test.go
Expand Up @@ -25,9 +25,9 @@ import (
"oras.land/oras-go/v2/content/memory"
)

// ExampleImageV11RC4 demonstrates packing an OCI Image Manifest as defined in
// image-spec v1.1.0-rc4.
func ExamplePackManifest_imageV11RC4() {
// ExampleImageV11 demonstrates packing an OCI Image Manifest as defined in
// image-spec v1.1.0.
func ExamplePackManifest_imageV11() {
// 0. Create a storage
store := memory.New()

Expand All @@ -43,7 +43,7 @@ func ExamplePackManifest_imageV11RC4() {

// 2. Pack a manifest
artifactType := "application/vnd.example+type"
manifestDesc, err := oras.PackManifest(ctx, store, oras.PackManifestVersion1_1_RC4, artifactType, opts)
manifestDesc, err := oras.PackManifest(ctx, store, oras.PackManifestVersion1_1, artifactType, opts)
if err != nil {
panic(err)
}
Expand Down
2 changes: 1 addition & 1 deletion example_test.go
Expand Up @@ -169,7 +169,7 @@ func Example_pushFilesToRemoteRepository() {
opts := oras.PackManifestOptions{
Layers: fileDescriptors,
}
manifestDescriptor, err := oras.PackManifest(ctx, fs, oras.PackManifestVersion1_1_RC4, artifactType, opts)
manifestDescriptor, err := oras.PackManifest(ctx, fs, oras.PackManifestVersion1_1, artifactType, opts)
if err != nil {
panic(err)
}
Expand Down
17 changes: 11 additions & 6 deletions pack.go
Expand Up @@ -53,7 +53,7 @@ var (
ErrInvalidDateTimeFormat = errors.New("invalid date and time format")

// ErrMissingArtifactType is returned by [PackManifest] when
// packManifestVersion is PackManifestVersion1_1_RC4 and artifactType is
// packManifestVersion is PackManifestVersion1_1 and artifactType is
// empty and the config media type is set to
// "application/vnd.oci.empty.v1+json".
ErrMissingArtifactType = errors.New("missing artifact type")
Expand All @@ -71,7 +71,12 @@ const (
// PackManifestVersion1_1_RC4 represents the OCI Image Manifest defined
// in image-spec v1.1.0-rc4.
// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0-rc4/manifest.md
PackManifestVersion1_1_RC4 PackManifestVersion = 2
PackManifestVersion1_1_RC4 PackManifestVersion = PackManifestVersion1_1
shizhMSFT marked this conversation as resolved.
Show resolved Hide resolved

// PackManifestVersion1_1 represents the OCI Image Manifest defined in
// image-spec v1.1.0.
// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0/manifest.md
PackManifestVersion1_1 PackManifestVersion = 2
)

// PackManifestOptions contains optional parameters for [PackManifest].
Expand All @@ -98,16 +103,16 @@ type PackManifestOptions struct {

// mediaTypeRegexp checks the format of media types.
// References:
// - https://github.com/opencontainers/image-spec/blob/v1.1.0-rc4/schema/defs-descriptor.json#L7
// - https://github.com/opencontainers/image-spec/blob/v1.1.0/schema/defs-descriptor.json#L7
// - https://datatracker.ietf.org/doc/html/rfc6838#section-4.2
var mediaTypeRegexp = regexp.MustCompile(`^[A-Za-z0-9][A-Za-z0-9!#$&-^_.+]{0,126}/[A-Za-z0-9][A-Za-z0-9!#$&-^_.+]{0,126}$`)

// PackManifest generates an OCI Image Manifest based on the given parameters
// and pushes the packed manifest to a content storage using pusher. The version
// of the manifest to be packed is determined by packManifestVersion
// (Recommended value: PackManifestVersion1_1_RC4).
// (Recommended value: PackManifestVersion1_1).
//
// - If packManifestVersion is [PackManifestVersion1_1_RC4]:
// - If packManifestVersion is [PackManifestVersion1_1]:
// artifactType MUST NOT be empty unless opts.ConfigDescriptor is specified.
// - If packManifestVersion is [PackManifestVersion1_0]:
// if opts.ConfigDescriptor is nil, artifactType will be used as the
Expand All @@ -122,7 +127,7 @@ func PackManifest(ctx context.Context, pusher content.Pusher, packManifestVersio
switch packManifestVersion {
case PackManifestVersion1_0:
return packManifestV1_0(ctx, pusher, artifactType, opts)
case PackManifestVersion1_1_RC4:
case PackManifestVersion1_1:
return packManifestV1_1_RC4(ctx, pusher, artifactType, opts)
shizhMSFT marked this conversation as resolved.
Show resolved Hide resolved
default:
return ocispec.Descriptor{}, fmt.Errorf("PackManifestVersion(%v): %w", packManifestVersion, errdef.ErrUnsupported)
Expand Down
28 changes: 14 additions & 14 deletions pack_test.go
Expand Up @@ -801,13 +801,13 @@ func Test_PackManifest_ImageV1_0_InvalidDateTimeFormat(t *testing.T) {
}
}

func Test_PackManifest_ImageV1_1_RC4(t *testing.T) {
func Test_PackManifest_ImageV1_1(t *testing.T) {
s := memory.New()

// test PackManifest
ctx := context.Background()
artifactType := "application/vnd.test"
manifestDesc, err := PackManifest(ctx, s, PackManifestVersion1_1_RC4, artifactType, PackManifestOptions{})
manifestDesc, err := PackManifest(ctx, s, PackManifestVersion1_1, artifactType, PackManifestOptions{})
if err != nil {
t.Fatal("Oras.PackManifest() error =", err)
}
Expand All @@ -831,7 +831,7 @@ func Test_PackManifest_ImageV1_1_RC4(t *testing.T) {
}
}

func Test_PackManifest_ImageV1_1_RC4_WithOptions(t *testing.T) {
func Test_PackManifest_ImageV1_1_WithOptions(t *testing.T) {
s := memory.New()

// prepare test content
Expand Down Expand Up @@ -863,7 +863,7 @@ func Test_PackManifest_ImageV1_1_RC4_WithOptions(t *testing.T) {
ConfigAnnotations: configAnnotations,
ManifestAnnotations: annotations,
}
manifestDesc, err := PackManifest(ctx, s, PackManifestVersion1_1_RC4, artifactType, opts)
manifestDesc, err := PackManifest(ctx, s, PackManifestVersion1_1, artifactType, opts)
if err != nil {
t.Fatal("Oras.PackManifest() error =", err)
}
Expand Down Expand Up @@ -916,7 +916,7 @@ func Test_PackManifest_ImageV1_1_RC4_WithOptions(t *testing.T) {
ConfigAnnotations: configAnnotations,
ManifestAnnotations: annotations,
}
manifestDesc, err = PackManifest(ctx, s, PackManifestVersion1_1_RC4, "", opts)
manifestDesc, err = PackManifest(ctx, s, PackManifestVersion1_1, "", opts)
if err != nil {
t.Fatal("Oras.PackManifest() error =", err)
}
Expand Down Expand Up @@ -967,7 +967,7 @@ func Test_PackManifest_ImageV1_1_RC4_WithOptions(t *testing.T) {
ConfigAnnotations: configAnnotations,
ManifestAnnotations: annotations,
}
manifestDesc, err = PackManifest(ctx, s, PackManifestVersion1_1_RC4, artifactType, opts)
manifestDesc, err = PackManifest(ctx, s, PackManifestVersion1_1, artifactType, opts)
if err != nil {
t.Fatal("Oras.PackManifest() error =", err)
}
Expand Down Expand Up @@ -1015,12 +1015,12 @@ func Test_PackManifest_ImageV1_1_RC4_WithOptions(t *testing.T) {
}
}

func Test_PackManifest_ImageV1_1_RC4_NoArtifactType(t *testing.T) {
func Test_PackManifest_ImageV1_1_NoArtifactType(t *testing.T) {
s := memory.New()

ctx := context.Background()
// test no artifact type and no config
_, err := PackManifest(ctx, s, PackManifestVersion1_1_RC4, "", PackManifestOptions{})
_, err := PackManifest(ctx, s, PackManifestVersion1_1, "", PackManifestOptions{})
if wantErr := ErrMissingArtifactType; !errors.Is(err, wantErr) {
t.Errorf("Oras.PackManifest() error = %v, wantErr = %v", err, wantErr)
}
Expand All @@ -1031,13 +1031,13 @@ func Test_PackManifest_ImageV1_1_RC4_NoArtifactType(t *testing.T) {
MediaType: ocispec.DescriptorEmptyJSON.MediaType,
},
}
_, err = PackManifest(ctx, s, PackManifestVersion1_1_RC4, "", opts)
_, err = PackManifest(ctx, s, PackManifestVersion1_1, "", opts)
if wantErr := ErrMissingArtifactType; !errors.Is(err, wantErr) {
t.Errorf("Oras.PackManifest() error = %v, wantErr = %v", err, wantErr)
}
}

func Test_PackManifest_ImageV1_1_RC4_InvalidMediaType(t *testing.T) {
func Test_PackManifest_ImageV1_1_InvalidMediaType(t *testing.T) {
s := memory.New()

ctx := context.Background()
Expand All @@ -1048,7 +1048,7 @@ func Test_PackManifest_ImageV1_1_RC4_InvalidMediaType(t *testing.T) {
opts := PackManifestOptions{
ConfigDescriptor: &configDesc,
}
_, err := PackManifest(ctx, s, PackManifestVersion1_1_RC4, artifactType, opts)
_, err := PackManifest(ctx, s, PackManifestVersion1_1, artifactType, opts)
if wantErr := errdef.ErrInvalidMediaType; !errors.Is(err, wantErr) {
t.Errorf("Oras.PackManifest() error = %v, wantErr = %v", err, wantErr)
}
Expand All @@ -1059,13 +1059,13 @@ func Test_PackManifest_ImageV1_1_RC4_InvalidMediaType(t *testing.T) {
opts = PackManifestOptions{
ConfigDescriptor: &configDesc,
}
_, err = PackManifest(ctx, s, PackManifestVersion1_1_RC4, artifactType, opts)
_, err = PackManifest(ctx, s, PackManifestVersion1_1, artifactType, opts)
if wantErr := errdef.ErrInvalidMediaType; !errors.Is(err, wantErr) {
t.Errorf("Oras.PackManifest() error = %v, wantErr = %v", err, wantErr)
}
}

func Test_PackManifest_ImageV1_1_RC4_InvalidDateTimeFormat(t *testing.T) {
func Test_PackManifest_ImageV1_1_InvalidDateTimeFormat(t *testing.T) {
s := memory.New()

ctx := context.Background()
Expand All @@ -1075,7 +1075,7 @@ func Test_PackManifest_ImageV1_1_RC4_InvalidDateTimeFormat(t *testing.T) {
},
}
artifactType := "application/vnd.test"
_, err := PackManifest(ctx, s, PackManifestVersion1_1_RC4, artifactType, opts)
_, err := PackManifest(ctx, s, PackManifestVersion1_1, artifactType, opts)
if wantErr := ErrInvalidDateTimeFormat; !errors.Is(err, wantErr) {
t.Errorf("Oras.PackManifest() error = %v, wantErr = %v", err, wantErr)
}
Expand Down
4 changes: 2 additions & 2 deletions registry/reference.go
Expand Up @@ -34,13 +34,13 @@ var (
//
// References:
// - https://github.com/distribution/distribution/blob/v2.7.1/reference/regexp.go#L53
// - https://github.com/opencontainers/distribution-spec/blob/v1.1.0-rc4/spec.md#pulling-manifests
// - https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#pulling-manifests
repositoryRegexp = regexp.MustCompile(`^[a-z0-9]+(?:(?:[._]|__|[-]*)[a-z0-9]+)*(?:/[a-z0-9]+(?:(?:[._]|__|[-]*)[a-z0-9]+)*)*$`)

// tagRegexp checks the tag name.
// The docker and OCI spec have the same regular expression.
//
// Reference: https://github.com/opencontainers/distribution-spec/blob/v1.1.0-rc4/spec.md#pulling-manifests
// Reference: https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#pulling-manifests
tagRegexp = regexp.MustCompile(`^[\w][\w.-]{0,127}$`)
)

Expand Down
6 changes: 3 additions & 3 deletions registry/remote/errcode/errors.go
Expand Up @@ -24,7 +24,7 @@ import (
)

// References:
// - https://github.com/opencontainers/distribution-spec/blob/v1.1.0-rc4/spec.md#error-codes
// - https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#error-codes
// - https://docs.docker.com/registry/spec/api/#errors-2
const (
ErrorCodeBlobUnknown = "BLOB_UNKNOWN"
Expand All @@ -45,7 +45,7 @@ const (
// Error represents a response inner error returned by the remote
// registry.
// References:
// - https://github.com/opencontainers/distribution-spec/blob/v1.1.0-rc4/spec.md#error-codes
// - https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#error-codes
// - https://docs.docker.com/registry/spec/api/#errors-2
type Error struct {
Code string `json:"code"`
Expand Down Expand Up @@ -73,7 +73,7 @@ func (e Error) Error() string {
// Errors represents a list of response inner errors returned by the remote
// server.
// References:
// - https://github.com/opencontainers/distribution-spec/blob/v1.1.0-rc4/spec.md#error-codes
// - https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#error-codes
// - https://docs.docker.com/registry/spec/api/#errors-2
type Errors []Error

Expand Down
2 changes: 1 addition & 1 deletion registry/remote/referrers.go
Expand Up @@ -102,7 +102,7 @@ func (e *ReferrersError) IsReferrersIndexDelete() bool {

// buildReferrersTag builds the referrers tag for the given manifest descriptor.
// Format: <algorithm>-<digest>
// Reference: https://github.com/opencontainers/distribution-spec/blob/v1.1.0-rc4/spec.md#unavailable-referrers-api
// Reference: https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#unavailable-referrers-api
func buildReferrersTag(desc ocispec.Descriptor) string {
alg := desc.Digest.Algorithm().String()
encoded := desc.Digest.Encoded()
Expand Down
2 changes: 1 addition & 1 deletion registry/remote/registry.go
Expand Up @@ -94,7 +94,7 @@ func (r *Registry) do(req *http.Request) (*http.Response, error) {
//
// References:
// - https://docs.docker.com/registry/spec/api/#base
// - https://github.com/opencontainers/distribution-spec/blob/v1.1.0-rc4/spec.md#api
// - https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#api
func (r *Registry) Ping(ctx context.Context) error {
url := buildRegistryBaseURL(r.PlainHTTP, r.Reference)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
Expand Down