From d6a59943ef48178783ffd28b862c5e1c62ca50ca Mon Sep 17 00:00:00 2001 From: Uwe Krueger Date: Wed, 6 Nov 2024 12:00:00 +0100 Subject: [PATCH] fix artifact set tagging (#1033) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What this PR does / why we need it Because the new OCI references now always contain the digest in addition to the tag, the artifactset creation is not able anymore to provide appropriate meta data. This is fixed by a new ArtVersion type able to handle the combination of digest and tag. #### Which issue(s) this PR fixes --------- Co-authored-by: Jakob Möller --- api/oci/art_test.go | 8 +- .../artifactset/utils_synthesis.go | 10 +- api/oci/ociutils/ref.go | 97 +++++++++++++++++++ api/oci/ref.go | 48 +++++---- api/oci/ref_test.go | 83 +++++++++++----- api/oci/testhelper/manifests.go | 6 +- .../accessmethods/ociartifact/method.go | 4 +- .../relativeociref/method_test.go | 2 +- .../handlers/oci/ocirepo/handler_test.go | 2 +- .../download/handlers/ocirepo/handler.go | 25 ++--- api/ocm/tools/signing/transport_test.go | 2 +- .../common/handlers/artifacthdlr/closure.go | 2 +- .../handlers/artifacthdlr/typehandler.go | 2 +- 13 files changed, 214 insertions(+), 77 deletions(-) create mode 100644 api/oci/ociutils/ref.go diff --git a/api/oci/art_test.go b/api/oci/art_test.go index d118fb22a..5305930dc 100644 --- a/api/oci/art_test.go +++ b/api/oci/art_test.go @@ -15,7 +15,7 @@ func CheckArt(ref string, exp *oci.ArtSpec) { Expect(err).To(HaveOccurred()) } else { Expect(err).To(Succeed()) - Expect(spec).To(Equal(*exp)) + Expect(spec).To(Equal(exp)) } } @@ -26,9 +26,9 @@ var _ = Describe("art parsing", func() { It("succeeds", func() { CheckArt("ubuntu", &oci.ArtSpec{Repository: "ubuntu"}) CheckArt("ubuntu/test", &oci.ArtSpec{Repository: "ubuntu/test"}) - CheckArt("ubuntu/test@"+digest.String(), &oci.ArtSpec{Repository: "ubuntu/test", Digest: &digest}) - CheckArt("ubuntu/test:"+tag, &oci.ArtSpec{Repository: "ubuntu/test", Tag: &tag}) - CheckArt("ubuntu/test:"+tag+"@"+digest.String(), &oci.ArtSpec{Repository: "ubuntu/test", Digest: &digest, Tag: &tag}) + CheckArt("ubuntu/test@"+digest.String(), &oci.ArtSpec{Repository: "ubuntu/test", ArtVersion: oci.ArtVersion{Digest: &digest}}) + CheckArt("ubuntu/test:"+tag, &oci.ArtSpec{Repository: "ubuntu/test", ArtVersion: oci.ArtVersion{Tag: &tag}}) + CheckArt("ubuntu/test:"+tag+"@"+digest.String(), &oci.ArtSpec{Repository: "ubuntu/test", ArtVersion: oci.ArtVersion{Digest: &digest, Tag: &tag}}) }) It("fails", func() { diff --git a/api/oci/extensions/repositories/artifactset/utils_synthesis.go b/api/oci/extensions/repositories/artifactset/utils_synthesis.go index 2a6bd5641..74165c115 100644 --- a/api/oci/extensions/repositories/artifactset/utils_synthesis.go +++ b/api/oci/extensions/repositories/artifactset/utils_synthesis.go @@ -11,6 +11,7 @@ import ( "ocm.software/ocm/api/oci/artdesc" "ocm.software/ocm/api/oci/cpi" + "ocm.software/ocm/api/oci/ociutils" "ocm.software/ocm/api/oci/tools/transfer" "ocm.software/ocm/api/oci/tools/transfer/filters" "ocm.software/ocm/api/utils/accessio" @@ -92,14 +93,19 @@ func SynthesizeArtifactBlobForArtifact(art cpi.ArtifactAccess, ref string, filte return nil, err } + vers, err := ociutils.ParseVersion(ref) + if err != nil { + return nil, err + } + return SythesizeArtifactSet(func(set *ArtifactSet) (string, error) { dig, err := transfer.TransferArtifactWithFilter(art, set, filters.And(filter...)) if err != nil { return "", fmt.Errorf("failed to transfer artifact: %w", err) } - if ok, _ := artdesc.IsDigest(ref); !ok { - err = set.AddTags(*dig, ref) + if ok := vers.IsTagged(); ok { + err = set.AddTags(*dig, vers.GetTag()) if err != nil { return "", fmt.Errorf("failed to add tag: %w", err) } diff --git a/api/oci/ociutils/ref.go b/api/oci/ociutils/ref.go new file mode 100644 index 000000000..50f767526 --- /dev/null +++ b/api/oci/ociutils/ref.go @@ -0,0 +1,97 @@ +package ociutils + +import ( + "strings" + + "github.com/mandelsoft/goutils/generics" + "github.com/opencontainers/go-digest" +) + +// ParseVersion parses the version part of an OCI reference consisting +// of an optional tag and/or digest. +func ParseVersion(vers string) (*ArtVersion, error) { + if strings.HasPrefix(vers, "@") { + dig, err := digest.Parse(vers[1:]) + if err != nil { + return nil, err + } + return &ArtVersion{ + Digest: &dig, + }, nil + } + + i := strings.Index(vers, "@") + if i > 0 { + dig, err := digest.Parse(vers[i+1:]) + if err != nil { + return nil, err + } + return &ArtVersion{ + Tag: generics.Pointer(vers[:i]), + Digest: &dig, + }, nil + } + return &ArtVersion{ + Tag: &vers, + }, nil +} + +// ArtVersion is the version part of an OCI reference consisting of an +// optional tag and/or digest. Both parts may be nil, if a reference +// does not include a version part. +// Such objects are sub objects of (oci.)ArtSpec, which has be moved +// to separate package to avoid package cycles. The methods are +// derived from ArtSpec. +type ArtVersion struct { + // +optional + Tag *string `json:"tag,omitempty"` + // +optional + Digest *digest.Digest `json:"digest,omitempty"` +} + +func (v *ArtVersion) VersionSpec() string { + if v != nil { + return "" + } + + vers := "" + if v.Tag != nil { + vers = *v.Tag + } + + if v.Digest != nil { + vers += "@" + string(*v.Digest) + } + if vers == "" { + return "latest" + } + return vers +} + +// IsVersion returns true, if the object ref is given +// and describes a dedicated version, either by tag or digest. +// As part of the ArtSpec type in oci, it might describe +// no version part. THis method indicates, whether a version part +// is present. +func (v *ArtVersion) IsVersion() bool { + if v == nil { + return false + } + return v.Tag != nil || v.Digest != nil +} + +func (v *ArtVersion) IsTagged() bool { + return v != nil && v.Tag != nil +} + +func (v *ArtVersion) IsDigested() bool { + return v != nil && v.Digest != nil +} + +func (v *ArtVersion) GetTag() string { + if v != nil && + v.Tag != nil { + return *v.Tag + } + return "" +} diff --git a/api/oci/ref.go b/api/oci/ref.go index 457eef3f1..20186d78c 100644 --- a/api/oci/ref.go +++ b/api/oci/ref.go @@ -8,6 +8,7 @@ import ( "github.com/opencontainers/go-digest" "ocm.software/ocm/api/oci/grammar" + "ocm.software/ocm/api/oci/ociutils" ) // to find a suitable secret for images on Docker Hub, we need its two domains to do matching. @@ -224,11 +225,18 @@ func (r RefSpec) DeepCopy() RefSpec { //////////////////////////////////////////////////////////////////////////////// -func ParseArt(art string) (ArtSpec, error) { +// ParseVersion parses an OCI version part of an OCI reference. +// It has to be placed in a utils package to avoid package cycles +// for particular users. +func ParseVersion(vers string) (*ArtVersion, error) { + return ociutils.ParseVersion(vers) +} + +func ParseArt(art string) (*ArtSpec, error) { match := grammar.AnchoredArtifactVersionRegexp.FindSubmatch([]byte(art)) if match == nil { - return ArtSpec{}, errors.ErrInvalid(KIND_ARETEFACT_REFERENCE, art) + return nil, errors.ErrInvalid(KIND_ARETEFACT_REFERENCE, art) } var tag *string var dig *digest.Digest @@ -241,25 +249,27 @@ func ParseArt(art string) (ArtSpec, error) { t := string(match[3]) d, err := digest.Parse(t) if err != nil { - return ArtSpec{}, errors.ErrInvalidWrap(err, KIND_ARETEFACT_REFERENCE, art) + return nil, errors.ErrInvalidWrap(err, KIND_ARETEFACT_REFERENCE, art) } dig = &d } - return ArtSpec{ + return &ArtSpec{ Repository: string(match[1]), - Tag: tag, - Digest: dig, + ArtVersion: ArtVersion{ + Tag: tag, + Digest: dig, + }, }, nil } +type ArtVersion = ociutils.ArtVersion + // ArtSpec is a go internal representation of a oci reference. type ArtSpec struct { // Repository is the part of a reference without its hostname Repository string `json:"repository"` - // +optional - Tag *string `json:"tag,omitempty"` - // +optional - Digest *digest.Digest `json:"digest,omitempty"` + // artifact version + ArtVersion `json:",inline"` } func (r *ArtSpec) Version() string { @@ -276,22 +286,10 @@ func (r *ArtSpec) IsRegistry() bool { return r.Repository == "" } -func (r *ArtSpec) IsVersion() bool { - return r.Tag != nil || r.Digest != nil -} - -func (r *ArtSpec) IsTagged() bool { - return r.Tag != nil -} - -func (r *ArtSpec) GetTag() string { - if r.Tag != nil { - return *r.Tag - } - return "" -} - func (r *ArtSpec) String() string { + if r == nil { + return "" + } s := r.Repository if r.Tag != nil { s += fmt.Sprintf(":%s", *r.Tag) diff --git a/api/oci/ref_test.go b/api/oci/ref_test.go index a62abd3c1..f0d27516c 100644 --- a/api/oci/ref_test.go +++ b/api/oci/ref_test.go @@ -3,6 +3,7 @@ package oci_test import ( "strings" + "github.com/mandelsoft/goutils/generics" . "github.com/mandelsoft/goutils/testutils" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -143,8 +144,7 @@ var _ = Describe("ref parsing", func() { }, ArtSpec: oci.ArtSpec{ Repository: r, - Tag: Pointer([]byte(uv)), - Digest: Dig([]byte(ud)), + ArtVersion: oci.ArtVersion{Tag: Pointer([]byte(uv)), Digest: Dig([]byte(ud))}, }, }) }) @@ -192,8 +192,10 @@ var _ = Describe("ref parsing", func() { }, ArtSpec: oci.ArtSpec{ Repository: r, - Tag: Pointer([]byte(uv)), - Digest: Dig([]byte(ud)), + ArtVersion: oci.ArtVersion{ + Tag: Pointer([]byte(uv)), + Digest: Dig([]byte(ud)), + }, }, }) }) @@ -253,8 +255,8 @@ var _ = Describe("ref parsing", func() { }, ArtSpec: oci.ArtSpec{ Repository: r, - Tag: Pointer([]byte(uv)), - Digest: Dig([]byte(ud)), + ArtVersion: oci.ArtVersion{Tag: Pointer([]byte(uv)), + Digest: Dig([]byte(ud))}, }, }) }) @@ -291,8 +293,8 @@ var _ = Describe("ref parsing", func() { }, ArtSpec: oci.ArtSpec{ Repository: r, - Tag: Pointer([]byte(uv)), - Digest: Dig([]byte(ud)), + ArtVersion: oci.ArtVersion{Tag: Pointer([]byte(uv)), + Digest: Dig([]byte(ud))}, }, }) }) @@ -341,8 +343,8 @@ var _ = Describe("ref parsing", func() { }, ArtSpec: oci.ArtSpec{ Repository: r, - Tag: Pointer([]byte(uv)), - Digest: Dig([]byte(ud)), + ArtVersion: oci.ArtVersion{Tag: Pointer([]byte(uv)), + Digest: Dig([]byte(ud))}, }, }) }) @@ -380,8 +382,8 @@ var _ = Describe("ref parsing", func() { }, ArtSpec: oci.ArtSpec{ Repository: "library/" + r, - Tag: Pointer([]byte(uv)), - Digest: Dig([]byte(ud)), + ArtVersion: oci.ArtVersion{Tag: Pointer([]byte(uv)), + Digest: Dig([]byte(ud))}, }, }) }) @@ -416,8 +418,8 @@ var _ = Describe("ref parsing", func() { }, ArtSpec: oci.ArtSpec{ Repository: r, - Tag: Pointer([]byte(uv)), - Digest: Dig([]byte(ud)), + ArtVersion: oci.ArtVersion{Tag: Pointer([]byte(uv)), + Digest: Dig([]byte(ud))}, }, }) }) @@ -565,20 +567,20 @@ var _ = Describe("ref parsing", func() { }) It("succeeds", func() { CheckRef("ubuntu", &oci.RefSpec{UniformRepositorySpec: docker, ArtSpec: oci.ArtSpec{Repository: "library/ubuntu"}}) - CheckRef("ubuntu:v1", &oci.RefSpec{UniformRepositorySpec: docker, ArtSpec: oci.ArtSpec{Repository: "library/ubuntu", Tag: &tag}}) + CheckRef("ubuntu:v1", &oci.RefSpec{UniformRepositorySpec: docker, ArtSpec: oci.ArtSpec{Repository: "library/ubuntu", ArtVersion: oci.ArtVersion{Tag: &tag}}}) CheckRef("test/ubuntu", &oci.RefSpec{UniformRepositorySpec: docker, ArtSpec: oci.ArtSpec{Repository: "test/ubuntu"}}) CheckRef("test_test/ubuntu", &oci.RefSpec{UniformRepositorySpec: docker, ArtSpec: oci.ArtSpec{Repository: "test_test/ubuntu"}}) CheckRef("test__test/ubuntu", &oci.RefSpec{UniformRepositorySpec: docker, ArtSpec: oci.ArtSpec{Repository: "test__test/ubuntu"}}) CheckRef("test-test/ubuntu", &oci.RefSpec{UniformRepositorySpec: docker, ArtSpec: oci.ArtSpec{Repository: "test-test/ubuntu"}}) CheckRef("test--test/ubuntu", &oci.RefSpec{UniformRepositorySpec: docker, ArtSpec: oci.ArtSpec{Repository: "test--test/ubuntu"}}) CheckRef("test-----test/ubuntu", &oci.RefSpec{UniformRepositorySpec: docker, ArtSpec: oci.ArtSpec{Repository: "test-----test/ubuntu"}}) - CheckRef("test/ubuntu:v1", &oci.RefSpec{UniformRepositorySpec: docker, ArtSpec: oci.ArtSpec{Repository: "test/ubuntu", Tag: &tag}}) + CheckRef("test/ubuntu:v1", &oci.RefSpec{UniformRepositorySpec: docker, ArtSpec: oci.ArtSpec{Repository: "test/ubuntu", ArtVersion: oci.ArtVersion{Tag: &tag}}}) CheckRef("ghcr.io/test/ubuntu", &oci.RefSpec{UniformRepositorySpec: ghcr, ArtSpec: oci.ArtSpec{Repository: "test/ubuntu"}}) CheckRef("ghcr.io/test", &oci.RefSpec{UniformRepositorySpec: ghcr, ArtSpec: oci.ArtSpec{Repository: "test"}}) CheckRef("ghcr.io:8080/test/ubuntu", &oci.RefSpec{UniformRepositorySpec: oci.UniformRepositorySpec{Host: "ghcr.io:8080"}, ArtSpec: oci.ArtSpec{Repository: "test/ubuntu"}}) - CheckRef("ghcr.io/test/ubuntu:v1", &oci.RefSpec{UniformRepositorySpec: ghcr, ArtSpec: oci.ArtSpec{Repository: "test/ubuntu", Tag: &tag}}) - CheckRef("ghcr.io/test/ubuntu@sha256:3d05e105e350edf5be64fe356f4906dd3f9bf442a279e4142db9879bba8e677a", &oci.RefSpec{UniformRepositorySpec: ghcr, ArtSpec: oci.ArtSpec{Repository: "test/ubuntu", Digest: &digest}}) - CheckRef("ghcr.io/test/ubuntu:v1@sha256:3d05e105e350edf5be64fe356f4906dd3f9bf442a279e4142db9879bba8e677a", &oci.RefSpec{UniformRepositorySpec: ghcr, ArtSpec: oci.ArtSpec{Repository: "test/ubuntu", Tag: &tag, Digest: &digest}}) + CheckRef("ghcr.io/test/ubuntu:v1", &oci.RefSpec{UniformRepositorySpec: ghcr, ArtSpec: oci.ArtSpec{Repository: "test/ubuntu", ArtVersion: oci.ArtVersion{Tag: &tag}}}) + CheckRef("ghcr.io/test/ubuntu@sha256:3d05e105e350edf5be64fe356f4906dd3f9bf442a279e4142db9879bba8e677a", &oci.RefSpec{UniformRepositorySpec: ghcr, ArtSpec: oci.ArtSpec{Repository: "test/ubuntu", ArtVersion: oci.ArtVersion{Digest: &digest}}}) + CheckRef("ghcr.io/test/ubuntu:v1@sha256:3d05e105e350edf5be64fe356f4906dd3f9bf442a279e4142db9879bba8e677a", &oci.RefSpec{UniformRepositorySpec: ghcr, ArtSpec: oci.ArtSpec{Repository: "test/ubuntu", ArtVersion: oci.ArtVersion{Tag: &tag, Digest: &digest}}}) CheckRef("test___test/ubuntu", &oci.RefSpec{ UniformRepositorySpec: oci.UniformRepositorySpec{ Info: "test___test/ubuntu", @@ -594,8 +596,8 @@ var _ = Describe("ref parsing", func() { }, ArtSpec: oci.ArtSpec{ Repository: "repo/repo", - Tag: &tag, - Digest: &digest, + ArtVersion: oci.ArtVersion{Tag: &tag, + Digest: &digest}, }, }) CheckRef("http://127.0.0.1:443/repo/repo:v1@"+digest.String(), &oci.RefSpec{ @@ -607,8 +609,8 @@ var _ = Describe("ref parsing", func() { }, ArtSpec: oci.ArtSpec{ Repository: "repo/repo", - Tag: &tag, - Digest: &digest, + ArtVersion: oci.ArtVersion{Tag: &tag, + Digest: &digest}, }, }) CheckRef("directory::a/b", &oci.RefSpec{ @@ -695,7 +697,7 @@ var _ = Describe("ref parsing", func() { }, ArtSpec: oci.ArtSpec{ Repository: "mandelsoft/test", - Tag: &tag, + ArtVersion: oci.ArtVersion{Tag: &tag}, }, }) CheckRef("/tmp/ctf", &oci.RefSpec{ @@ -722,7 +724,7 @@ var _ = Describe("ref parsing", func() { }, ArtSpec: oci.ArtSpec{ Repository: "repo", - Tag: &tag, + ArtVersion: oci.ArtVersion{Tag: &tag}, }, }) ref := Must(oci.ParseRef("OCIRegistry::{\"type\":\"OCIRegistry\", \"baseUrl\": \"test.com\"}//repo:1.0.0")) @@ -745,7 +747,7 @@ var _ = Describe("ref parsing", func() { }, ArtSpec: oci.ArtSpec{ Repository: "repo", - Tag: &tag, + ArtVersion: oci.ArtVersion{Tag: &tag}, }, }) ref := Must(oci.ParseRef("oci::{\"type\":\"OCIRegistry\", \"baseUrl\": \"test.com\"}//repo:1.0.0")) @@ -826,4 +828,33 @@ var _ = Describe("ref parsing", func() { spec := Must(ctx.MapUniformRepositorySpec(&ref)) Expect(spec).To(Equal(Must(ctf.NewRepositorySpec(accessobj.ACC_WRITABLE, "./file/path")))) }) + + Context("version", func() { + It("parses tag", func() { + v := Must(oci.ParseVersion("tag")) + + Expect(v).To(Equal(&oci.ArtVersion{ + Tag: generics.Pointer("tag"), + Digest: nil, + })) + }) + + It("parses digest", func() { + v := Must(oci.ParseVersion("@sha256:3d05e105e350edf5be64fe356f4906dd3f9bf442a279e4142db9879bba8e677a")) + + Expect(v).To(Equal(&oci.ArtVersion{ + Tag: nil, + Digest: generics.Pointer(godigest.Digest("sha256:3d05e105e350edf5be64fe356f4906dd3f9bf442a279e4142db9879bba8e677a")), + })) + }) + + It("parses tag+digest", func() { + v := Must(oci.ParseVersion("tag@sha256:3d05e105e350edf5be64fe356f4906dd3f9bf442a279e4142db9879bba8e677a")) + + Expect(v).To(Equal(&oci.ArtVersion{ + Tag: generics.Pointer("tag"), + Digest: generics.Pointer(godigest.Digest("sha256:3d05e105e350edf5be64fe356f4906dd3f9bf442a279e4142db9879bba8e677a")), + })) + }) + }) }) diff --git a/api/oci/testhelper/manifests.go b/api/oci/testhelper/manifests.go index 824ab871f..44b92c12c 100644 --- a/api/oci/testhelper/manifests.go +++ b/api/oci/testhelper/manifests.go @@ -64,7 +64,8 @@ func OCIArtifactResource1(env *builder.Builder, name string, host string, funcs const ( D_OCIMANIFEST1 = "0c4abdb72cf59cb4b77f4aacb4775f9f546ebc3face189b2224a966c8826ca9f" - H_OCIARCHMANIFEST1 = "b0692bcec00e0a875b6b280f3209d6776f3eca128adcb7e81e82fd32127c0c62" + H_OCIARCHMANIFEST1 = "818fb6a69a5f55e8b3dbc921a61fdd000b9445a745b587ba753a811b02426326" + // H_OCIARCHMANIFEST1 = "b0692bcec00e0a875b6b280f3209d6776f3eca128adcb7e81e82fd32127c0c62". ) var DS_OCIMANIFEST1 = &metav1.DigestSpec{ @@ -123,7 +124,8 @@ func OCIManifest2For(env *builder.Builder, ns, tag string, nested ...func()) (*a const ( D_OCIMANIFEST2 = "c2d2dca275c33c1270dea6168a002d67c0e98780d7a54960758139ae19984bd7" - H_OCIARCHMANIFEST2 = "cb85cd58b10e36343971691abbfe40200cb645c6e95f0bdabd111a30cf794708" + H_OCIARCHMANIFEST2 = "2aaf6f8857dcbfa04a72fb98dd53f649b46e5d81aa4fb17330df74b0ffc30839" + // H_OCIARCHMANIFEST2 = "cb85cd58b10e36343971691abbfe40200cb645c6e95f0bdabd111a30cf794708". ) func HashManifest2(fmt string) string { diff --git a/api/ocm/extensions/accessmethods/ociartifact/method.go b/api/ocm/extensions/accessmethods/ociartifact/method.go index b31ca9d61..a8cb90841 100644 --- a/api/ocm/extensions/accessmethods/ociartifact/method.go +++ b/api/ocm/extensions/accessmethods/ociartifact/method.go @@ -247,7 +247,7 @@ func (m *accessMethod) eval(relto oci.Repository) error { } ref = oci.RefSpec{ UniformRepositorySpec: *repo.GetSpecification().UniformRepositorySpec(), - ArtSpec: art, + ArtSpec: *art, } m.repo = repo } @@ -355,7 +355,7 @@ func (m *accessMethod) getBlob() (artifactset.ArtifactBlob, error) { } logger := Logger(WrapContextProvider(m.ctx)) logger.Info("synthesize artifact blob", "ref", m.reference) - m.blob, err = artifactset.SynthesizeArtifactBlobForArtifact(m.art, m.ref.Version()) + m.blob, err = artifactset.SynthesizeArtifactBlobForArtifact(m.art, m.ref.VersionSpec()) logger.Info("synthesize artifact blob done", "ref", m.reference, "error", logging.ErrorMessage(err)) if err != nil { m.err = err diff --git a/api/ocm/extensions/accessmethods/relativeociref/method_test.go b/api/ocm/extensions/accessmethods/relativeociref/method_test.go index 4634480fc..2e589770c 100644 --- a/api/ocm/extensions/accessmethods/relativeociref/method_test.go +++ b/api/ocm/extensions/accessmethods/relativeociref/method_test.go @@ -68,7 +68,7 @@ var _ = Describe("Method", func() { return m.Close() }) data := Must(m.Get()) - Expect(len(data)).To(Equal(628)) + Expect(len(data)).To(Equal(630)) Expect(accspeccpi.GetAccessMethodImplementation(m).(blobaccess.DigestSource).Digest().String()).To(Equal("sha256:0c4abdb72cf59cb4b77f4aacb4775f9f546ebc3face189b2224a966c8826ca9f")) Expect(utils.GetOCIArtifactRef(env, res)).To(Equal("ocm/value:v2.0")) }) diff --git a/api/ocm/extensions/blobhandler/handlers/oci/ocirepo/handler_test.go b/api/ocm/extensions/blobhandler/handlers/oci/ocirepo/handler_test.go index 66fec9df1..6fc5155f2 100644 --- a/api/ocm/extensions/blobhandler/handlers/oci/ocirepo/handler_test.go +++ b/api/ocm/extensions/blobhandler/handlers/oci/ocirepo/handler_test.go @@ -125,7 +125,7 @@ var _ = Describe("oci artifact transfer", func() { data := Must(json.Marshal(comp.GetDescriptor().Resources[1].Access)) fmt.Printf("%s\n", string(data)) - Expect(string(data)).To(StringEqualWithContext(`{"globalAccess":{"imageReference":"baseurl.io/ocm/value:v2.0@sha256:` + D_OCIMANIFEST1 + `","type":"ociArtifact"},"localReference":"sha256:b0692bcec00e0a875b6b280f3209d6776f3eca128adcb7e81e82fd32127c0c62","mediaType":"application/vnd.oci.image.manifest.v1+tar+gzip","referenceName":"ocm/value:v2.0","type":"localBlob"}`)) + Expect(string(data)).To(StringEqualWithContext(`{"globalAccess":{"imageReference":"baseurl.io/ocm/value:v2.0@sha256:` + D_OCIMANIFEST1 + `","type":"ociArtifact"},"localReference":"sha256:` + H_OCIARCHMANIFEST1 + `","mediaType":"application/vnd.oci.image.manifest.v1+tar+gzip","referenceName":"ocm/value:v2.0","type":"localBlob"}`)) ocirepo := genericocireg.GetOCIRepository(tgt) Expect(ocirepo).NotTo(BeNil()) diff --git a/api/ocm/extensions/download/handlers/ocirepo/handler.go b/api/ocm/extensions/download/handlers/ocirepo/handler.go index 269a9bb0a..b6b8dcad6 100644 --- a/api/ocm/extensions/download/handlers/ocirepo/handler.go +++ b/api/ocm/extensions/download/handlers/ocirepo/handler.go @@ -78,7 +78,7 @@ func (h *handler) Download(p common.Printer, racc cpi.ResourceAccess, path strin ocictx := ctx.OCIContext() - var artspec oci.ArtSpec + var artspec *oci.ArtSpec var prefix string var result oci.RefSpec @@ -101,7 +101,7 @@ func (h *handler) Download(p common.Printer, racc cpi.ResourceAccess, path strin return true, "", err } finalize.Close(repo, "repository for downloading OCI artifact") - artspec = ref.ArtSpec + artspec = &ref.ArtSpec } else { log.Debug("evaluating config") if path != "" { @@ -117,16 +117,19 @@ func (h *handler) Download(p common.Printer, racc cpi.ResourceAccess, path strin } result.UniformRepositorySpec = *us } - log.Debug("using artifact spec", "spec", artspec.String()) - if artspec.Digest != nil { - return true, "", fmt.Errorf("digest not possible for target") - } - if artspec.Repository != "" { - namespace = artspec.Repository - } - if artspec.IsTagged() { - tag = *artspec.Tag + if artspec != nil { + log.Debug("using artifact spec", "spec", artspec.String()) + if artspec.IsDigested() { + return true, "", fmt.Errorf("digest not possible for target") + } + + if artspec.Repository != "" { + namespace = artspec.Repository + } + if artspec.IsTagged() { + tag = *artspec.Tag + } } if prefix != "" && namespace != "" { diff --git a/api/ocm/tools/signing/transport_test.go b/api/ocm/tools/signing/transport_test.go index 85323ce2b..c5294e2d1 100644 --- a/api/ocm/tools/signing/transport_test.go +++ b/api/ocm/tools/signing/transport_test.go @@ -168,7 +168,7 @@ var _ = Describe("transport and signing", func() { ra := desc.GetResourceIndexByIdentity(metav1.NewIdentity("image")) Expect(ra).To(BeNumerically(">=", 0)) // indeed, the artifact set archive hash seems to be reproducible - desc.Resources[ra].Access = localblob.New("sha256:b0692bcec00e0a875b6b280f3209d6776f3eca128adcb7e81e82fd32127c0c62", "ocm/value:v2.0", "application/vnd.oci.image.manifest.v1+tar+gzip", nil) + desc.Resources[ra].Access = localblob.New("sha256:"+H_OCIARCHMANIFEST1, "ocm/value:v2.0", "application/vnd.oci.image.manifest.v1+tar+gzip", nil) Expect(tcv.GetDescriptor()).To(YAMLEqual(desc)) descSigned := tcv.GetDescriptor().Copy() diff --git a/cmds/ocm/commands/ocicmds/common/handlers/artifacthdlr/closure.go b/cmds/ocm/commands/ocicmds/common/handlers/artifacthdlr/closure.go index 978515dbe..129a018a2 100644 --- a/cmds/ocm/commands/ocicmds/common/handlers/artifacthdlr/closure.go +++ b/cmds/ocm/commands/ocicmds/common/handlers/artifacthdlr/closure.go @@ -52,7 +52,7 @@ func traverse(hist common.History, o *Object, octx out.Context) []output.Object UniformRepositorySpec: o.Spec.UniformRepositorySpec, ArtSpec: oci.ArtSpec{ Repository: o.Spec.Repository, - Digest: &ref.Digest, + ArtVersion: oci.ArtVersion{Digest: &ref.Digest}, }, }, Namespace: o.Namespace, diff --git a/cmds/ocm/commands/ocicmds/common/handlers/artifacthdlr/typehandler.go b/cmds/ocm/commands/ocicmds/common/handlers/artifacthdlr/typehandler.go index aa8aa3480..5d027b3fd 100644 --- a/cmds/ocm/commands/ocicmds/common/handlers/artifacthdlr/typehandler.go +++ b/cmds/ocm/commands/ocicmds/common/handlers/artifacthdlr/typehandler.go @@ -192,7 +192,7 @@ func (h *TypeHandler) get(repo oci.Repository, elemspec utils.ElemSpec) ([]outpu return result, nil } } else { - art := oci.ArtSpec{Repository: ""} + art := &oci.ArtSpec{Repository: ""} if name != "" { art, err = oci.ParseArt(name) if err != nil {