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

Repository context of subinstallations #1147

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
2 changes: 0 additions & 2 deletions pkg/components/components_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,6 @@ var _ = Describe("facade implementation compatibility tests", func() {

Expect(oRaForCnudieCv.GetComponentDescriptor()).To(Equal(oRaForOcmCv.GetComponentDescriptor()))

Expect(oRaForCnudieCv.GetRepositoryContext()).To(Equal(oRaForOcmCv.GetRepositoryContext()))

Expect(oRaForCnudieCv.GetComponentReferences()).To(Equal(oRaForOcmCv.GetComponentReferences()))

Expect(oRaForCnudieCv.GetComponentReference(REFERENCED_COMPONENT_NAME)).To(Equal(oRaForOcmCv.GetComponentReference(REFERENCED_COMPONENT_NAME)))
Expand Down
8 changes: 0 additions & 8 deletions pkg/components/model/componentversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,6 @@ type ComponentVersion interface {
// Cannot be nil
GetComponentDescriptor() *types.ComponentDescriptor

// GetRepositoryContext return the current repository context,
// i.e. the last entry in the list of repository contexts.
// TODO: Remove this method
// ocm-spec specifies that the Repository Context is supposed to be informational about the transport history. The
// spec does not mandate to set this property and therefore, we should not program against it.
// Cannot be nil as component versions without repository context cannot be created (for now).
GetRepositoryContext() *types.UnstructuredTypedObject

// GetComponentReferences returns the list of component references of the present component version.
// (not transitively; only the references of the present component version)
GetComponentReferences() []types.ComponentReference
Expand Down
6 changes: 0 additions & 6 deletions pkg/components/model/componentversion_refs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package model

import (
"context"
"errors"
"fmt"

"github.com/gardener/landscaper/controller-utils/pkg/logging"
Expand Down Expand Up @@ -75,11 +74,6 @@ func getTransitiveComponentReferencesRecursively(ctx context.Context,
}
cds[cid] = cd

cdRepositoryContext := cd.GetRepositoryContext()
if cdRepositoryContext == nil {
return errors.New("component descriptor must at least contain one repository context with a base url")
}

cdComponentReferences := cd.GetComponentReferences()

for _, compRef := range cdComponentReferences {
Expand Down
4 changes: 0 additions & 4 deletions pkg/components/ocmlib/componentversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ func (c *ComponentVersion) GetComponentDescriptor() *types.ComponentDescriptor {
return &c.componentDescriptorV2
}

func (c *ComponentVersion) GetRepositoryContext() *types.UnstructuredTypedObject {
return c.componentDescriptorV2.GetEffectiveRepositoryContext()
}

func (c *ComponentVersion) GetComponentReferences() []types.ComponentReference {
return c.componentDescriptorV2.ComponentReferences
}
Expand Down
8 changes: 0 additions & 8 deletions pkg/components/testutils/componentversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,6 @@ func (t *TestComponentVersion) GetComponentDescriptor() *types.ComponentDescript
return t.componentDescriptor
}

func (t *TestComponentVersion) GetRepositoryContext() *types.UnstructuredTypedObject {
context := t.componentDescriptor.GetEffectiveRepositoryContext()
if context == nil {
return nil
}
return context
}

func (t *TestComponentVersion) GetComponentReferences() []types.ComponentReference {
return t.componentDescriptor.ComponentReferences
}
Expand Down
3 changes: 0 additions & 3 deletions pkg/landscaper/blueprints/resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,6 @@ func Resolve(
if cdRef == nil {
return nil, fmt.Errorf("no component descriptor reference defined")
}
if cdRef.RepositoryContext == nil {
return nil, fmt.Errorf("no respository context defined")
}
if registryAccess == nil {
return nil, fmt.Errorf("did not get a working component descriptor resolver")
}
Expand Down
41 changes: 17 additions & 24 deletions pkg/landscaper/installations/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,18 @@ import (
"errors"
"fmt"

"github.com/gardener/landscaper/pkg/utils"

cdv2 "github.com/gardener/component-spec/bindings-go/apis/v2"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"sigs.k8s.io/controller-runtime/pkg/client"

lsv1alpha1 "github.com/gardener/landscaper/apis/core/v1alpha1"
lsv1alpha1helper "github.com/gardener/landscaper/apis/core/v1alpha1/helper"
lserrors "github.com/gardener/landscaper/apis/errors"
kutil "github.com/gardener/landscaper/controller-utils/pkg/kubernetes"
"github.com/gardener/landscaper/controller-utils/pkg/logging"
"github.com/gardener/landscaper/pkg/components/model/componentoverwrites"

lsv1alpha1 "github.com/gardener/landscaper/apis/core/v1alpha1"
lsv1alpha1helper "github.com/gardener/landscaper/apis/core/v1alpha1/helper"
lc "github.com/gardener/landscaper/controller-utils/pkg/logging/constants"
"github.com/gardener/landscaper/pkg/components/model/componentoverwrites"
"github.com/gardener/landscaper/pkg/utils"
"github.com/gardener/landscaper/pkg/utils/read_write_layer"
)

Expand Down Expand Up @@ -133,6 +132,9 @@ type ExternalContext struct {
ComponentName string
// ComponentVersion defines the version of the component.
ComponentVersion string
// ResultingRepositoryContext is the repository context, taking into account the repository context in the
// installation, the repository context in the context resource, and the overwriter.
ResultingRepositoryContext *cdv2.UnstructuredTypedObject
// Overwriter is the component version overwriter used for this installation.
Overwriter componentoverwrites.Overwriter
}
Expand All @@ -143,7 +145,7 @@ func (c *ExternalContext) ComponentDescriptorRef() *lsv1alpha1.ComponentDescript
return nil
}
ref := &lsv1alpha1.ComponentDescriptorReference{}
ref.RepositoryContext = c.RepositoryContext
ref.RepositoryContext = c.ResultingRepositoryContext
ref.ComponentName = c.ComponentName
ref.Version = c.ComponentVersion
return ref
Expand Down Expand Up @@ -232,15 +234,6 @@ func GetParent(ctx context.Context, kubeClient client.Client, inst *lsv1alpha1.I
return parent, nil
}

// GetInstallationContextName returns the name of the context of an installation.
// The context name is basically the name of the parent component.
func GetInstallationContextName(inst *lsv1alpha1.Installation) string {
if IsRootInstallation(inst) {
return ""
}
return lsv1alpha1helper.DataObjectSourceFromInstallationName(GetParentInstallationName(inst))
}

// IsRoot returns if the current component is a root component
func (o *Operation) IsRoot() bool {
return o.Context().Parent == nil
Expand Down Expand Up @@ -287,6 +280,9 @@ func GetExternalContext(ctx context.Context, kubeClient client.Client, inst *lsv
}, nil
}

// Avoid that component overwrite modifies the installation
cdRef = cdRef.DeepCopy()

cond, err := ApplyComponentOverwrite(ctx, inst, overwriter, lsCtx, cdRef)
if err != nil {
return ExternalContext{}, lserrors.NewWrappedError(err,
Expand All @@ -295,15 +291,12 @@ func GetExternalContext(ctx context.Context, kubeClient client.Client, inst *lsv
if cond != nil {
inst.Status.Conditions = lsv1alpha1helper.MergeConditions(inst.Status.Conditions, *cond)
}
if cdRef.RepositoryContext == nil {
return ExternalContext{}, MissingRepositoryContextError
}
lsCtx.RepositoryContext = cdRef.RepositoryContext
return ExternalContext{
Context: *lsCtx,
ComponentName: cdRef.ComponentName,
ComponentVersion: cdRef.Version,
Overwriter: overwriter,
Context: *lsCtx,
ComponentName: cdRef.ComponentName,
ComponentVersion: cdRef.Version,
ResultingRepositoryContext: cdRef.RepositoryContext,
Overwriter: overwriter,
}, nil
}

Expand Down
74 changes: 22 additions & 52 deletions pkg/landscaper/installations/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,22 @@ package installations_test
import (
"context"

testutils2 "github.com/gardener/landscaper/pkg/components/testutils"

"github.com/open-component-model/ocm/pkg/contexts/datacontext"
"github.com/open-component-model/ocm/pkg/contexts/ocm"

"github.com/gardener/landscaper/controller-utils/pkg/logging"

"github.com/gardener/landscaper/apis/config"

cdv2 "github.com/gardener/component-spec/bindings-go/apis/v2"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gstruct"
"github.com/open-component-model/ocm/pkg/contexts/datacontext"
"github.com/open-component-model/ocm/pkg/contexts/ocm"
"k8s.io/client-go/tools/record"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/gardener/landscaper/apis/config"
lsv1alpha1 "github.com/gardener/landscaper/apis/core/v1alpha1"
"github.com/gardener/landscaper/controller-utils/pkg/logging"
"github.com/gardener/landscaper/pkg/api"
"github.com/gardener/landscaper/pkg/components/model/componentoverwrites"
"github.com/gardener/landscaper/pkg/components/registries"
testutils2 "github.com/gardener/landscaper/pkg/components/testutils"
"github.com/gardener/landscaper/pkg/landscaper/installations"
lsoperation "github.com/gardener/landscaper/pkg/landscaper/operation"
testutils "github.com/gardener/landscaper/test/utils"
Expand Down Expand Up @@ -175,29 +171,7 @@ var _ = Describe("Context", func() {
extCtx, err := installations.GetExternalContext(ctx, testenv.Client, inst)
Expect(err).ToNot(HaveOccurred())
Expect(inst.Spec.ComponentDescriptor.Reference.RepositoryContext.Raw).To(MatchJSON(repoCtx.Raw))
Expect(extCtx.RepositoryContext.Raw).To(MatchJSON(repoCtx.Raw))
})

It("should throw an error if a component name and version is defined but no repository context", func() {
state, err := testenv.InitState(ctx)
Expect(err).ToNot(HaveOccurred())

lsCtx := &lsv1alpha1.Context{}
lsCtx.Name = "test"
lsCtx.Namespace = state.Namespace
Expect(state.Create(ctx, lsCtx)).To(Succeed())

inst := &lsv1alpha1.Installation{}
inst.Namespace = state.Namespace
inst.Spec.Context = "test"
inst.Spec.ComponentDescriptor = &lsv1alpha1.ComponentDescriptorDefinition{
Reference: &lsv1alpha1.ComponentDescriptorReference{
ComponentName: "abc",
},
}

_, err = installations.GetExternalContext(ctx, testenv.Client, inst)
Expect(err).To(HaveOccurred())
Expect(extCtx.ResultingRepositoryContext.Raw).To(MatchJSON(repoCtx.Raw))
})

Context("ComponentVersionOverwrite", func() {
Expand Down Expand Up @@ -243,8 +217,10 @@ var _ = Describe("Context", func() {

extCtx, err := installations.GetExternalContext(ctx, testenv.Client, inst)
Expect(err).ToNot(HaveOccurred())
Expect(cdv2.UnstructuredTypesEqual(inst.Spec.ComponentDescriptor.Reference.RepositoryContext, repoCtx)).To(BeTrue())
Expect(cdv2.UnstructuredTypesEqual(extCtx.RepositoryContext, repoCtx)).To(BeTrue())
// the installation should remain unchanged
Expect(cdv2.UnstructuredTypesEqual(inst.Spec.ComponentDescriptor.Reference.RepositoryContext, testutils.ExampleRepositoryContext())).To(BeTrue())
// the resulting repository context should contain the result of the overwriting
Expect(cdv2.UnstructuredTypesEqual(extCtx.ResultingRepositoryContext, repoCtx)).To(BeTrue())
})

It("should overwrite a repository context defined by the external context", func() {
Expand Down Expand Up @@ -288,8 +264,10 @@ var _ = Describe("Context", func() {

extCtx, err := installations.GetExternalContext(ctx, testenv.Client, inst)
Expect(err).ToNot(HaveOccurred())
Expect(cdv2.UnstructuredTypesEqual(inst.Spec.ComponentDescriptor.Reference.RepositoryContext, repoCtx)).To(BeTrue())
Expect(cdv2.UnstructuredTypesEqual(extCtx.RepositoryContext, repoCtx)).To(BeTrue())
// the installation should remain unchanged
Expect(inst.Spec.ComponentDescriptor.Reference.RepositoryContext).To(BeNil())
// the resulting repository context should contain the result of the overwriting
Expect(cdv2.UnstructuredTypesEqual(extCtx.ResultingRepositoryContext, repoCtx)).To(BeTrue())
})
})

Expand All @@ -315,34 +293,26 @@ var _ = Describe("Context", func() {
Context("InjectComponentDescriptorRef", func() {
It("should inject the component ref", func() {
extCtx := installations.ExternalContext{
Context: lsv1alpha1.Context{
ContextConfiguration: lsv1alpha1.ContextConfiguration{
RepositoryContext: testutils.ExampleRepositoryContext(),
},
},
ComponentName: "example.com/a",
ComponentVersion: "0.0.1",
ResultingRepositoryContext: testutils.ExampleRepositoryContext(),
ComponentName: "example.com/a",
ComponentVersion: "0.0.1",
}

inst := &lsv1alpha1.Installation{}
extCtx.InjectComponentDescriptorRef(inst)
Expect(inst.Spec.ComponentDescriptor).ToNot(BeNil())
Expect(inst.Spec.ComponentDescriptor.Reference).To(gstruct.PointTo(gstruct.MatchAllFields(gstruct.Fields{
"RepositoryContext": Equal(extCtx.RepositoryContext),
"RepositoryContext": Equal(extCtx.ResultingRepositoryContext),
"ComponentName": Equal("example.com/a"),
"Version": Equal("0.0.1"),
})))
})

It("should overwrite the component ref", func() {
extCtx := installations.ExternalContext{
Context: lsv1alpha1.Context{
ContextConfiguration: lsv1alpha1.ContextConfiguration{
RepositoryContext: testutils.ExampleRepositoryContext(),
},
},
ComponentName: "example.com/a",
ComponentVersion: "0.0.1",
ResultingRepositoryContext: testutils.ExampleRepositoryContext(),
ComponentName: "example.com/a",
ComponentVersion: "0.0.1",
}

inst := &lsv1alpha1.Installation{}
Expand All @@ -355,7 +325,7 @@ var _ = Describe("Context", func() {
extCtx.InjectComponentDescriptorRef(inst)
Expect(inst.Spec.ComponentDescriptor).ToNot(BeNil())
Expect(inst.Spec.ComponentDescriptor.Reference).To(gstruct.PointTo(gstruct.MatchAllFields(gstruct.Fields{
"RepositoryContext": Equal(extCtx.RepositoryContext),
"RepositoryContext": Equal(extCtx.ResultingRepositoryContext),
"ComponentName": Equal("example.com/a"),
"Version": Equal("0.0.1"),
})))
Expand Down
2 changes: 1 addition & 1 deletion pkg/landscaper/installations/executions/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func (o *ExecutionOperation) RenderDeployItemTemplates(ctx context.Context,
executions, err := tmpl.TemplateDeployExecutions(
template.NewDeployExecutionOptions(
template.NewBlueprintExecutionOptions(
o.Context().External.InjectComponentDescriptorRef(inst.GetInstallation()),
o.Context().External.InjectComponentDescriptorRef(inst.GetInstallation().DeepCopy()),
inst.GetBlueprint(),
o.ComponentVersion,
o.ResolvedComponentDescriptorList,
Expand Down
10 changes: 3 additions & 7 deletions pkg/landscaper/installations/executions/operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,9 @@ var _ = Describe("Execution Operation", func() {
Name: "default",
Parent: nil,
External: installations.ExternalContext{
Context: lsv1alpha1.Context{
ContextConfiguration: lsv1alpha1.ContextConfiguration{
RepositoryContext: &repositoryContext,
},
},
ComponentName: "example.com/root",
ComponentVersion: "v1.0.0",
ResultingRepositoryContext: &repositoryContext,
ComponentName: "example.com/root",
ComponentVersion: "v1.0.0",
},
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/landscaper/installations/imports/constructor.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ func (c *Constructor) RenderImportExecutions() error {
spiff.New(templateStateHandler, targetResolver))
errors, bindings, err := tmpl.TemplateImportExecutions(
template.NewBlueprintExecutionOptions(
c.Operation.Context().External.InjectComponentDescriptorRef(c.Operation.Inst.GetInstallation()),
c.Operation.Context().External.InjectComponentDescriptorRef(c.Operation.Inst.GetInstallation().DeepCopy()),
c.Operation.Inst.GetBlueprint(),
c.Operation.ComponentVersion,
c.Operation.ResolvedComponentDescriptorList,
Expand Down
12 changes: 11 additions & 1 deletion pkg/landscaper/installations/subinstallations/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func GetBlueprintDefinitionFromInstallationTemplate(
}

// resolve component descriptor list
// TODO: why is the overwriter not relevant here?
_, res, err := uri.Get(componentVersion, repositoryContext)
if err != nil {
return nil, nil, fmt.Errorf("unable to resolve blueprint ref in component descriptor %s: %w", componentVersion.GetName(), err)
Expand Down Expand Up @@ -85,7 +86,16 @@ func GetBlueprintDefinitionFromInstallationTemplate(

if cdDef.Inline == nil {
cdDef = &lsv1alpha1.ComponentDescriptorDefinition{
Reference: subInstCdRef,
Reference: &lsv1alpha1.ComponentDescriptorReference{
ComponentName: subInstCdRef.ComponentName,
Version: subInstCdRef.Version,
},
}

// Usually, the repository context of the parent installation is specified in the context resource or ocm config.
// Only if it is specified directly in the parent installation, we specify the same repository context in the subinstallation.
if inst.Spec.ComponentDescriptor != nil && inst.Spec.ComponentDescriptor.Reference != nil {
cdDef.Reference.RepositoryContext = inst.Spec.ComponentDescriptor.Reference.RepositoryContext
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ func (o *Operation) createOrUpdateNewInstallation(ctx context.Context,
subBlueprint, subCdDef, err := GetBlueprintDefinitionFromInstallationTemplate(inst,
subInstTmpl,
o.ComponentVersion,
o.Context().External.RepositoryContext,
o.Context().External.ResultingRepositoryContext,
o.Context().External.Overwriter)
if err != nil {
return nil, err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,9 @@ var _ = Describe("SubInstallation", func() {
Expect(subinsts[0].Spec.ComponentDescriptor.Reference.ComponentName).To(Equal("example.com/root"))
Expect(subinsts[0].Spec.ComponentDescriptor.Reference.Version).To(Equal("1.0.0"))

Expect(subinsts[0].Spec.ComponentDescriptor.Reference.RepositoryContext.Object["baseUrl"]).To(Equal("./testdata/registry"))
Expect(subinsts[0].Spec.ComponentDescriptor.Reference.RepositoryContext.Object["type"]).To(Equal("ociRegistry"))
// expecting the same repository context as in the root installation
Expect(subinsts[0].Spec.ComponentDescriptor.Reference.RepositoryContext.Object["baseUrl"]).To(Equal("../testdata/registry"))
Expect(subinsts[0].Spec.ComponentDescriptor.Reference.RepositoryContext.Object["type"]).To(Equal("local"))

Expect(subinsts[0].Spec.Blueprint.Reference.ResourceName).To(Equal("def-1"))

Expand Down
Loading