This is an automated email from the ASF dual-hosted git repository.

orpiske pushed a commit to branch camel-main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 5edd5df80768226ecd92f4ba9766012fe3966ae0
Author: Luca Burgazzoli <lburgazz...@gmail.com>
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 0a7b203..46a12d1 100644
--- a/pkg/resources/resources.go
+++ b/pkg/resources/resources.go
@@ -474,9 +474,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")
+}

Reply via email to