From e5457d100e98e11aa335b713807d30a2fce09162 Mon Sep 17 00:00:00 2001 From: Junjie Gao Date: Thu, 31 Aug 2023 14:00:11 +0800 Subject: [PATCH] fix: update oras-go v2.3.0 Signed-off-by: Junjie Gao --- go.mod | 2 +- go.sum | 4 ++-- registry/repository.go | 36 +++++++++++++++++++++++++++++++++--- registry/repository_test.go | 6 ++++++ 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index bc209fa6..0d942b2a 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/veraison/go-cose v1.1.0 golang.org/x/crypto v0.12.0 golang.org/x/mod v0.12.0 - oras.land/oras-go/v2 v2.2.1 + oras.land/oras-go/v2 v2.3.0 ) require ( diff --git a/go.sum b/go.sum index 9ed5a621..898af608 100644 --- a/go.sum +++ b/go.sum @@ -75,5 +75,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -oras.land/oras-go/v2 v2.2.1 h1:3VJTYqy5KfelEF9c2jo1MLSpr+TM3mX8K42wzZcd6qE= -oras.land/oras-go/v2 v2.2.1/go.mod h1:GeAwLuC4G/JpNwkd+bSZ6SkDMGaaYglt6YK2WvZP7uQ= +oras.land/oras-go/v2 v2.3.0 h1:lqX1aXdN+DAmDTKjiDyvq85cIaI4RkIKp/PghWlAGIU= +oras.land/oras-go/v2 v2.3.0/go.mod h1:GeAwLuC4G/JpNwkd+bSZ6SkDMGaaYglt6YK2WvZP7uQ= diff --git a/registry/repository.go b/registry/repository.go index cb6e20a3..72c692e2 100644 --- a/registry/repository.go +++ b/registry/repository.go @@ -14,8 +14,10 @@ package registry import ( + "bytes" "context" "encoding/json" + "errors" "fmt" "os" @@ -24,6 +26,7 @@ import ( "oras.land/oras-go/v2" "oras.land/oras-go/v2/content" "oras.land/oras-go/v2/content/oci" + "oras.land/oras-go/v2/errdef" "oras.land/oras-go/v2/registry" ) @@ -187,13 +190,40 @@ func (c *repositoryClient) getSignatureBlobDesc(ctx context.Context, sigManifest // uploadSignatureManifest uploads the signature manifest to the registry func (c *repositoryClient) uploadSignatureManifest(ctx context.Context, subject, blobDesc ocispec.Descriptor, annotations map[string]string) (ocispec.Descriptor, error) { - opts := oras.PackOptions{ + configDesc, err := pushNotationManifestConfig(ctx, c.GraphTarget) + if err != nil { + return ocispec.Descriptor{}, err + } + + opts := oras.PackManifestOptions{ Subject: &subject, ManifestAnnotations: annotations, - PackImageManifest: true, + Layers: []ocispec.Descriptor{blobDesc}, + ConfigDescriptor: configDesc, } - return oras.Pack(ctx, c.GraphTarget, ArtifactTypeNotation, []ocispec.Descriptor{blobDesc}, opts) + return oras.PackManifest(ctx, c.GraphTarget, oras.PackManifestVersion1_1_RC4, "", opts) +} + +// pushNotationManifestConfig pushes an empty notation manifest config, if it +// doesn't exist. +func pushNotationManifestConfig(ctx context.Context, pusher content.Pusher) (*ocispec.Descriptor, error) { + configContent := []byte("{}") + desc := content.NewDescriptorFromBytes(ArtifactTypeNotation, configContent) + if ros, ok := pusher.(content.ReadOnlyStorage); ok { + exists, err := ros.Exists(ctx, desc) + if err != nil { + return nil, fmt.Errorf("failed to check existence: %s: %s: %w", desc.Digest.String(), desc.MediaType, err) + } + if exists { + return &desc, nil + } + } + + if err := pusher.Push(ctx, desc, bytes.NewReader(configContent)); err != nil && !errors.Is(err, errdef.ErrAlreadyExists) { + return nil, fmt.Errorf("failed to push: %s: %s: %w", desc.Digest.String(), desc.MediaType, err) + } + return &desc, nil } // signatureReferrers returns referrer nodes of desc in target filtered by diff --git a/registry/repository_test.go b/registry/repository_test.go index 38fbcf29..37caab88 100644 --- a/registry/repository_test.go +++ b/registry/repository_test.go @@ -38,6 +38,7 @@ import ( const ( zeroDigest = "sha256:0000000000000000000000000000000000000000000000000000000000000000" + emptyConfigDigest = "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a" validDigest = "6c3c624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b" validDigest2 = "1834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f2" invalidDigest = "invaliddigest" @@ -129,6 +130,11 @@ func (c mockRemoteClient) Do(req *http.Request) (*http.Response, error) { "Docker-Content-Digest": {validDigestWithAlgo2}, }, }, nil + case "/v2/test/blobs/" + emptyConfigDigest: + return &http.Response{ + StatusCode: http.StatusNotFound, + Body: io.NopCloser(bytes.NewReader([]byte{})), + }, nil case "/v2/test/manifests/" + invalidDigest: return &http.Response{}, fmt.Errorf(errMsg) case "v2/test/manifest/" + validDigest2: