From fc38402550d4ad17db7bac8a21f47f5ae8abf7ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Thu, 9 Jan 2025 14:42:52 +0100 Subject: [PATCH] fix(transfer): accidental extra identity defaulting during transfer (#1236) #### What this PR does / why we need it replaces https://github.com/open-component-model/ocm/pull/1223 as it does not contain the revert for the normalization algorithm Introduces DisableExtraIdentityDefaulting which is enabled by default during transport because IsModifyElement is not enough to differentiate if the component version is allowed to be modified during transfer. #### Which issue(s) this PR fixes PR that tackles a case in which `ocm transfer cv` caused accidental defaults to the extra identity. --------- Co-authored-by: Uwe Krueger --- api/ocm/cpi/modopts.go | 4 ++ api/ocm/cpi/repocpi/view_cv.go | 9 ++- api/ocm/internal/modopts.go | 34 ++++++++++ api/ocm/modopts.go | 5 ++ api/ocm/tools/transfer/transfer.go | 2 +- .../transferhandler/standard/compat_test.go | 64 ++++++++++++++++++ .../transferhandler/standard/handler.go | 4 +- .../testdata/v0.18.0/artifact-index.json | 1 + ...5753d17e2b6152ff31fbd07ff947b821f717f1232a | 1 + ...1777c3478d6513f786a591bd892da1a577bf2335f9 | 1 + ...ee6e61f6335ea5156d79aa98e733e1ed2393e0f649 | 1 + ...aa924fb236e977bfbc43309908aa9c45b154f689cd | 1 + ...7e903f449ad7b4a9ec9897f2084b982a66fcdbfb5f | Bin 0 -> 4608 bytes 13 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 api/ocm/tools/transfer/transferhandler/standard/compat_test.go create mode 100755 api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/artifact-index.json create mode 100644 api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.210dda6808d47862660fdf5753d17e2b6152ff31fbd07ff947b821f717f1232a create mode 100644 api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.916f0027a575074ce72a331777c3478d6513f786a591bd892da1a577bf2335f9 create mode 100644 api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.920ce99fb13b43ca0408caee6e61f6335ea5156d79aa98e733e1ed2393e0f649 create mode 100644 api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.958eb6b2928a569d7aaab2aa924fb236e977bfbc43309908aa9c45b154f689cd create mode 100644 api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.a4b84597729cfa026c51a47e903f449ad7b4a9ec9897f2084b982a66fcdbfb5f diff --git a/api/ocm/cpi/modopts.go b/api/ocm/cpi/modopts.go index ebdfeab00d..0679dc335b 100644 --- a/api/ocm/cpi/modopts.go +++ b/api/ocm/cpi/modopts.go @@ -35,6 +35,10 @@ func NewTargetElementOptions(list ...TargetElementOption) *TargetElementOptions return &m } +func DisableExtraIdentityDefaulting(flag ...bool) internal.TargetOptionImpl { + return internal.DisableExtraIdentityDefaulting(flag...) +} + //////////////////////////////////////////////////////////////////////////////// func NewAddVersionOptions(list ...AddVersionOption) *AddVersionOptions { diff --git a/api/ocm/cpi/repocpi/view_cv.go b/api/ocm/cpi/repocpi/view_cv.go index 2c36d65db8..fd44231e1b 100644 --- a/api/ocm/cpi/repocpi/view_cv.go +++ b/api/ocm/cpi/repocpi/view_cv.go @@ -468,7 +468,7 @@ func (c *componentVersionAccessView) SetResource(meta *cpi.ResourceMeta, acc com } else { cd.Resources[idx] = *res } - if opts.IsModifyElement() { + if opts.IsModifyElement() && !opts.IsDisableExtraIdentityDefaulting() { // default handling for completing an extra identity for modifications, only. compdesc.DefaultResources(cd) } @@ -527,6 +527,7 @@ func (c *componentVersionAccessView) SetSource(meta *cpi.SourceMeta, acc compdes return accessio.ErrReadOnly } + opts := cpi.NewTargetElementOptions(optlist...) res := &compdesc.Source{ SourceMeta: *meta.Copy(), Access: acc, @@ -548,7 +549,9 @@ func (c *componentVersionAccessView) SetSource(meta *cpi.SourceMeta, acc compdes } else { cd.Sources[idx] = *res } - compdesc.DefaultSources(cd) + if !opts.IsDisableExtraIdentityDefaulting() { + compdesc.DefaultSources(cd) + } return c.bridge.Update(false) }) } @@ -584,7 +587,7 @@ func (c *componentVersionAccessView) SetReference(ref *cpi.ComponentReference, o cd.References[idx].Equivalent(ref) cd.References[idx] = *ref } - if opts.IsModifyElement(moddef) { + if opts.IsModifyElement(moddef) && !opts.IsDisableExtraIdentityDefaulting() { compdesc.DefaultReferences(cd) } return c.bridge.Update(false) diff --git a/api/ocm/internal/modopts.go b/api/ocm/internal/modopts.go index 3732c59434..df43fc40f3 100644 --- a/api/ocm/internal/modopts.go +++ b/api/ocm/internal/modopts.go @@ -108,6 +108,10 @@ type TargetOptionImpl interface { type TargetElementOptions struct { TargetElement TargetElement + + // DisableExtraIdentityDefaulting disables the implicit defaulting of the extraIdentity. + // A transfer operation must set this flag to preserve the normalizations. + DisableExtraIdentityDefaulting *bool } type TargetElementOption interface { @@ -128,6 +132,11 @@ func (m *TargetElementOptions) ApplyElementModificationOption(opts *ElementModif func (m *TargetElementOptions) ApplyTargetOption(opts *TargetElementOptions) { optionutils.Transfer(&opts.TargetElement, m.TargetElement) + optionutils.Transfer(&opts.DisableExtraIdentityDefaulting, m.DisableExtraIdentityDefaulting) +} + +func (m *TargetElementOptions) IsDisableExtraIdentityDefaulting() bool { + return utils.AsBool(m.DisableExtraIdentityDefaulting) } func (m *TargetElementOptions) ApplyTargetOptions(list ...TargetElementOption) *TargetElementOptions { @@ -355,6 +364,31 @@ func (m TargetIdentity) ApplyTargetOption(opts *TargetElementOptions) { //////////////////////////////////////////////////////////////////////////////// +type disableextraidentitydefaulting bool + +func (m disableextraidentitydefaulting) ApplyBlobModificationOption(opts *BlobModificationOptions) { + m.ApplyModificationOption(&opts.ModificationOptions) +} + +func (m disableextraidentitydefaulting) ApplyModificationOption(opts *ModificationOptions) { + m.ApplyTargetOption(&opts.TargetElementOptions) +} + +func (m disableextraidentitydefaulting) ApplyElementModificationOption(opts *ElementModificationOptions) { + m.ApplyTargetOption(&opts.TargetElementOptions) +} + +func (m disableextraidentitydefaulting) ApplyTargetOption(opts *TargetElementOptions) { + opts.DisableExtraIdentityDefaulting = utils.BoolP(m) +} + +// DisableExtraIdentityDefaulting disables the defaulting of the extra identity. +func DisableExtraIdentityDefaulting(flag ...bool) TargetOptionImpl { + return disableextraidentitydefaulting(utils.OptionalDefaultedBool(true, flag...)) +} + +//////////////////////////////////////////////////////////////////////////////// + type replaceElement struct{} var UpdateElement = replaceElement{} diff --git a/api/ocm/modopts.go b/api/ocm/modopts.go index a980ae0485..5d0fb9dedf 100644 --- a/api/ocm/modopts.go +++ b/api/ocm/modopts.go @@ -66,6 +66,11 @@ func TargetIndex(idx int) internal.TargetOptionImpl { return internal.TargetIndex(idx) } +// DisableExtraIdentityDefaulting disables the defaulting of the extra identity +func DisableExtraIdentityDefaulting(flag ...bool) internal.TargetOptionImpl { + return internal.DisableExtraIdentityDefaulting(flag...) +} + const AppendElement = internal.TargetIndex(-1) var UpdateElement = internal.UpdateElement diff --git a/api/ocm/tools/transfer/transfer.go b/api/ocm/tools/transfer/transfer.go index ad6121728e..8d66870009 100644 --- a/api/ocm/tools/transfer/transfer.go +++ b/api/ocm/tools/transfer/transfer.go @@ -273,7 +273,7 @@ func copyVersion(printer common.Printer, log logging.Logger, hist common.History err = handler.HandleTransferResource(r, m, hint, t) } else { if err == nil { // old resource found -> keep current access method - t.SetResource(r.Meta(), old.Access, ocm.ModifyElement(), ocm.SkipVerify()) + t.SetResource(r.Meta(), old.Access, ocm.ModifyElement(), ocm.SkipVerify(), ocm.DisableExtraIdentityDefaulting()) } notifyArtifactInfo(printer, log, "resource", i, r.Meta(), hint, "already present") } diff --git a/api/ocm/tools/transfer/transferhandler/standard/compat_test.go b/api/ocm/tools/transfer/transferhandler/standard/compat_test.go new file mode 100644 index 0000000000..efb06e6d97 --- /dev/null +++ b/api/ocm/tools/transfer/transferhandler/standard/compat_test.go @@ -0,0 +1,64 @@ +package standard_test + +import ( + . "github.com/mandelsoft/goutils/testutils" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "ocm.software/ocm/cmds/ocm/testhelper" + + "ocm.software/ocm/api/ocm/extensions/repositories/ctf" + "ocm.software/ocm/api/ocm/tools/transfer" + "ocm.software/ocm/api/utils/accessio" + "ocm.software/ocm/api/utils/accessobj" + common "ocm.software/ocm/api/utils/misc" +) + +const COMPAT_ARCH = "/testdata/v0.18.0" +const COMPAT_COMP = "github.com/mandelsoft/test1" +const COMPAT_VERS = "1.0.0" + +var _ = Describe("Transfer Test Environment", func() { + Context("extraid compatibility transfer", func() { + + var env *TestEnv + + BeforeEach(func() { + env = NewTestEnv(TestData()) + }) + + It("", func() { + src := Must(ctf.Open(env.OCMContext(), accessobj.ACC_READONLY, COMPAT_ARCH, 0, env)) + defer Close(src, "source") + cv := Must(src.LookupComponentVersion(COMPAT_COMP, COMPAT_VERS)) + defer Close(cv, "source cv") + tgt := Must(ctf.Create(env.OCMContext(), accessobj.ACC_WRITABLE|accessobj.ACC_CREATE, OUT, 0o700, accessio.FormatDirectory, env)) + defer Close(tgt, "target") + + p, buf := common.NewBufferedPrinter() + MustBeSuccessful(transfer.Transfer(cv, tgt, transfer.WithPrinter(p))) + Expect(env.DirExists(OUT)).To(BeTrue()) + + Expect(buf.String()).To(StringEqualTrimmedWithContext(` +transferring version "github.com/mandelsoft/test1:1.0.0"... +...resource 0 multi-implicit[plainText]... +...resource 1 multi-implicit[plainText]... +...resource 2 multi-explicit[plainText]... +...resource 3 multi-explicit[plainText]... +...source 0 multi-implicit[plainText]... +...source 1 multi-implicit[plainText]... +...source 2 multi-explicit[plainText]... +...source 3 multi-explicit[plainText]... +...adding component version... +`)) + + tcv := Must(tgt.LookupComponentVersion(COMPAT_COMP, COMPAT_VERS)) + defer Close(tcv, "target cv") + Expect(tcv.GetDescriptor()).To(YAMLEqual(cv.GetDescriptor())) + + Expect(tcv.GetDescriptor().Resources[0].ExtraIdentity).To(BeNil()) + Expect(tcv.GetDescriptor().Resources[1].ExtraIdentity).To(BeNil()) + Expect(tcv.GetDescriptor().Sources[0].ExtraIdentity).To(BeNil()) + Expect(tcv.GetDescriptor().Sources[1].ExtraIdentity).To(BeNil()) + }) + }) +}) diff --git a/api/ocm/tools/transfer/transferhandler/standard/handler.go b/api/ocm/tools/transfer/transferhandler/standard/handler.go index 5792f2cd2e..0f8f7cf6b9 100644 --- a/api/ocm/tools/transfer/transferhandler/standard/handler.go +++ b/api/ocm/tools/transfer/transferhandler/standard/handler.go @@ -87,7 +87,7 @@ func (h *Handler) HandleTransferResource(r ocm.ResourceAccess, m cpi.AccessMetho } defer blob.Close() return accessio.Retry(h.opts.GetRetries(), time.Second, func() error { - return t.SetResourceBlob(r.Meta(), blob, hint, h.GlobalAccess(t.GetContext(), m), ocm.SkipVerify()) + return t.SetResourceBlob(r.Meta(), blob, hint, h.GlobalAccess(t.GetContext(), m), ocm.SkipVerify(), ocm.DisableExtraIdentityDefaulting()) }) } @@ -98,7 +98,7 @@ func (h *Handler) HandleTransferSource(r ocm.SourceAccess, m cpi.AccessMethod, h } defer blob.Close() return accessio.Retry(h.opts.GetRetries(), time.Second, func() error { - return t.SetSourceBlob(r.Meta(), blob, hint, h.GlobalAccess(t.GetContext(), m)) + return t.SetSourceBlob(r.Meta(), blob, hint, h.GlobalAccess(t.GetContext(), m), ocm.DisableExtraIdentityDefaulting()) }) } diff --git a/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/artifact-index.json b/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/artifact-index.json new file mode 100755 index 0000000000..8aaca543b3 --- /dev/null +++ b/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/artifact-index.json @@ -0,0 +1 @@ +{"schemaVersion":1,"artifacts":[{"repository":"component-descriptors/github.com/mandelsoft/test1","tag":"1.0.0","digest":"sha256:210dda6808d47862660fdf5753d17e2b6152ff31fbd07ff947b821f717f1232a"}]} \ No newline at end of file diff --git a/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.210dda6808d47862660fdf5753d17e2b6152ff31fbd07ff947b821f717f1232a b/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.210dda6808d47862660fdf5753d17e2b6152ff31fbd07ff947b821f717f1232a new file mode 100644 index 0000000000..59dcbdde0a --- /dev/null +++ b/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.210dda6808d47862660fdf5753d17e2b6152ff31fbd07ff947b821f717f1232a @@ -0,0 +1 @@ +{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.ocm.software.component.config.v1+json","digest":"sha256:958eb6b2928a569d7aaab2aa924fb236e977bfbc43309908aa9c45b154f689cd","size":201},"layers":[{"mediaType":"application/vnd.ocm.software.component-descriptor.v2+yaml+tar","digest":"sha256:a4b84597729cfa026c51a47e903f449ad7b4a9ec9897f2084b982a66fcdbfb5f","size":4608},{"mediaType":"application/octet-stream","digest":"sha256:916f0027a575074ce72a331777c3478d6513f786a591bd892da1a577bf2335f9","size":9,"annotations":{"software.ocm.artifact":"[{\"kind\":\"resource\",\"identity\":{\"name\":\"multi-implicit\",\"version\":\"v1\"}},{\"kind\":\"resource\",\"identity\":{\"name\":\"multi-explicit\",\"version\":\"v1\"}},{\"kind\":\"source\",\"identity\":{\"name\":\"multi-implicit\",\"version\":\"v1\"}},{\"kind\":\"source\",\"identity\":{\"name\":\"multi-explicit\",\"version\":\"v1\"}}]"}},{"mediaType":"application/octet-stream","digest":"sha256:920ce99fb13b43ca0408caee6e61f6335ea5156d79aa98e733e1ed2393e0f649","size":18,"annotations":{"software.ocm.artifact":"[{\"kind\":\"resource\",\"identity\":{\"name\":\"multi-implicit\",\"version\":\"v2\"}},{\"kind\":\"resource\",\"identity\":{\"name\":\"multi-explicit\",\"version\":\"v2\"}},{\"kind\":\"source\",\"identity\":{\"name\":\"multi-implicit\",\"version\":\"v2\"}},{\"kind\":\"source\",\"identity\":{\"name\":\"multi-explicit\",\"version\":\"v2\"}}]"}}],"annotations":{"software.ocm.componentversion":"github.com/mandelsoft/test1:1.0.0","software.ocm.creator":"OCM Go Library 0.18.0"}} \ No newline at end of file diff --git a/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.916f0027a575074ce72a331777c3478d6513f786a591bd892da1a577bf2335f9 b/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.916f0027a575074ce72a331777c3478d6513f786a591bd892da1a577bf2335f9 new file mode 100644 index 0000000000..0aa6fb5467 --- /dev/null +++ b/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.916f0027a575074ce72a331777c3478d6513f786a591bd892da1a577bf2335f9 @@ -0,0 +1 @@ +test data \ No newline at end of file diff --git a/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.920ce99fb13b43ca0408caee6e61f6335ea5156d79aa98e733e1ed2393e0f649 b/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.920ce99fb13b43ca0408caee6e61f6335ea5156d79aa98e733e1ed2393e0f649 new file mode 100644 index 0000000000..8173e28754 --- /dev/null +++ b/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.920ce99fb13b43ca0408caee6e61f6335ea5156d79aa98e733e1ed2393e0f649 @@ -0,0 +1 @@ +extended test data \ No newline at end of file diff --git a/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.958eb6b2928a569d7aaab2aa924fb236e977bfbc43309908aa9c45b154f689cd b/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.958eb6b2928a569d7aaab2aa924fb236e977bfbc43309908aa9c45b154f689cd new file mode 100644 index 0000000000..c3142a4ab0 --- /dev/null +++ b/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.958eb6b2928a569d7aaab2aa924fb236e977bfbc43309908aa9c45b154f689cd @@ -0,0 +1 @@ +{"componentDescriptorLayer":{"mediaType":"application/vnd.ocm.software.component-descriptor.v2+yaml+tar","digest":"sha256:a4b84597729cfa026c51a47e903f449ad7b4a9ec9897f2084b982a66fcdbfb5f","size":4608}} \ No newline at end of file diff --git a/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.a4b84597729cfa026c51a47e903f449ad7b4a9ec9897f2084b982a66fcdbfb5f b/api/ocm/tools/transfer/transferhandler/standard/testdata/v0.18.0/blobs/sha256.a4b84597729cfa026c51a47e903f449ad7b4a9ec9897f2084b982a66fcdbfb5f new file mode 100644 index 0000000000000000000000000000000000000000..29fedc243f8689c3df4a402413ea49266a640d79 GIT binary patch literal 4608 zcmeHKO^@0z5aqnTBHDYvA8|}_+qQ@H+M*s>^)NUSu$07+ZP4=XYlnsIu0)|#q!laX zLgJZ>-@KO@2W8scblCZ{LZ__my|L3Bw9RBZBYT^i_!YU}6PnSSOPb|`ObE?5;gf`n z2jO(4jq_jww9^rnd0rQH*;8*Gr4IU+cS&-*`HD4K>=e2(`S~k)EP~gjTj&fQo3+qY*f>-BnMdboi0Q4_>I!X{{Bcf=T?LoL z-Z&lJz}-jFd3^MT?JYX9u@O#)N)u4wa=1={HAX>mL|i6r4NT-^LGzjrCP7F+WTsFu z;G9Y+70=|n$_3@MoaZ14x~%2}tAK`BxvUxIqAtQt(ORrDEOvdU3;Mp%YT#jJlt-UB zA9!h>BK;6Fp!v|4<*-`mRVX{6j!|q8GOumeo_X>2-yhGpcrn7>m*i)-I5PzP&P9Cqcrwr_nUcE}J;X!9 asWrCn{rFME?%w>r!VSQUfg1zwi-F(j9+$)b literal 0 HcmV?d00001