This is an automated email from the ASF dual-hosted git repository.
astefanutti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
The following commit(s) were added to refs/heads/main by this push:
new c37f1f7 Make it possible to define the ocontainer image without
IntegrationKit
c37f1f7 is described below
commit c37f1f752cd61413d736a077220e067f0b89c39d
Author: Luca Burgazzoli <[email protected]>
AuthorDate: Fri Jun 4 14:55:14 2021 +0200
Make it possible to define the ocontainer image without IntegrationKit
---
pkg/controller/integration/initialize.go | 42 ++++----
pkg/controller/integrationkit/monitor.go | 5 +
pkg/resources/resources.go | 4 +-
pkg/trait/container.go | 54 ++++++++--
pkg/trait/container_test.go | 179 +++++++++++++++++++++++++++++++
5 files changed, 251 insertions(+), 33 deletions(-)
diff --git a/pkg/controller/integration/initialize.go
b/pkg/controller/integration/initialize.go
index 04a95b4..7a55d80 100644
--- a/pkg/controller/integration/initialize.go
+++ b/pkg/controller/integration/initialize.go
@@ -55,30 +55,32 @@ func (action *initializeAction) Handle(ctx context.Context,
integration *v1.Inte
return nil, err
}
- if integration.Spec.IntegrationKit == nil && integration.Spec.Kit != ""
{
- // TODO: temporary fallback until deprecated field gets removed
- integration.Spec.IntegrationKit = &corev1.ObjectReference{
- Name: integration.Spec.Kit,
+ if integration.Status.IntegrationKit == nil {
+ if integration.Spec.IntegrationKit == nil &&
integration.Spec.Kit != "" {
+ // TODO: temporary fallback until deprecated field gets
removed
+ integration.Spec.IntegrationKit =
&corev1.ObjectReference{
+ Name: integration.Spec.Kit,
+ }
}
- }
- if integration.Spec.IntegrationKit != nil &&
integration.Spec.IntegrationKit.Name != "" {
- kitNamespace := integration.Spec.IntegrationKit.Namespace
- kitName := integration.Spec.IntegrationKit.Name
-
- if kitNamespace == "" {
- pl, err := platform.GetCurrent(ctx, action.client,
integration.Namespace)
- if err != nil && !k8serrors.IsNotFound(err) {
- return nil, err
- }
- if pl != nil {
- kitNamespace = pl.Namespace
+ if integration.Spec.IntegrationKit != nil &&
integration.Spec.IntegrationKit.Name != "" {
+ kitNamespace :=
integration.Spec.IntegrationKit.Namespace
+ kitName := integration.Spec.IntegrationKit.Name
+
+ if kitNamespace == "" {
+ pl, err := platform.GetCurrent(ctx,
action.client, integration.Namespace)
+ if err != nil && !k8serrors.IsNotFound(err) {
+ return nil, err
+ }
+ if pl != nil {
+ kitNamespace = pl.Namespace
+ }
}
+ kit := v1.NewIntegrationKit(kitNamespace, kitName)
+ integration.SetIntegrationKit(&kit)
+ } else {
+ integration.Status.IntegrationKit = nil
}
- kit := v1.NewIntegrationKit(kitNamespace, kitName)
- integration.SetIntegrationKit(&kit)
- } else {
- integration.Status.IntegrationKit = nil
}
integration.Status.Phase = v1.IntegrationPhaseBuildingKit
diff --git a/pkg/controller/integrationkit/monitor.go
b/pkg/controller/integrationkit/monitor.go
index 84177b1..336a574 100644
--- a/pkg/controller/integrationkit/monitor.go
+++ b/pkg/controller/integrationkit/monitor.go
@@ -54,6 +54,11 @@ func (action *monitorAction) Handle(ctx context.Context, kit
*v1.IntegrationKit)
return kit, nil
}
+ if kit.Spec.Image != "" && kit.Spec.Image != kit.Status.Image {
+ kit.Status.Phase = v1.IntegrationKitPhaseInitialization
+
+ return kit, nil
+ }
return nil, nil
}
diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go
index ad5e8eb..1b7a486 100644
--- a/pkg/resources/resources.go
+++ b/pkg/resources/resources.go
@@ -467,9 +467,9 @@ var assets = func() http.FileSystem {
"/traits.yaml": &vfsgen۰CompressedFileInfo{
name: "traits.yaml",
modTime: time.Time{},
- uncompressedSize: 38748,
+ uncompressedSize: 38972,
- compressedContent:
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\x6d\x6f\x1c\x37\xd2\xe0\x77\xff\x0a\x42\xcf\x01\x7a\xc1\x4c\x4b\xce\x22\xbb\x39\xdd\xf9\x16\x8a\xed\xec\x2a\x89\x6d\x9d\xe5\xcd\xe2\xe0\x0b\x76\x38\xdd\x35\x33\xb4\xd8\x64\x2f\xc9\x96\x3c\x39\xdc\x7f\x3f\xb0\x8a\x6f\x3d\xd3\x92\x46\x4e\x14\x44\x87\x67\xf7\x43\x2c\xa9\xbb\x58\x2c\x16\xeb\xbd\xaa\x9d\xe1\xc2\xd9\xd3\x67\x53\xa6\x78\x0b\xa7\x8c\x2f\x16\x42\x09\xb7\x7e\xc6\x58\x27\xb9\x5b\x68\xd3\x9e\xb2\x05\x97\x
[...]
+ compressedContent:
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\x7b\x73\x1c\x37\xf2\xd8\xff\xfa\x14\x28\xfe\x52\xc5\x47\xed\x0e\x29\x5f\x7c\xe7\x30\x51\xae\x68\x49\xbe\xa3\x6d\x49\x8c\xa8\xf3\x55\x4a\x71\xdd\x62\x67\x7a\x77\x21\x62\x80\x39\x00\x43\x6a\x9d\xca\x77\x4f\xa1\x1b\xaf\xd9\x1d\x92\x4b\xd9\x74\x99\xa9\xdc\xfd\x61\x91\x9c\x69\x34\x1a\x8d\x7e\x77\x8f\x33\x5c\x38\x7b\xfa\x6c\xca\x14\x6f\xe1\x94\xf1\xc5\x42\x28\xe1\xd6\xcf\x18\xeb\x24\x77\x0b\x6d\xda\x53\xb6\xe0\xd2\x
[...]
},
}
fs["/"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
diff --git a/pkg/trait/container.go b/pkg/trait/container.go
index 11dcb61..65781bb 100644
--- a/pkg/trait/container.go
+++ b/pkg/trait/container.go
@@ -76,6 +76,8 @@ type containerTrait struct {
// The main container name. It's named `integration` by default.
Name string `property:"name" json:"name,omitempty"`
+ // The main container image
+ Image string `property:"image" json:"image,omitempty"`
// ProbesEnabled enable/disable probes on the container (default
`false`)
ProbesEnabled *bool `property:"probes-enabled"
json:"probesEnabled,omitempty"`
@@ -141,7 +143,7 @@ func (t *containerTrait) Configure(e *Environment) (bool,
error) {
func (t *containerTrait) Apply(e *Environment) error {
if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) {
- t.configureDependencies(e)
+ return t.configureDependencies(e)
}
if e.IntegrationInPhase(v1.IntegrationPhaseDeploying,
v1.IntegrationPhaseRunning) {
@@ -156,21 +158,51 @@ func (t *containerTrait) IsPlatformTrait() bool {
return true
}
-func (t *containerTrait) configureDependencies(e *Environment) {
- if util.IsNilOrFalse(t.ProbesEnabled) {
- return
- }
-
+func (t *containerTrait) configureDependencies(e *Environment) error {
if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) {
- if capability, ok :=
e.CamelCatalog.Runtime.Capabilities[v1.CapabilityHealth]; ok {
- for _, dependency := range capability.Dependencies {
-
util.StringSliceUniqueAdd(&e.Integration.Status.Dependencies,
dependency.GetDependencyID())
+ if t.Image != "" {
+ if e.Integration.Spec.IntegrationKit != nil {
+ return fmt.Errorf(
+ "unsupported configuration: a container
image has been set in conjunction with an IntegrationKit %v",
+ e.Integration.Spec.IntegrationKit)
+ }
+ if e.Integration.Spec.Kit != "" {
+ return fmt.Errorf(
+ "unsupported configuration: a container
image has been set in conjunction with an IntegrationKit %s",
+ e.Integration.Spec.Kit)
+ }
+
+ kitName := fmt.Sprintf("kit-%s", e.Integration.Name)
+ kit := v1.NewIntegrationKit(e.Integration.Namespace,
kitName)
+ kit.Spec.Image = t.Image
+
+ // Add some information for post-processing, this may
need to be refactored
+ // to a proper data structure
+ kit.Labels = map[string]string{
+ "camel.apache.org/kit.type":
v1.IntegrationKitTypeExternal,
+ "camel.apache.org/created.by.kind":
v1.IntegrationKind,
+ "camel.apache.org/created.by.name":
e.Integration.Name,
+ "camel.apache.org/created.by.namespace":
e.Integration.Namespace,
+ "camel.apache.org/created.by.version":
e.Integration.ResourceVersion,
}
- // sort the dependencies to get always the same list if
they don't change
- sort.Strings(e.Integration.Status.Dependencies)
+ t.L.Infof("image %s", kit.Spec.Image)
+ e.Resources.Add(&kit)
+ e.Integration.SetIntegrationKit(&kit)
+ }
+ if util.IsTrue(t.ProbesEnabled) {
+ if capability, ok :=
e.CamelCatalog.Runtime.Capabilities[v1.CapabilityHealth]; ok {
+ for _, dependency := range
capability.Dependencies {
+
util.StringSliceUniqueAdd(&e.Integration.Status.Dependencies,
dependency.GetDependencyID())
+ }
+
+ // sort the dependencies to get always the same
list if they don't change
+ sort.Strings(e.Integration.Status.Dependencies)
+ }
}
}
+
+ return nil
}
// nolint:gocyclo
diff --git a/pkg/trait/container_test.go b/pkg/trait/container_test.go
index a4610ee..9952aa8 100644
--- a/pkg/trait/container_test.go
+++ b/pkg/trait/container_test.go
@@ -19,12 +19,15 @@ package trait
import (
"context"
+ "github.com/google/uuid"
+ "k8s.io/apimachinery/pkg/types"
"testing"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ ctrl "sigs.k8s.io/controller-runtime/pkg/client"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
"github.com/apache/camel-k/pkg/util/camel"
@@ -148,3 +151,179 @@ func TestContainerWithCustomName(t *testing.T) {
trait := test.TraitSpecToMap(t,
environment.Integration.Spec.Traits["container"])
assert.Equal(t, trait["name"], d.Spec.Template.Spec.Containers[0].Name)
}
+
+func TestContainerWithCustomImage(t *testing.T) {
+ catalog, err := camel.DefaultCatalog()
+ assert.Nil(t, err)
+
+ client, _ := test.NewFakeClient()
+ traitCatalog := NewCatalog(context.TODO(), nil)
+
+ environment := Environment{
+ C: context.TODO(),
+ Client: client,
+ CamelCatalog: catalog,
+ Catalog: traitCatalog,
+ Integration: &v1.Integration{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: ServiceTestName,
+ Namespace: "ns",
+ UID: types.UID(uuid.NewString()),
+ },
+ Status: v1.IntegrationStatus{
+ Phase: v1.IntegrationPhaseInitialization,
+ },
+ Spec: v1.IntegrationSpec{
+ Profile: v1.TraitProfileKubernetes,
+ Traits: map[string]v1.TraitSpec{
+ "container": test.TraitSpecFromMap(t,
map[string]interface{}{
+ "image": "foo/bar:1.0.0",
+ }),
+ },
+ },
+ },
+ Platform: &v1.IntegrationPlatform{
+ Spec: v1.IntegrationPlatformSpec{
+ Cluster: v1.IntegrationPlatformClusterOpenShift,
+ Build: v1.IntegrationPlatformBuildSpec{
+ PublishStrategy:
v1.IntegrationPlatformBuildPublishStrategyS2I,
+ Registry:
v1.IntegrationPlatformRegistrySpec{Address: "registry"},
+ },
+ },
+ },
+ EnvVars: make([]corev1.EnvVar, 0),
+ ExecutedTraits: make([]Trait, 0),
+ Resources: kubernetes.NewCollection(),
+ }
+ environment.Platform.ResyncStatusFullConfig()
+
+ err = traitCatalog.apply(&environment)
+ assert.Nil(t, err)
+
+ for _, postAction := range environment.PostActions {
+ assert.Nil(t, postAction(&environment))
+ }
+
+ assert.NotEmpty(t, environment.ExecutedTraits)
+ assert.NotNil(t, environment.GetTrait("deployer"))
+ assert.NotNil(t, environment.GetTrait("container"))
+ assert.Equal(t, "kit-"+ServiceTestName,
environment.Integration.Status.IntegrationKit.Name)
+
+ ikt := v1.IntegrationKit{}
+ key := ctrl.ObjectKey{
+ Namespace: "ns",
+ Name: "kit-" + ServiceTestName,
+ }
+
+ err = client.Get(context.TODO(), key, &ikt)
+ assert.Nil(t, err)
+ assert.Equal(t, environment.Integration.ObjectMeta.UID,
ikt.ObjectMeta.OwnerReferences[0].UID)
+
+ trait := test.TraitSpecToMap(t,
environment.Integration.Spec.Traits["container"])
+ assert.Equal(t, trait["image"], ikt.Spec.Image)
+}
+
+func TestContainerWithCustomImageAndIntegrationKit(t *testing.T) {
+ catalog, err := camel.DefaultCatalog()
+ assert.Nil(t, err)
+
+ client, _ := test.NewFakeClient()
+ traitCatalog := NewCatalog(context.TODO(), nil)
+
+ environment := Environment{
+ C: context.TODO(),
+ Client: client,
+ CamelCatalog: catalog,
+ Catalog: traitCatalog,
+ Integration: &v1.Integration{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: ServiceTestName,
+ Namespace: "ns",
+ UID: types.UID(uuid.NewString()),
+ },
+ Status: v1.IntegrationStatus{
+ Phase: v1.IntegrationPhaseInitialization,
+ },
+ Spec: v1.IntegrationSpec{
+ Profile: v1.TraitProfileKubernetes,
+ Traits: map[string]v1.TraitSpec{
+ "container": test.TraitSpecFromMap(t,
map[string]interface{}{
+ "image": "foo/bar:1.0.0",
+ }),
+ },
+ IntegrationKit: &corev1.ObjectReference{
+ Name: "bad-" + ServiceTestName,
+ Namespace: "ns",
+ },
+ },
+ },
+ Platform: &v1.IntegrationPlatform{
+ Spec: v1.IntegrationPlatformSpec{
+ Cluster: v1.IntegrationPlatformClusterOpenShift,
+ Build: v1.IntegrationPlatformBuildSpec{
+ PublishStrategy:
v1.IntegrationPlatformBuildPublishStrategyS2I,
+ Registry:
v1.IntegrationPlatformRegistrySpec{Address: "registry"},
+ },
+ },
+ },
+ EnvVars: make([]corev1.EnvVar, 0),
+ ExecutedTraits: make([]Trait, 0),
+ Resources: kubernetes.NewCollection(),
+ }
+ environment.Platform.ResyncStatusFullConfig()
+
+ err = traitCatalog.apply(&environment)
+ assert.NotNil(t, err)
+ assert.Contains(t, err.Error(), "unsupported configuration: a container
image has been set in conjunction with an IntegrationKit")
+}
+
+func TestContainerWithCustomImageAndDeprecatedIntegrationKit(t *testing.T) {
+ catalog, err := camel.DefaultCatalog()
+ assert.Nil(t, err)
+
+ client, _ := test.NewFakeClient()
+ traitCatalog := NewCatalog(context.TODO(), nil)
+
+ environment := Environment{
+ C: context.TODO(),
+ Client: client,
+ CamelCatalog: catalog,
+ Catalog: traitCatalog,
+ Integration: &v1.Integration{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: ServiceTestName,
+ Namespace: "ns",
+ UID: types.UID(uuid.NewString()),
+ },
+ Status: v1.IntegrationStatus{
+ Phase: v1.IntegrationPhaseInitialization,
+ },
+ Spec: v1.IntegrationSpec{
+ Profile: v1.TraitProfileKubernetes,
+ Traits: map[string]v1.TraitSpec{
+ "container": test.TraitSpecFromMap(t,
map[string]interface{}{
+ "image": "foo/bar:1.0.0",
+ }),
+ },
+ Kit: "bad-" + ServiceTestName,
+ },
+ },
+ Platform: &v1.IntegrationPlatform{
+ Spec: v1.IntegrationPlatformSpec{
+ Cluster: v1.IntegrationPlatformClusterOpenShift,
+ Build: v1.IntegrationPlatformBuildSpec{
+ PublishStrategy:
v1.IntegrationPlatformBuildPublishStrategyS2I,
+ Registry:
v1.IntegrationPlatformRegistrySpec{Address: "registry"},
+ },
+ },
+ },
+ EnvVars: make([]corev1.EnvVar, 0),
+ ExecutedTraits: make([]Trait, 0),
+ Resources: kubernetes.NewCollection(),
+ }
+ environment.Platform.ResyncStatusFullConfig()
+
+ err = traitCatalog.apply(&environment)
+ assert.NotNil(t, err)
+ assert.Contains(t, err.Error(), "unsupported configuration: a container
image has been set in conjunction with an IntegrationKit")
+}