From 8cc5c30fbe7b744d5930449780ea7bc3def536a7 Mon Sep 17 00:00:00 2001 From: "Lixia (Sylvia) Lei" Date: Thu, 12 Oct 2023 14:59:39 +0800 Subject: [PATCH] build: bump `github.com/opencontainers/image-spec` to `v1.1.0-rc5` (#615) 1. Bump `github.com/opencontainers/image-spec` to `v1.1.0-rc5` in go mod 2. Replace "index.json" and "blobs" with corresponding constants in the spec 3. Fix testable examples that broke by the spec change - `MediaType` became a required field in `Descriptor` Resolve: #599 Signed-off-by: Lixia (Sylvia) Lei --- content/oci/oci.go | 14 ++------------ content/oci/oci_test.go | 6 +++--- content/oci/readonlyoci.go | 2 +- content/oci/readonlyoci_test.go | 14 +++++++------- content/oci/readonlystorage.go | 2 +- content/oci/readonlystorage_test.go | 6 +++--- content/oci/storage_test.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- registry/remote/example_test.go | 26 +++++++++++++++++--------- 10 files changed, 38 insertions(+), 40 deletions(-) diff --git a/content/oci/oci.go b/content/oci/oci.go index 97ba6de5..27afde16 100644 --- a/content/oci/oci.go +++ b/content/oci/oci.go @@ -38,16 +38,6 @@ import ( "oras.land/oras-go/v2/internal/resolver" ) -// ociImageIndexFile is the file name of the index -// from the OCI Image Layout Specification. -// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0-rc4/image-layout.md#indexjson-file -const ociImageIndexFile = "index.json" - -// ociBlobsDir is the name of the blobs directory -// from the OCI Image Layout Specification. -// Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0-rc4/image-layout.md#content -const ociBlobsDir = "blobs" - // 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-rc4/image-layout.md @@ -89,13 +79,13 @@ func NewWithContext(ctx context.Context, root string) (*Store, error) { store := &Store{ AutoSaveIndex: true, root: rootAbs, - indexPath: filepath.Join(rootAbs, ociImageIndexFile), + indexPath: filepath.Join(rootAbs, ocispec.ImageIndexFile), storage: storage, tagResolver: resolver.NewMemory(), graph: graph.NewMemory(), } - if err := ensureDir(filepath.Join(rootAbs, ociBlobsDir)); err != nil { + if err := ensureDir(filepath.Join(rootAbs, ocispec.ImageBlobsDir)); err != nil { return nil, err } if err := store.ensureOCILayoutFile(); err != nil { diff --git a/content/oci/oci_test.go b/content/oci/oci_test.go index 931dabf5..43e57f0a 100644 --- a/content/oci/oci_test.go +++ b/content/oci/oci_test.go @@ -109,7 +109,7 @@ func TestStore_Success(t *testing.T) { } // validate index.json - indexFilePath := filepath.Join(tempDir, ociImageIndexFile) + indexFilePath := filepath.Join(tempDir, "index.json") indexFile, err := os.Open(indexFilePath) if err != nil { t.Errorf("error opening layout file, error = %v", err) @@ -361,7 +361,7 @@ func TestStore_NotExistingRoot(t *testing.T) { } // validate index.json - indexFilePath := filepath.Join(root, ociImageIndexFile) + indexFilePath := filepath.Join(root, "index.json") indexFile, err := os.Open(indexFilePath) if err != nil { t.Errorf("error opening layout file, error = %v", err) @@ -930,7 +930,7 @@ func TestStore_TagByDigest(t *testing.T) { func TestStore_BadIndex(t *testing.T) { tempDir := t.TempDir() content := []byte("whatever") - path := filepath.Join(tempDir, ociImageIndexFile) + path := filepath.Join(tempDir, "index.json") os.WriteFile(path, content, 0666) _, err := New(tempDir) diff --git a/content/oci/readonlyoci.go b/content/oci/readonlyoci.go index eb94f61c..66ca54c9 100644 --- a/content/oci/readonlyoci.go +++ b/content/oci/readonlyoci.go @@ -154,7 +154,7 @@ func validateOCILayout(layout *ocispec.ImageLayout) error { // loadIndexFile reads index.json from s.fsys. func (s *ReadOnlyStore) loadIndexFile(ctx context.Context) error { - indexFile, err := s.fsys.Open(ociImageIndexFile) + indexFile, err := s.fsys.Open(ocispec.ImageIndexFile) if err != nil { return fmt.Errorf("failed to open index file: %w", err) } diff --git a/content/oci/readonlyoci_test.go b/content/oci/readonlyoci_test.go index fdc0cde3..d7b4fd0e 100644 --- a/content/oci/readonlyoci_test.go +++ b/content/oci/readonlyoci_test.go @@ -123,11 +123,11 @@ func TestReadOnlyStore(t *testing.T) { // build fs fsys := fstest.MapFS{} for i, desc := range descs { - path := strings.Join([]string{ociBlobsDir, desc.Digest.Algorithm().String(), desc.Digest.Encoded()}, "/") + path := strings.Join([]string{"blobs", desc.Digest.Algorithm().String(), desc.Digest.Encoded()}, "/") fsys[path] = &fstest.MapFile{Data: blobs[i]} } fsys[ocispec.ImageLayoutFile] = &fstest.MapFile{Data: layoutJSON} - fsys[ociImageIndexFile] = &fstest.MapFile{Data: indexJSON} + fsys["index.json"] = &fstest.MapFile{Data: indexJSON} // test read-only store ctx := context.Background() @@ -507,7 +507,7 @@ func TestReadOnlyStore_TarFS(t *testing.T) { func TestReadOnlyStore_BadIndex(t *testing.T) { content := []byte("whatever") fsys := fstest.MapFS{ - ociImageIndexFile: &fstest.MapFile{Data: content}, + "index.json": &fstest.MapFile{Data: content}, } ctx := context.Background() @@ -603,11 +603,11 @@ func TestReadOnlyStore_Copy_OCIToMemory(t *testing.T) { // build fs fsys := fstest.MapFS{} for i, desc := range descs { - path := strings.Join([]string{ociBlobsDir, desc.Digest.Algorithm().String(), desc.Digest.Encoded()}, "/") + path := strings.Join([]string{"blobs", desc.Digest.Algorithm().String(), desc.Digest.Encoded()}, "/") fsys[path] = &fstest.MapFile{Data: blobs[i]} } fsys[ocispec.ImageLayoutFile] = &fstest.MapFile{Data: layoutJSON} - fsys[ociImageIndexFile] = &fstest.MapFile{Data: indexJSON} + fsys["index.json"] = &fstest.MapFile{Data: indexJSON} // test read-only store ctx := context.Background() @@ -717,11 +717,11 @@ func TestReadOnlyStore_Tags(t *testing.T) { // build fs fsys := fstest.MapFS{} for i, desc := range descs { - path := strings.Join([]string{ociBlobsDir, desc.Digest.Algorithm().String(), desc.Digest.Encoded()}, "/") + path := strings.Join([]string{"blobs", desc.Digest.Algorithm().String(), desc.Digest.Encoded()}, "/") fsys[path] = &fstest.MapFile{Data: blobs[i]} } fsys[ocispec.ImageLayoutFile] = &fstest.MapFile{Data: layoutJSON} - fsys[ociImageIndexFile] = &fstest.MapFile{Data: indexJSON} + fsys["index.json"] = &fstest.MapFile{Data: indexJSON} // test read-only store ctx := context.Background() diff --git a/content/oci/readonlystorage.go b/content/oci/readonlystorage.go index b5e53039..6e319a64 100644 --- a/content/oci/readonlystorage.go +++ b/content/oci/readonlystorage.go @@ -95,5 +95,5 @@ func blobPath(dgst digest.Digest) (string, error) { return "", fmt.Errorf("cannot calculate blob path from invalid digest %s: %w: %v", dgst.String(), errdef.ErrInvalidDigest, err) } - return path.Join(ociBlobsDir, dgst.Algorithm().String(), dgst.Encoded()), nil + return path.Join(ocispec.ImageBlobsDir, dgst.Algorithm().String(), dgst.Encoded()), nil } diff --git a/content/oci/readonlystorage_test.go b/content/oci/readonlystorage_test.go index d7b4f176..b1d1906a 100644 --- a/content/oci/readonlystorage_test.go +++ b/content/oci/readonlystorage_test.go @@ -38,7 +38,7 @@ func TestReadOnlyStorage_Exists(t *testing.T) { dgst := digest.FromBytes(blob) desc := content.NewDescriptorFromBytes("", blob) fsys := fstest.MapFS{ - strings.Join([]string{ociBlobsDir, dgst.Algorithm().String(), dgst.Encoded()}, "/"): {}, + strings.Join([]string{"blobs", dgst.Algorithm().String(), dgst.Encoded()}, "/"): {}, } s := NewStorageFromFS(fsys) ctx := context.Background() @@ -76,7 +76,7 @@ func TestReadOnlyStorage_Fetch(t *testing.T) { dgst := digest.FromBytes(blob) desc := content.NewDescriptorFromBytes("", blob) fsys := fstest.MapFS{ - strings.Join([]string{ociBlobsDir, dgst.Algorithm().String(), dgst.Encoded()}, "/"): { + strings.Join([]string{"blobs", dgst.Algorithm().String(), dgst.Encoded()}, "/"): { Data: blob, }, } @@ -123,7 +123,7 @@ func TestReadOnlyStorage_DirFS(t *testing.T) { dgst := digest.FromBytes(blob) desc := content.NewDescriptorFromBytes("test", blob) // write blob to disk - path := filepath.Join(tempDir, ociBlobsDir, dgst.Algorithm().String(), dgst.Encoded()) + path := filepath.Join(tempDir, "blobs", dgst.Algorithm().String(), dgst.Encoded()) if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil { t.Fatal("error calling Mkdir(), error =", err) } diff --git a/content/oci/storage_test.go b/content/oci/storage_test.go index ac6ae8dd..7e3b1e58 100644 --- a/content/oci/storage_test.go +++ b/content/oci/storage_test.go @@ -289,7 +289,7 @@ func TestStorage_Fetch_ExistingBlobs(t *testing.T) { } tempDir := t.TempDir() - path := filepath.Join(tempDir, ociBlobsDir, dgst.Algorithm().String(), dgst.Encoded()) + path := filepath.Join(tempDir, "blobs", dgst.Algorithm().String(), dgst.Encoded()) if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil { t.Fatal("error calling Mkdir(), error =", err) } diff --git a/go.mod b/go.mod index df53ceb2..57c4c93d 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,6 @@ go 1.20 require ( github.com/opencontainers/go-digest v1.0.0 - github.com/opencontainers/image-spec v1.1.0-rc4 + github.com/opencontainers/image-spec v1.1.0-rc5 golang.org/x/sync v0.4.0 ) diff --git a/go.sum b/go.sum index ee56d5ac..41b71e0d 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,6 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= -github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= +github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= diff --git a/registry/remote/example_test.go b/registry/remote/example_test.go index 35502a94..d2fb529d 100644 --- a/registry/remote/example_test.go +++ b/registry/remote/example_test.go @@ -40,18 +40,20 @@ import ( ) const ( - exampleRepositoryName = "example" - exampleTag = "latest" - exampleConfig = "Example config content" - exampleLayer = "Example layer content" - exampleUploadUUid = "0bc84d80-837c-41d9-824e-1907463c53b3" - ManifestDigest = "sha256:0b696106ecd0654e031f19e0a8cbd1aee4ad457d7c9cea881f07b12a930cd307" - ReferenceManifestDigest = "sha256:6983f495f7ee70d43e571657ae8b39ca3d3ca1b0e77270fd4fbddfb19832a1cf" + _ = ExampleUnplayable + exampleRepositoryName = "example" + exampleTag = "latest" + exampleConfig = "Example config content" + exampleLayer = "Example layer content" + exampleUploadUUid = "0bc84d80-837c-41d9-824e-1907463c53b3" + // For ExampleRepository_Push_artifactReferenceManifest: + ManifestDigest = "sha256:a3f9d449466b9b7194c3a76ca4890d792e11eb4e62e59aa8b4c3cce0a56f129d" + ReferenceManifestDigest = "sha256:2d30397701742b04550891851529abe6b071e4fae920a91897d34612662a3bf6" + // For Example_pushAndIgnoreReferrersIndexError: referrersAPIUnavailableRepositoryName = "no-referrers-api" - referrerDigest = "sha256:21c623eb8ccd273f2702efd74a0abb455dd06a99987f413c2114fb00961ebfe7" + referrerDigest = "sha256:4caba1e18385eb152bd92e9fee1dc01e47c436e594123b3c2833acfcad9883e2" referrersTag = "sha256-c824a9aa7d2e3471306648c6d4baa1abbcb97ff0276181ab4722ca27127cdba0" referrerIndexDigest = "sha256:7baac5147dd58d56fdbaad5a888fa919235a3a90cb71aaa8b56ee5d19f4cd838" - _ = ExampleUnplayable ) var ( @@ -107,8 +109,10 @@ var ( Size: int64(len(exampleManifestWithBlobs))} subjectDescriptor = content.NewDescriptorFromBytes(ocispec.MediaTypeImageManifest, []byte(`{"layers":[]}`)) referrerManifestContent, _ = json.Marshal(ocispec.Manifest{ + Versioned: specs.Versioned{SchemaVersion: 2}, MediaType: ocispec.MediaTypeImageManifest, Subject: &subjectDescriptor, + Config: ocispec.DescriptorEmptyJSON, }) referrerDescriptor = content.NewDescriptorFromBytes(ocispec.MediaTypeImageManifest, referrerManifestContent) referrerIndex, _ = json.Marshal(ocispec.Index{ @@ -304,7 +308,11 @@ func ExampleRepository_Push_artifactReferenceManifest() { // 1. assemble the referenced artifact manifest manifest := ocispec.Manifest{ + Versioned: specs.Versioned{ + SchemaVersion: 2, // historical value. does not pertain to OCI or docker version + }, MediaType: ocispec.MediaTypeImageManifest, + Config: content.NewDescriptorFromBytes(ocispec.MediaTypeImageConfig, []byte("config bytes")), } manifestContent, err := json.Marshal(manifest) if err != nil {