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

annotate oci layers with component information #882

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package genericocireg_test

import (
. "github.com/mandelsoft/goutils/testutils"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
. "ocm.software/ocm/api/helper/builder"

"ocm.software/ocm/api/oci/extensions/repositories/ctf"
metav1 "ocm.software/ocm/api/ocm/compdesc/meta/v1"
resourcetypes "ocm.software/ocm/api/ocm/extensions/artifacttypes"
"ocm.software/ocm/api/utils/accessio"
"ocm.software/ocm/api/utils/accessobj"
"ocm.software/ocm/api/utils/mime"
)

const (
ARCH = "/tmp/ctf"
PROVIDER = "mandelsoft"
VERSION = "v1"
TEST_CONTENT1 = "this is a test"
TEST_CONTENT2 = "this is another test"
)

var _ = Describe("Transfer handler", func() {
var env *Builder

BeforeEach(func() {
env = NewBuilder()

env.OCMCommonTransport(ARCH, accessio.FormatDirectory, func() {
env.Component(COMPONENT, func() {
env.Version(VERSION, func() {
env.Provider(PROVIDER)
env.Resource("test1", "", resourcetypes.PLAIN_TEXT, metav1.LocalRelation, func() {
env.BlobStringData(mime.MIME_TEXT, TEST_CONTENT1)
})
env.Resource("test2", "", resourcetypes.PLAIN_TEXT, metav1.LocalRelation, func() {
env.BlobStringData(mime.MIME_TEXT, TEST_CONTENT1)
})
env.Resource("test3", "", resourcetypes.PLAIN_TEXT, metav1.LocalRelation, func() {
env.BlobStringData(mime.MIME_TEXT, TEST_CONTENT2)
})
env.Source("test4", "", resourcetypes.PLAIN_TEXT, func() {
env.BlobStringData(mime.MIME_TEXT, TEST_CONTENT2)
})
})
})
})
})

AfterEach(func() {
env.Cleanup()
})

It("check expected oci layer annotation", func() {
arch := Must(ctf.Open(env, accessobj.ACC_READONLY, ARCH, 0, env))
defer Close(arch)
c := Must(arch.LookupNamespace("component-descriptors/" + COMPONENT))
defer Close(c)
v := Must(c.GetArtifact(VERSION))
defer Close(v)
Expect(v.GetDescriptor()).To(YAMLEqual(`
mediaType: application/vnd.oci.image.manifest.v1+json
schemaVersion: 2
config:
digest: sha256:edf034a303e8cc7e5a05c522bb5fc74a09a00ed3aca390ffafba1020c97470cc
mediaType: application/vnd.ocm.software.component.config.v1+json
size: 201
layers:
- digest: sha256:43d7113c5e6dd84c617477c5713368cffb86b059808df176bbf3e02849ea6b3e
mediaType: application/vnd.ocm.software.component-descriptor.v2+yaml+tar
size: 3584
- annotations:
ocm-artifact: '[{"kind":"resource","identity":{"name":"test1"}},{"kind":"resource","identity":{"name":"test2"}}]'
digest: sha256:2e99758548972a8e8822ad47fa1017ff72f06f3ff6a016851f45c398732bc50c
mediaType: text/plain
size: 14
- annotations:
ocm-artifact: '[{"kind":"resource","identity":{"name":"test3"}},{"kind":"source","identity":{"name":"test4"}}]'
digest: sha256:f69bff44070ba35d7169196ba0095425979d96346a31486b507b4a3f77bd356d
mediaType: text/plain
size: 20
`))
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"ocm.software/ocm/api/oci/artdesc"
"ocm.software/ocm/api/oci/extensions/repositories/artifactset"
"ocm.software/ocm/api/ocm/compdesc"
metav1 "ocm.software/ocm/api/ocm/compdesc/meta/v1"
"ocm.software/ocm/api/ocm/cpi"
"ocm.software/ocm/api/ocm/cpi/accspeccpi"
"ocm.software/ocm/api/ocm/cpi/repocpi"
Expand All @@ -27,6 +28,7 @@ import (
"ocm.software/ocm/api/utils/errkind"
common "ocm.software/ocm/api/utils/misc"
"ocm.software/ocm/api/utils/refmgmt"
"ocm.software/ocm/api/utils/runtime"
)

// newComponentVersionAccess creates a component access for the artifact access, if this fails the artifact acess is closed.
Expand Down Expand Up @@ -147,6 +149,20 @@ func (c *ComponentVersionContainer) SetDescriptor(cd *compdesc.ComponentDescript
return c.Update()
}

type LayerAnnotations []ArtifactInfo

type ArtifactInfo struct {
// Kind specifies whether the artifact is a source, resource or a label
Kind string `json:"kind"`
Identity metav1.Identity `json:"identity"`
}

const (
ARTKIND_RESOURCE = "resource"
ARTKIND_SOURCE = "source"
OCM_ARTIFACT = "ocm-artifact"
)

func (c *ComponentVersionContainer) Update() error {
logger := Logger(c.GetContext()).WithValues("cv", common.NewNameVersion(c.comp.name, c.version))
err := c.Check()
Expand All @@ -155,6 +171,8 @@ func (c *ComponentVersionContainer) Update() error {
}

if c.state.HasChanged() {
layerAnnotations := map[int]LayerAnnotations{}

logger.Debug("update component version")
desc := c.GetDescriptor()
layers := set.Set[int]{}
Expand All @@ -167,6 +185,10 @@ func (c *ComponentVersionContainer) Update() error {
return fmt.Errorf("failed resource layer evaluation: %w", err)
}
if l > 0 {
layerAnnotations[l] = append(layerAnnotations[l], ArtifactInfo{
Kind: ARTKIND_RESOURCE,
Identity: r.GetIdentity(desc.Resources),
})
layers.Delete(l)
}
if s != r.Access {
Expand All @@ -179,13 +201,28 @@ func (c *ComponentVersionContainer) Update() error {
return fmt.Errorf("failed source layer evaluation: %w", err)
}
if l > 0 {
layerAnnotations[l] = append(layerAnnotations[l], ArtifactInfo{
Kind: ARTKIND_SOURCE,
Identity: r.GetIdentity(desc.Sources),
})
layers.Delete(l)
}
if s != r.Access {
desc.Sources[i].Access = s
}
}
m := c.manifest.GetDescriptor()

for layer, info := range layerAnnotations {
data, err := runtime.DefaultJSONEncoding.Marshal(info)
if err != nil {
return err
}
if m.Layers[layer].Annotations == nil {
m.Layers[layer].Annotations = map[string]string{}
}
m.Layers[layer].Annotations[OCM_ARTIFACT] = string(data)
}
i := len(m.Layers) - 1

for i > 0 {
Expand Down
2 changes: 1 addition & 1 deletion api/ocm/resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
. "ocm.software/ocm/api/helper/builder"
"ocm.software/ocm/api/ocm/internal"

"ocm.software/ocm/api/ocm"
"ocm.software/ocm/api/ocm/extensions/repositories/ctf"
"ocm.software/ocm/api/ocm/extensions/repositories/ocireg"
"ocm.software/ocm/api/ocm/internal"
"ocm.software/ocm/api/utils/accessio"
"ocm.software/ocm/api/utils/accessobj"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ import (
"ocm.software/ocm/api/utils/accessobj"
)

const ARCH = "ctf"
const COMP = "acme.org/comp1"
const VERS1 = "1.0.0"
const VERS2 = "2.0.0"
const (
ARCH = "ctf"
COMP = "acme.org/comp1"
VERS1 = "1.0.0"
VERS2 = "2.0.0"
)

var _ = Describe("version handler", func() {

var env *TestEnv

BeforeEach(func() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package npm_test
import (
. "github.com/onsi/ginkgo/v2"
. "ocm.software/ocm/cmds/ocm/commands/ocmcmds/common/inputs/testutils"
"ocm.software/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/npm"

"ocm.software/ocm/cmds/ocm/commands/ocmcmds/common/inputs"
"ocm.software/ocm/cmds/ocm/commands/ocmcmds/common/inputs/options"
"ocm.software/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/npm"
)

var _ = Describe("Input Type", func() {
Expand Down
Loading