You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by as...@apache.org on 2019/11/28 07:41:00 UTC

[camel-k] branch master updated (46fa770 -> 93c3d2b)

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

astefanutti pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git.


    from 46fa770  Fix #613: Fix doc formatting
     new 231b109  chore: Migrate from OpenShift deprecated API
     new 940746c  chore(replicas): Use JSON merge patch to update deployment replicas
     new 7e6d00e  feat: Generic patching of integration resources in running phase
     new c4c00d6  fix: Add missing labels to route resources
     new f797de8  feat: Patch generation labels of integration resources used by GC trait
     new f758178  chore: Rely on generic patching to reconcile deployment replicas for running integrations
     new 7e97939  chore: Rely on generic patching to reconcile Knative service scaling annotations for running integrations
     new 38f5b5f  chore: fix typo
     new a3c3cf4  chore: Remove conflict checking as patch is now used instead of update
     new 755d061  feat: Use JSON merge patch to update integration status
     new 6cf412a  chore: Use reflection to compute positive JSON merge patch
     new 57f5d83  chore: Remove empty maps recursively from JSON merge patch
     new 93c3d2b  chore(patch): Skip patch requests for empty JSON merge patches

The 13 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../integration/integration_controller.go          |  30 +----
 pkg/controller/integration/monitor.go              |   3 +-
 pkg/trait/affinity.go                              |   2 +-
 pkg/trait/classpath.go                             |   3 +-
 pkg/trait/container.go                             |   2 +-
 pkg/trait/debug.go                                 |   2 +-
 pkg/trait/deployer.go                              | 130 ++++++++++++++++++++-
 pkg/trait/deployment.go                            |  46 +++-----
 pkg/trait/deployment_test.go                       |  10 +-
 pkg/trait/environment.go                           |   2 +-
 pkg/trait/gc.go                                    |  36 +++---
 pkg/trait/gc_test.go                               |   2 +-
 pkg/trait/ingress.go                               |   2 +-
 pkg/trait/istio.go                                 |   6 +-
 pkg/trait/jolokia.go                               |   2 +-
 pkg/trait/jolokia_test.go                          |   2 +-
 pkg/trait/knative.go                               |   2 +-
 pkg/trait/knative_service.go                       |  58 ++++-----
 pkg/trait/owner.go                                 |   2 +-
 pkg/trait/probes.go                                |   8 +-
 pkg/trait/prometheus.go                            |   2 +-
 pkg/trait/route.go                                 |  14 ++-
 pkg/trait/service.go                               |   4 +-
 pkg/trait/trait.go                                 |   7 --
 pkg/trait/trait_catalog.go                         |   6 +-
 pkg/util/kubernetes/collection.go                  |   6 +-
 26 files changed, 232 insertions(+), 157 deletions(-)


[camel-k] 13/13: chore(patch): Skip patch requests for empty JSON merge patches

Posted by as...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 93c3d2bff91a17cb02193a7dd1e2729fd0e7bd50
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Wed Nov 27 10:39:59 2019 +0100

    chore(patch): Skip patch requests for empty JSON merge patches
---
 pkg/trait/deployer.go | 47 +++++++++++++++++++++++++----------------------
 1 file changed, 25 insertions(+), 22 deletions(-)

diff --git a/pkg/trait/deployer.go b/pkg/trait/deployer.go
index f6052a1..a996f5b 100644
--- a/pkg/trait/deployer.go
+++ b/pkg/trait/deployer.go
@@ -85,7 +85,15 @@ func (t *deployerTrait) Apply(e *Environment) error {
 					return err
 				}
 
-				err = env.Client.Patch(env.C, resource, mergeFrom(object))
+				patch, err := positiveMergePatch(object, resource)
+				if err != nil {
+					return err
+				} else if len(patch) == 0 {
+					// Avoid triggering a patch request for nothing
+					continue
+				}
+
+				err = env.Client.Patch(env.C, resource, client.ConstantPatch(types.MergePatchType, patch))
 				if err != nil {
 					return errors.Wrap(err, "error during patch resource")
 				}
@@ -102,26 +110,18 @@ func (t *deployerTrait) IsPlatformTrait() bool {
 	return true
 }
 
-type mergeFromPositivePatch struct {
-	from runtime.Object
-}
-
-func (s *mergeFromPositivePatch) Type() types.PatchType {
-	return types.MergePatchType
-}
-
-func (s *mergeFromPositivePatch) Data(obj runtime.Object) ([]byte, error) {
-	originalJSON, err := json.Marshal(s.from)
+func positiveMergePatch(source runtime.Object, target runtime.Object) ([]byte, error) {
+	sourceJSON, err := json.Marshal(source)
 	if err != nil {
 		return nil, err
 	}
 
-	modifiedJSON, err := json.Marshal(obj)
+	targetJSON, err := json.Marshal(target)
 	if err != nil {
 		return nil, err
 	}
 
-	mergePatch, err := jsonpatch.CreateMergePatch(originalJSON, modifiedJSON)
+	mergePatch, err := jsonpatch.CreateMergePatch(sourceJSON, targetJSON)
 	if err != nil {
 		return nil, err
 	}
@@ -138,11 +138,12 @@ func (s *mergeFromPositivePatch) Data(obj runtime.Object) ([]byte, error) {
 	// by the traits.
 	removeNilValues(reflect.ValueOf(positivePatch), reflect.Value{})
 
-	return json.Marshal(positivePatch)
-}
+	// Return an empty patch if no keys remain
+	if len(positivePatch) == 0 {
+		return make([]byte, 0), nil
+	}
 
-func mergeFrom(obj runtime.Object) client.Patch {
-	return &mergeFromPositivePatch{obj}
+	return json.Marshal(positivePatch)
 }
 
 func removeNilValues(v reflect.Value, parent reflect.Value) {
@@ -156,15 +157,17 @@ func removeNilValues(v reflect.Value, parent reflect.Value) {
 		}
 	case reflect.Map:
 		for _, k := range v.MapKeys() {
-			c := v.MapIndex(k)
-			if c.IsNil() {
-				v.SetMapIndex(k, reflect.Value{})
-			} else if c.Elem().Kind() == reflect.Map && len(c.Elem().MapKeys()) == 0 {
+			switch c := v.MapIndex(k); {
+			case !c.IsValid():
+				// Skip keys previously deleted
+				continue
+			case c.IsNil(), c.Elem().Kind() == reflect.Map && len(c.Elem().MapKeys()) == 0:
 				v.SetMapIndex(k, reflect.Value{})
-			} else {
+			default:
 				removeNilValues(c, v)
 			}
 		}
+		// Back process the parent map in case it has been emptied so that it's deleted as well
 		if len(v.MapKeys()) == 0 && parent.Kind() == reflect.Map {
 			removeNilValues(parent, reflect.Value{})
 		}


[camel-k] 07/13: chore: Rely on generic patching to reconcile Knative service scaling annotations for running integrations

Posted by as...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 7e97939646fa94afb1c646f3c1bea31056cb1cc7
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Tue Nov 26 11:29:53 2019 +0100

    chore: Rely on generic patching to reconcile Knative service scaling annotations for running integrations
---
 pkg/trait/knative_service.go | 56 +++++++++++++++++---------------------------
 1 file changed, 21 insertions(+), 35 deletions(-)

diff --git a/pkg/trait/knative_service.go b/pkg/trait/knative_service.go
index d60e1b7..b57f76f 100644
--- a/pkg/trait/knative_service.go
+++ b/pkg/trait/knative_service.go
@@ -18,11 +18,8 @@ limitations under the License.
 package trait
 
 import (
-	"context"
 	"strconv"
 
-	"sigs.k8s.io/controller-runtime/pkg/client"
-
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
@@ -170,18 +167,24 @@ func (t *knativeServiceTrait) Configure(e *Environment) (bool, error) {
 }
 
 func (t *knativeServiceTrait) Apply(e *Environment) error {
-	if e.IntegrationInPhase(v1alpha1.IntegrationPhaseRunning) {
-		// Reconcile the Knative scale annotations
-		service := &serving.Service{}
-		err := t.client.Get(context.TODO(), client.ObjectKey{Namespace: e.Integration.Namespace, Name: e.Integration.Name}, service)
-		if err != nil {
-			return err
-		}
+	ksvc := t.getServiceFor(e)
+	maps := e.ComputeConfigMaps()
+
+	e.Resources.AddAll(maps)
+	e.Resources.Add(ksvc)
 
+	e.Integration.Status.SetCondition(
+		v1alpha1.IntegrationConditionKnativeServiceAvailable,
+		corev1.ConditionTrue,
+		v1alpha1.IntegrationConditionKnativeServiceAvailableReason,
+		ksvc.Name,
+	)
+
+	if e.IntegrationInPhase(v1alpha1.IntegrationPhaseRunning) {
 		replicas := e.Integration.Spec.Replicas
 
 		isUpdateRequired := false
-		minScale, ok := service.Spec.Template.Annotations[knativeServingMinScaleAnnotation]
+		minScale, ok := ksvc.Spec.Template.Annotations[knativeServingMinScaleAnnotation]
 		if ok {
 			min, err := strconv.Atoi(minScale)
 			if err != nil {
@@ -194,7 +197,7 @@ func (t *knativeServiceTrait) Apply(e *Environment) error {
 			isUpdateRequired = true
 		}
 
-		maxScale, ok := service.Spec.Template.Annotations[knativeServingMaxScaleAnnotation]
+		maxScale, ok := ksvc.Spec.Template.Annotations[knativeServingMaxScaleAnnotation]
 		if ok {
 			max, err := strconv.Atoi(maxScale)
 			if err != nil {
@@ -210,40 +213,23 @@ func (t *knativeServiceTrait) Apply(e *Environment) error {
 		if isUpdateRequired {
 			if replicas == nil {
 				if t.MinScale != nil && *t.MinScale > 0 {
-					service.Spec.Template.Annotations[knativeServingMinScaleAnnotation] = strconv.Itoa(*t.MinScale)
+					ksvc.Spec.Template.Annotations[knativeServingMinScaleAnnotation] = strconv.Itoa(*t.MinScale)
 				} else {
-					delete(service.Spec.Template.Annotations, knativeServingMinScaleAnnotation)
+					delete(ksvc.Spec.Template.Annotations, knativeServingMinScaleAnnotation)
 				}
 				if t.MaxScale != nil && *t.MaxScale > 0 {
-					service.Spec.Template.Annotations[knativeServingMaxScaleAnnotation] = strconv.Itoa(*t.MaxScale)
+					ksvc.Spec.Template.Annotations[knativeServingMaxScaleAnnotation] = strconv.Itoa(*t.MaxScale)
 				} else {
-					delete(service.Spec.Template.Annotations, knativeServingMaxScaleAnnotation)
+					delete(ksvc.Spec.Template.Annotations, knativeServingMaxScaleAnnotation)
 				}
 			} else {
 				scale := strconv.Itoa(int(*replicas))
-				service.Spec.Template.Annotations[knativeServingMinScaleAnnotation] = scale
-				service.Spec.Template.Annotations[knativeServingMaxScaleAnnotation] = scale
-			}
-			err := t.client.Update(context.TODO(), service)
-			if err != nil {
-				return err
+				ksvc.Spec.Template.Annotations[knativeServingMinScaleAnnotation] = scale
+				ksvc.Spec.Template.Annotations[knativeServingMaxScaleAnnotation] = scale
 			}
 		}
 	}
 
-	ksvc := t.getServiceFor(e)
-	maps := e.ComputeConfigMaps()
-
-	e.Resources.AddAll(maps)
-	e.Resources.Add(ksvc)
-
-	e.Integration.Status.SetCondition(
-		v1alpha1.IntegrationConditionKnativeServiceAvailable,
-		corev1.ConditionTrue,
-		v1alpha1.IntegrationConditionKnativeServiceAvailableReason,
-		ksvc.Name,
-	)
-
 	return nil
 }
 


[camel-k] 05/13: feat: Patch generation labels of integration resources used by GC trait

Posted by as...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit f797de8de8ad5fb6adddeef3a6feee3172761bca
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Tue Nov 26 11:27:42 2019 +0100

    feat: Patch generation labels of integration resources used by GC trait
---
 pkg/trait/gc.go      | 36 ++++++++++++++++++------------------
 pkg/trait/gc_test.go |  2 +-
 2 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/pkg/trait/gc.go b/pkg/trait/gc.go
index 11b8ccb..b35a4a8 100644
--- a/pkg/trait/gc.go
+++ b/pkg/trait/gc.go
@@ -90,35 +90,35 @@ func (t *garbageCollectorTrait) Configure(e *Environment) (bool, error) {
 }
 
 func (t *garbageCollectorTrait) Apply(e *Environment) error {
-	if e.IntegrationInPhase(v1alpha1.IntegrationPhaseInitialization, v1alpha1.IntegrationPhaseDeploying) {
+	switch e.Integration.Status.Phase {
+
+	case v1alpha1.IntegrationPhaseRunning:
+		// Register a post action that deletes the existing resources that are labelled
+		// with the previous integration generations.
+		// TODO: this should be refined so that it's run when all the replicas for the newer generation
+		// are ready. This is to be added when the integration scale status is refined with ready replicas
+		e.PostActions = append(e.PostActions, func(env *Environment) error {
+			// The collection and deletion are performed asynchronously to avoid blocking
+			// the reconcile loop.
+			go t.garbageCollectResources(env)
+			return nil
+		})
+		fallthrough
+
+	default:
 		// Register a post processor that adds the required labels to the new resources
 		e.PostProcessors = append(e.PostProcessors, func(env *Environment) error {
+			generation := strconv.FormatInt(env.Integration.GetGeneration(), 10)
 			env.Resources.VisitMetaObject(func(resource metav1.Object) {
 				labels := resource.GetLabels()
-				if labels == nil {
-					labels = map[string]string{}
-				}
 				// Label the resource with the current integration generation
-				labels["camel.apache.org/generation"] = strconv.FormatInt(env.Integration.GetGeneration(), 10)
+				labels["camel.apache.org/generation"] = generation
 				// Make sure the integration label is set
 				labels["camel.apache.org/integration"] = env.Integration.Name
 				resource.SetLabels(labels)
 			})
 			return nil
 		})
-	} else if e.IntegrationInPhase(v1alpha1.IntegrationPhaseRunning) {
-		// Let's run garbage collection during the integration running phase
-		// TODO: this should be refined so that it's run when all the replicas for the newer generation
-		// are ready. This is to be added when the integration scale status is refined with ready replicas
-
-		// Register a post action that deletes the existing resources that are labelled
-		// with the previous integration generations.
-		e.PostActions = append(e.PostActions, func(environment *Environment) error {
-			// The collection and deletion are performed asynchronously to avoid blocking
-			// the reconcile loop.
-			go t.garbageCollectResources(e)
-			return nil
-		})
 	}
 
 	return nil
diff --git a/pkg/trait/gc_test.go b/pkg/trait/gc_test.go
index 7766638..5a49058 100644
--- a/pkg/trait/gc_test.go
+++ b/pkg/trait/gc_test.go
@@ -51,7 +51,7 @@ func TestApplyGarbageCollectorTraitDoesSucceed(t *testing.T) {
 	err := gcTrait.Apply(environment)
 
 	assert.Nil(t, err)
-	assert.Len(t, environment.PostProcessors, 0)
+	assert.Len(t, environment.PostProcessors, 1)
 	assert.Len(t, environment.PostActions, 1)
 }
 


[camel-k] 12/13: chore: Remove empty maps recursively from JSON merge patch

Posted by as...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 57f5d83fb79fce28adb56798bb1fbe8f823dbce1
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Wed Nov 27 09:52:16 2019 +0100

    chore: Remove empty maps recursively from JSON merge patch
---
 pkg/trait/deployer.go | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/pkg/trait/deployer.go b/pkg/trait/deployer.go
index 56b0322..f6052a1 100644
--- a/pkg/trait/deployer.go
+++ b/pkg/trait/deployer.go
@@ -136,7 +136,7 @@ func (s *mergeFromPositivePatch) Data(obj runtime.Object) ([]byte, error) {
 	// so that values defaulted by controllers server-side are not deleted.
 	// It's generally acceptable as these values are orthogonal to the values managed
 	// by the traits.
-	removeNilValues(reflect.ValueOf(positivePatch))
+	removeNilValues(reflect.ValueOf(positivePatch), reflect.Value{})
 
 	return json.Marshal(positivePatch)
 }
@@ -145,23 +145,28 @@ func mergeFrom(obj runtime.Object) client.Patch {
 	return &mergeFromPositivePatch{obj}
 }
 
-func removeNilValues(v reflect.Value) {
+func removeNilValues(v reflect.Value, parent reflect.Value) {
 	for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
 		v = v.Elem()
 	}
 	switch v.Kind() {
 	case reflect.Array, reflect.Slice:
 		for i := 0; i < v.Len(); i++ {
-			removeNilValues(v.Index(i))
+			removeNilValues(v.Index(i), v)
 		}
 	case reflect.Map:
 		for _, k := range v.MapKeys() {
 			c := v.MapIndex(k)
 			if c.IsNil() {
 				v.SetMapIndex(k, reflect.Value{})
+			} else if c.Elem().Kind() == reflect.Map && len(c.Elem().MapKeys()) == 0 {
+				v.SetMapIndex(k, reflect.Value{})
 			} else {
-				removeNilValues(c)
+				removeNilValues(c, v)
 			}
 		}
+		if len(v.MapKeys()) == 0 && parent.Kind() == reflect.Map {
+			removeNilValues(parent, reflect.Value{})
+		}
 	}
 }


[camel-k] 11/13: chore: Use reflection to compute positive JSON merge patch

Posted by as...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 6cf412a83e0c0cf525ea0a03229f5b7b884c37a1
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Tue Nov 26 17:50:03 2019 +0100

    chore: Use reflection to compute positive JSON merge patch
---
 pkg/trait/deployer.go | 43 ++++++++++++++++++++++++++++++++++---------
 1 file changed, 34 insertions(+), 9 deletions(-)

diff --git a/pkg/trait/deployer.go b/pkg/trait/deployer.go
index 1a9550f..56b0322 100644
--- a/pkg/trait/deployer.go
+++ b/pkg/trait/deployer.go
@@ -18,10 +18,12 @@ limitations under the License.
 package trait
 
 import (
-	jsonpatch "github.com/evanphx/json-patch"
+	"reflect"
 
 	"github.com/pkg/errors"
 
+	jsonpatch "github.com/evanphx/json-patch"
+
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/apimachinery/pkg/util/json"
@@ -119,24 +121,47 @@ func (s *mergeFromPositivePatch) Data(obj runtime.Object) ([]byte, error) {
 		return nil, err
 	}
 
-	patch, err := jsonpatch.CreateMergePatch(originalJSON, modifiedJSON)
+	mergePatch, err := jsonpatch.CreateMergePatch(originalJSON, modifiedJSON)
 	if err != nil {
 		return nil, err
 	}
 
-	// The following is a work-around to remove null fields from the JSON merge patch
-	// so that values defaulted by controllers server-side are not deleted.
-	// It's generally acceptable as these values are orthogonal to the values managed
-	// by the traits.
-	out := obj.DeepCopyObject()
-	err = json.Unmarshal(patch, out)
+	var positivePatch map[string]interface{}
+	err = json.Unmarshal(mergePatch, &positivePatch)
 	if err != nil {
 		return nil, err
 	}
 
-	return json.Marshal(out)
+	// The following is a work-around to remove null fields from the JSON merge patch,
+	// so that values defaulted by controllers server-side are not deleted.
+	// It's generally acceptable as these values are orthogonal to the values managed
+	// by the traits.
+	removeNilValues(reflect.ValueOf(positivePatch))
+
+	return json.Marshal(positivePatch)
 }
 
 func mergeFrom(obj runtime.Object) client.Patch {
 	return &mergeFromPositivePatch{obj}
 }
+
+func removeNilValues(v reflect.Value) {
+	for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
+		v = v.Elem()
+	}
+	switch v.Kind() {
+	case reflect.Array, reflect.Slice:
+		for i := 0; i < v.Len(); i++ {
+			removeNilValues(v.Index(i))
+		}
+	case reflect.Map:
+		for _, k := range v.MapKeys() {
+			c := v.MapIndex(k)
+			if c.IsNil() {
+				v.SetMapIndex(k, reflect.Value{})
+			} else {
+				removeNilValues(c)
+			}
+		}
+	}
+}


[camel-k] 04/13: fix: Add missing labels to route resources

Posted by as...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit c4c00d6fd1ded169f144c4b1f31e9ee3413a9187
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Tue Nov 26 09:38:57 2019 +0100

    fix: Add missing labels to route resources
---
 pkg/trait/route.go | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/pkg/trait/route.go b/pkg/trait/route.go
index 1109c02..7ca59e1 100644
--- a/pkg/trait/route.go
+++ b/pkg/trait/route.go
@@ -121,6 +121,9 @@ func (t *routeTrait) Apply(e *Environment) error {
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      t.service.Name,
 			Namespace: t.service.Namespace,
+			Labels: map[string]string{
+				"camel.apache.org/integration": e.Integration.Name,
+			},
 		},
 		Spec: routev1.RouteSpec{
 			Port: &routev1.RoutePort{


[camel-k] 10/13: feat: Use JSON merge patch to update integration status

Posted by as...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 755d06108cc50154a6c8559e4d37e00f2deec84c
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Tue Nov 26 15:53:51 2019 +0100

    feat: Use JSON merge patch to update integration status
---
 pkg/controller/integration/integration_controller.go | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go
index 16849e8..730368b 100644
--- a/pkg/controller/integration/integration_controller.go
+++ b/pkg/controller/integration/integration_controller.go
@@ -255,7 +255,7 @@ func (r *ReconcileIntegration) Reconcile(request reconcile.Request) (reconcile.R
 				target.SetIntegrationPlatform(pl)
 			}
 
-			return r.update(ctx, targetLog, target)
+			return r.update(ctx, &instance, target)
 		}
 
 		return reconcile.Result{}, err
@@ -282,7 +282,7 @@ func (r *ReconcileIntegration) Reconcile(request reconcile.Request) (reconcile.R
 			}
 
 			if newTarget != nil {
-				if r, err := r.update(ctx, targetLog, newTarget); err != nil {
+				if r, err := r.update(ctx, &instance, newTarget); err != nil {
 					return r, err
 				}
 
@@ -304,8 +304,7 @@ func (r *ReconcileIntegration) Reconcile(request reconcile.Request) (reconcile.R
 	return reconcile.Result{}, nil
 }
 
-// Update --
-func (r *ReconcileIntegration) update(ctx context.Context, log log.Logger, target *v1alpha1.Integration) (reconcile.Result, error) {
+func (r *ReconcileIntegration) update(ctx context.Context, base *v1alpha1.Integration, target *v1alpha1.Integration) (reconcile.Result, error) {
 	dgst, err := digest.ComputeForIntegration(target)
 	if err != nil {
 		return reconcile.Result{}, err
@@ -313,16 +312,7 @@ func (r *ReconcileIntegration) update(ctx context.Context, log log.Logger, targe
 
 	target.Status.Digest = dgst
 
-	err = r.client.Status().Update(ctx, target)
-	if err != nil {
-		if k8serrors.IsConflict(err) {
-			log.Error(err, "conflict")
-
-			return reconcile.Result{
-				Requeue: true,
-			}, nil
-		}
-	}
+	err = r.client.Status().Patch(ctx, target, k8sclient.MergeFrom(base))
 
 	return reconcile.Result{}, err
 }


[camel-k] 01/13: chore: Migrate from OpenShift deprecated API

Posted by as...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 231b1098ba1edd61bd489cc8af909775d4f700bf
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Fri Nov 22 13:37:50 2019 +0100

    chore: Migrate from OpenShift deprecated API
---
 pkg/trait/route.go | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/pkg/trait/route.go b/pkg/trait/route.go
index adc8c37..6a0fd18 100644
--- a/pkg/trait/route.go
+++ b/pkg/trait/route.go
@@ -21,12 +21,13 @@ import (
 	"fmt"
 	"reflect"
 
-	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-
-	routev1 "github.com/openshift/api/route/v1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/intstr"
+
+	routev1 "github.com/openshift/api/route/v1"
+
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 )
 
 // The Route trait can be used to configure the creation of OpenShift routes for the integration.
@@ -115,7 +116,7 @@ func (t *routeTrait) Apply(e *Environment) error {
 	route := routev1.Route{
 		TypeMeta: metav1.TypeMeta{
 			Kind:       "Route",
-			APIVersion: routev1.SchemeGroupVersion.String(),
+			APIVersion: routev1.GroupVersion.String(),
 		},
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      t.service.Name,


[camel-k] 08/13: chore: fix typo

Posted by as...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 38f5b5f203217e5c70c2ffc0fab1907186d1cb95
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Tue Nov 26 11:30:16 2019 +0100

    chore: fix typo
---
 pkg/util/kubernetes/collection.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/pkg/util/kubernetes/collection.go b/pkg/util/kubernetes/collection.go
index 4c10184..20a2c25 100644
--- a/pkg/util/kubernetes/collection.go
+++ b/pkg/util/kubernetes/collection.go
@@ -35,12 +35,12 @@ type Collection struct {
 }
 
 // NewCollection creates a new empty collection
-func NewCollection(objcts ...runtime.Object) *Collection {
+func NewCollection(objects ...runtime.Object) *Collection {
 	collection := Collection{
-		items: make([]runtime.Object, 0, len(objcts)),
+		items: make([]runtime.Object, 0, len(objects)),
 	}
 
-	collection.items = append(collection.items, objcts...)
+	collection.items = append(collection.items, objects...)
 
 	return &collection
 }


[camel-k] 03/13: feat: Generic patching of integration resources in running phase

Posted by as...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 7e6d00e3a50f3bbee9ec183307d0eb8224fe6dae
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Tue Nov 26 09:17:44 2019 +0100

    feat: Generic patching of integration resources in running phase
---
 pkg/controller/integration/monitor.go |  3 +-
 pkg/trait/affinity.go                 |  2 +-
 pkg/trait/classpath.go                |  3 +-
 pkg/trait/container.go                |  2 +-
 pkg/trait/debug.go                    |  2 +-
 pkg/trait/deployer.go                 | 97 ++++++++++++++++++++++++++++++++++-
 pkg/trait/deployment.go               |  5 +-
 pkg/trait/environment.go              |  2 +-
 pkg/trait/ingress.go                  |  2 +-
 pkg/trait/istio.go                    |  6 ++-
 pkg/trait/jolokia.go                  |  2 +-
 pkg/trait/jolokia_test.go             |  2 +-
 pkg/trait/knative.go                  |  2 +-
 pkg/trait/knative_service.go          |  2 -
 pkg/trait/owner.go                    |  2 +-
 pkg/trait/probes.go                   |  8 ++-
 pkg/trait/prometheus.go               |  2 +-
 pkg/trait/route.go                    |  2 +-
 pkg/trait/service.go                  |  4 +-
 pkg/trait/trait.go                    |  7 ---
 pkg/trait/trait_catalog.go            |  6 +--
 21 files changed, 127 insertions(+), 36 deletions(-)

diff --git a/pkg/controller/integration/monitor.go b/pkg/controller/integration/monitor.go
index 85d5a5a..1cad996 100644
--- a/pkg/controller/integration/monitor.go
+++ b/pkg/controller/integration/monitor.go
@@ -62,8 +62,7 @@ func (action *monitorAction) Handle(ctx context.Context, integration *v1alpha1.I
 		return integration, nil
 	}
 
-	// Run traits that are enabled for the running phase,
-	// such as the deployment, garbage collector and Knative service traits.
+	// Run traits that are enabled for the running phase
 	_, err = trait.Apply(ctx, action.client, integration, nil)
 	if err != nil {
 		return nil, err
diff --git a/pkg/trait/affinity.go b/pkg/trait/affinity.go
index c285c6e..1c921e4 100644
--- a/pkg/trait/affinity.go
+++ b/pkg/trait/affinity.go
@@ -66,7 +66,7 @@ func (t *affinityTrait) Configure(e *Environment) (bool, error) {
 		return false, fmt.Errorf("both pod affinity and pod anti-affinity can't be set simultaneously")
 	}
 
-	return e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying), nil
+	return e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying, v1alpha1.IntegrationPhaseRunning), nil
 }
 
 func (t *affinityTrait) Apply(e *Environment) (err error) {
diff --git a/pkg/trait/classpath.go b/pkg/trait/classpath.go
index 14814f0..1a2a643 100644
--- a/pkg/trait/classpath.go
+++ b/pkg/trait/classpath.go
@@ -49,7 +49,8 @@ func (t *classpathTrait) Configure(e *Environment) (bool, error) {
 		return false, nil
 	}
 
-	return e.InPhase(v1alpha1.IntegrationKitPhaseReady, v1alpha1.IntegrationPhaseDeploying), nil
+	return e.InPhase(v1alpha1.IntegrationKitPhaseReady, v1alpha1.IntegrationPhaseDeploying) ||
+		e.InPhase(v1alpha1.IntegrationKitPhaseReady, v1alpha1.IntegrationPhaseRunning), nil
 }
 
 func (t *classpathTrait) Apply(e *Environment) error {
diff --git a/pkg/trait/container.go b/pkg/trait/container.go
index c37775c..6bd3ae6 100644
--- a/pkg/trait/container.go
+++ b/pkg/trait/container.go
@@ -82,7 +82,7 @@ func (t *containerTrait) Configure(e *Environment) (bool, error) {
 		return false, nil
 	}
 
-	if !e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying) {
+	if !e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying, v1alpha1.IntegrationPhaseRunning) {
 		return false, nil
 	}
 
diff --git a/pkg/trait/debug.go b/pkg/trait/debug.go
index 7dcc430..d9d30bf 100644
--- a/pkg/trait/debug.go
+++ b/pkg/trait/debug.go
@@ -40,7 +40,7 @@ func newDebugTrait() *debugTrait {
 
 func (t *debugTrait) Configure(e *Environment) (bool, error) {
 	if t.Enabled != nil && *t.Enabled {
-		return e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying), nil
+		return e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying, v1alpha1.IntegrationPhaseRunning), nil
 	}
 
 	return false, nil
diff --git a/pkg/trait/deployer.go b/pkg/trait/deployer.go
index b5a8beb..1a9550f 100644
--- a/pkg/trait/deployer.go
+++ b/pkg/trait/deployer.go
@@ -17,6 +17,21 @@ limitations under the License.
 
 package trait
 
+import (
+	jsonpatch "github.com/evanphx/json-patch"
+
+	"github.com/pkg/errors"
+
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/apimachinery/pkg/util/json"
+
+	"sigs.k8s.io/controller-runtime/pkg/client"
+
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/apache/camel-k/pkg/util/kubernetes"
+)
+
 // The deployer trait can be used to explicitly select the kind of high level resource that
 // will deploy the integration.
 //
@@ -34,10 +49,49 @@ func newDeployerTrait() *deployerTrait {
 }
 
 func (t *deployerTrait) Configure(e *Environment) (bool, error) {
-	return true, nil
+	return e.IntegrationInPhase(
+		v1alpha1.IntegrationPhaseInitialization,
+		v1alpha1.IntegrationPhaseDeploying,
+		v1alpha1.IntegrationPhaseRunning,
+	), nil
 }
 
 func (t *deployerTrait) Apply(e *Environment) error {
+	switch e.Integration.Status.Phase {
+
+	case v1alpha1.IntegrationPhaseInitialization, v1alpha1.IntegrationPhaseDeploying:
+		// Register a post action that updates the resources generated by the traits
+		e.PostActions = append(e.PostActions, func(env *Environment) error {
+			if err := kubernetes.ReplaceResources(env.C, env.Client, env.Resources.Items()); err != nil {
+				return errors.Wrap(err, "error during replace resource")
+			}
+			return nil
+		})
+
+	case v1alpha1.IntegrationPhaseRunning:
+		// Register a post action that patches the resources generated by the traits
+		e.PostActions = append(e.PostActions, func(env *Environment) error {
+			for _, resource := range env.Resources.Items() {
+				key, err := client.ObjectKeyFromObject(resource)
+				if err != nil {
+					return err
+				}
+
+				object := resource.DeepCopyObject()
+				err = env.Client.Get(env.C, key, object)
+				if err != nil {
+					return err
+				}
+
+				err = env.Client.Patch(env.C, resource, mergeFrom(object))
+				if err != nil {
+					return errors.Wrap(err, "error during patch resource")
+				}
+			}
+			return nil
+		})
+	}
+
 	return nil
 }
 
@@ -45,3 +99,44 @@ func (t *deployerTrait) Apply(e *Environment) error {
 func (t *deployerTrait) IsPlatformTrait() bool {
 	return true
 }
+
+type mergeFromPositivePatch struct {
+	from runtime.Object
+}
+
+func (s *mergeFromPositivePatch) Type() types.PatchType {
+	return types.MergePatchType
+}
+
+func (s *mergeFromPositivePatch) Data(obj runtime.Object) ([]byte, error) {
+	originalJSON, err := json.Marshal(s.from)
+	if err != nil {
+		return nil, err
+	}
+
+	modifiedJSON, err := json.Marshal(obj)
+	if err != nil {
+		return nil, err
+	}
+
+	patch, err := jsonpatch.CreateMergePatch(originalJSON, modifiedJSON)
+	if err != nil {
+		return nil, err
+	}
+
+	// The following is a work-around to remove null fields from the JSON merge patch
+	// so that values defaulted by controllers server-side are not deleted.
+	// It's generally acceptable as these values are orthogonal to the values managed
+	// by the traits.
+	out := obj.DeepCopyObject()
+	err = json.Unmarshal(patch, out)
+	if err != nil {
+		return nil, err
+	}
+
+	return json.Marshal(out)
+}
+
+func mergeFrom(obj runtime.Object) client.Patch {
+	return &mergeFromPositivePatch{obj}
+}
diff --git a/pkg/trait/deployment.go b/pkg/trait/deployment.go
index 29f8b52..1375dfd 100644
--- a/pkg/trait/deployment.go
+++ b/pkg/trait/deployment.go
@@ -107,7 +107,8 @@ func (t *deploymentTrait) Apply(e *Environment) error {
 		return nil
 	}
 
-	if e.InPhase(v1alpha1.IntegrationKitPhaseReady, v1alpha1.IntegrationPhaseDeploying) {
+	if e.InPhase(v1alpha1.IntegrationKitPhaseReady, v1alpha1.IntegrationPhaseDeploying) ||
+		e.InPhase(v1alpha1.IntegrationKitPhaseReady, v1alpha1.IntegrationPhaseRunning) {
 		maps := e.ComputeConfigMaps()
 		depl := t.getDeploymentFor(e)
 
@@ -120,8 +121,6 @@ func (t *deploymentTrait) Apply(e *Environment) error {
 			v1alpha1.IntegrationConditionDeploymentAvailableReason,
 			depl.Name,
 		)
-
-		return nil
 	}
 
 	if e.IntegrationInPhase(v1alpha1.IntegrationPhaseRunning) {
diff --git a/pkg/trait/environment.go b/pkg/trait/environment.go
index 137b3ff..04774f7 100644
--- a/pkg/trait/environment.go
+++ b/pkg/trait/environment.go
@@ -53,7 +53,7 @@ func newEnvironmentTrait() *environmentTrait {
 
 func (t *environmentTrait) Configure(e *Environment) (bool, error) {
 	if t.Enabled == nil || *t.Enabled {
-		return e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying), nil
+		return e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying, v1alpha1.IntegrationPhaseRunning), nil
 	}
 
 	return false, nil
diff --git a/pkg/trait/ingress.go b/pkg/trait/ingress.go
index 0b99cdd..75af6f9 100644
--- a/pkg/trait/ingress.go
+++ b/pkg/trait/ingress.go
@@ -62,7 +62,7 @@ func (t *ingressTrait) Configure(e *Environment) (bool, error) {
 		return false, nil
 	}
 
-	if !e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying) {
+	if !e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying, v1alpha1.IntegrationPhaseRunning) {
 		return false, nil
 	}
 
diff --git a/pkg/trait/istio.go b/pkg/trait/istio.go
index abe3f81..4b8a904 100644
--- a/pkg/trait/istio.go
+++ b/pkg/trait/istio.go
@@ -20,9 +20,11 @@ package trait
 import (
 	"strconv"
 
-	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	appsv1 "k8s.io/api/apps/v1"
+
 	servingv1 "knative.dev/serving/pkg/apis/serving/v1"
+
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 )
 
 // The Istio trait allows to configure properties related to the Istio service mesh,
@@ -51,7 +53,7 @@ func newIstioTrait() *istioTrait {
 
 func (t *istioTrait) Configure(e *Environment) (bool, error) {
 	if t.Enabled != nil && *t.Enabled {
-		return e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying), nil
+		return e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying, v1alpha1.IntegrationPhaseRunning), nil
 	}
 
 	return false, nil
diff --git a/pkg/trait/jolokia.go b/pkg/trait/jolokia.go
index 90c590d..8a8b80d 100644
--- a/pkg/trait/jolokia.go
+++ b/pkg/trait/jolokia.go
@@ -96,7 +96,7 @@ func (t *jolokiaTrait) Configure(e *Environment) (bool, error) {
 		setDefaultJolokiaOption(options, &t.UseSslClientAuthentication, "useSslClientAuthentication", true)
 	}
 
-	return e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying), nil
+	return e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying, v1alpha1.IntegrationPhaseRunning), nil
 }
 
 func (t *jolokiaTrait) Apply(e *Environment) (err error) {
diff --git a/pkg/trait/jolokia_test.go b/pkg/trait/jolokia_test.go
index 5474fde..abf43f9 100644
--- a/pkg/trait/jolokia_test.go
+++ b/pkg/trait/jolokia_test.go
@@ -55,7 +55,7 @@ func TestConfigureJolokiaTraitInWrongPhaseDoesNotSucceed(t *testing.T) {
 	configured, err := trait.Configure(environment)
 
 	assert.Nil(t, err)
-	assert.False(t, configured)
+	assert.True(t, configured)
 }
 
 func TestConfigureJolokiaTraitWithUnparseableOptionsDoesNotSucceed(t *testing.T) {
diff --git a/pkg/trait/knative.go b/pkg/trait/knative.go
index 368d6f8..13f36ff 100644
--- a/pkg/trait/knative.go
+++ b/pkg/trait/knative.go
@@ -95,7 +95,7 @@ func (t *knativeTrait) Configure(e *Environment) (bool, error) {
 		return false, nil
 	}
 
-	if !e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying) {
+	if !e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying, v1alpha1.IntegrationPhaseRunning) {
 		return false, nil
 	}
 
diff --git a/pkg/trait/knative_service.go b/pkg/trait/knative_service.go
index 9fa8089..d60e1b7 100644
--- a/pkg/trait/knative_service.go
+++ b/pkg/trait/knative_service.go
@@ -229,8 +229,6 @@ func (t *knativeServiceTrait) Apply(e *Environment) error {
 				return err
 			}
 		}
-
-		return nil
 	}
 
 	ksvc := t.getServiceFor(e)
diff --git a/pkg/trait/owner.go b/pkg/trait/owner.go
index 37c7d64..3b1ff11 100644
--- a/pkg/trait/owner.go
+++ b/pkg/trait/owner.go
@@ -54,7 +54,7 @@ func (t *ownerTrait) Configure(e *Environment) (bool, error) {
 		return false, nil
 	}
 
-	return e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying), nil
+	return e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying, v1alpha1.IntegrationPhaseRunning), nil
 }
 
 func (t *ownerTrait) Apply(e *Environment) error {
diff --git a/pkg/trait/probes.go b/pkg/trait/probes.go
index 5731d6f..8ab2ba3 100644
--- a/pkg/trait/probes.go
+++ b/pkg/trait/probes.go
@@ -73,7 +73,11 @@ func newProbesTrait() *probesTrait {
 
 func (t *probesTrait) Configure(e *Environment) (bool, error) {
 	if t.Enabled != nil && *t.Enabled {
-		return e.IntegrationInPhase(v1alpha1.IntegrationPhaseInitialization) || e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying), nil
+		return e.IntegrationInPhase(
+			v1alpha1.IntegrationPhaseInitialization,
+			v1alpha1.IntegrationPhaseDeploying,
+			v1alpha1.IntegrationPhaseRunning,
+		), nil
 	}
 
 	return false, nil
@@ -100,7 +104,7 @@ func (t *probesTrait) Apply(e *Environment) error {
 		)
 	}
 
-	if e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying) {
+	if e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying, v1alpha1.IntegrationPhaseRunning) {
 		e.Resources.VisitDeployment(func(deployment *appsv1.Deployment) {
 			if len(deployment.Spec.Template.Spec.Containers) != 1 {
 				return
diff --git a/pkg/trait/prometheus.go b/pkg/trait/prometheus.go
index 84a8a73..8cc6ad0 100644
--- a/pkg/trait/prometheus.go
+++ b/pkg/trait/prometheus.go
@@ -64,7 +64,7 @@ func newPrometheusTrait() *prometheusTrait {
 }
 
 func (t *prometheusTrait) Configure(e *Environment) (bool, error) {
-	return e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying), nil
+	return e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying, v1alpha1.IntegrationPhaseRunning), nil
 }
 
 func (t *prometheusTrait) Apply(e *Environment) (err error) {
diff --git a/pkg/trait/route.go b/pkg/trait/route.go
index 6a0fd18..1109c02 100644
--- a/pkg/trait/route.go
+++ b/pkg/trait/route.go
@@ -87,7 +87,7 @@ func (t *routeTrait) Configure(e *Environment) (bool, error) {
 		return false, nil
 	}
 
-	if !e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying) {
+	if !e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying, v1alpha1.IntegrationPhaseRunning) {
 		return false, nil
 	}
 
diff --git a/pkg/trait/service.go b/pkg/trait/service.go
index e58ff68..8511dd9 100644
--- a/pkg/trait/service.go
+++ b/pkg/trait/service.go
@@ -64,7 +64,7 @@ func (t *serviceTrait) Configure(e *Environment) (bool, error) {
 		return false, nil
 	}
 
-	if !e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying) {
+	if !e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying, v1alpha1.IntegrationPhaseRunning) {
 		return false, nil
 	}
 
@@ -102,8 +102,8 @@ func (t *serviceTrait) Apply(e *Environment) error {
 	// add a new service if not already created
 	if svc == nil {
 		svc = getServiceFor(e)
-		e.Resources.Add(svc)
 	}
+	e.Resources.Add(svc)
 	return nil
 }
 
diff --git a/pkg/trait/trait.go b/pkg/trait/trait.go
index 8e50c2c..8d691bc 100644
--- a/pkg/trait/trait.go
+++ b/pkg/trait/trait.go
@@ -47,13 +47,6 @@ func Apply(ctx context.Context, c client.Client, integration *v1alpha1.Integrati
 		return nil, errors.Wrap(err, "error during trait customization")
 	}
 
-	// replace resources created by the trait
-	if environment.Resources != nil {
-		if err := kubernetes.ReplaceResources(ctx, c, environment.Resources.Items()); err != nil {
-			return nil, errors.Wrap(err, "error during replace resource")
-		}
-	}
-
 	// execute post actions registered by traits
 	for _, postAction := range environment.PostActions {
 		err := postAction(environment)
diff --git a/pkg/trait/trait_catalog.go b/pkg/trait/trait_catalog.go
index 1f3c1d1..3e627ae 100644
--- a/pkg/trait/trait_catalog.go
+++ b/pkg/trait/trait_catalog.go
@@ -143,7 +143,6 @@ func (c *Catalog) TraitsForProfile(profile v1alpha1.TraitProfile) []Trait {
 	case v1alpha1.TraitProfileOpenShift:
 		return []Trait{
 			c.tCamel,
-			c.tGarbageCollector,
 			c.tDebug,
 			c.tRestDsl,
 			c.tDependencies,
@@ -152,6 +151,7 @@ func (c *Catalog) TraitsForProfile(profile v1alpha1.TraitProfile) []Trait {
 			c.tEnvironment,
 			c.tDeployer,
 			c.tDeployment,
+			c.tGarbageCollector,
 			c.tAffinity,
 			c.tService,
 			c.tContainer,
@@ -167,7 +167,6 @@ func (c *Catalog) TraitsForProfile(profile v1alpha1.TraitProfile) []Trait {
 	case v1alpha1.TraitProfileKubernetes:
 		return []Trait{
 			c.tCamel,
-			c.tGarbageCollector,
 			c.tDebug,
 			c.tRestDsl,
 			c.tDependencies,
@@ -176,6 +175,7 @@ func (c *Catalog) TraitsForProfile(profile v1alpha1.TraitProfile) []Trait {
 			c.tEnvironment,
 			c.tDeployer,
 			c.tDeployment,
+			c.tGarbageCollector,
 			c.tAffinity,
 			c.tService,
 			c.tContainer,
@@ -191,7 +191,6 @@ func (c *Catalog) TraitsForProfile(profile v1alpha1.TraitProfile) []Trait {
 	case v1alpha1.TraitProfileKnative:
 		return []Trait{
 			c.tCamel,
-			c.tGarbageCollector,
 			c.tDebug,
 			c.tRestDsl,
 			c.tKnative,
@@ -201,6 +200,7 @@ func (c *Catalog) TraitsForProfile(profile v1alpha1.TraitProfile) []Trait {
 			c.tEnvironment,
 			c.tDeployer,
 			c.tDeployment,
+			c.tGarbageCollector,
 			c.tAffinity,
 			c.tKnativeService,
 			c.tContainer,


[camel-k] 06/13: chore: Rely on generic patching to reconcile deployment replicas for running integrations

Posted by as...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit f7581782ac09a4e472deb45d561cab89f5d6aa31
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Tue Nov 26 11:28:51 2019 +0100

    chore: Rely on generic patching to reconcile deployment replicas for running integrations
---
 pkg/trait/deployment.go      | 42 +++++++++++++-----------------------------
 pkg/trait/deployment_test.go | 10 ++++------
 2 files changed, 17 insertions(+), 35 deletions(-)

diff --git a/pkg/trait/deployment.go b/pkg/trait/deployment.go
index 1375dfd..818fc9f 100644
--- a/pkg/trait/deployment.go
+++ b/pkg/trait/deployment.go
@@ -18,14 +18,10 @@ limitations under the License.
 package trait
 
 import (
-	"context"
-
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	"sigs.k8s.io/controller-runtime/pkg/client"
-
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 )
 
@@ -97,7 +93,6 @@ func (t *deploymentTrait) Configure(e *Environment) (bool, error) {
 func (t *deploymentTrait) Apply(e *Environment) error {
 	if e.IntegrationKitInPhase(v1alpha1.IntegrationKitPhaseReady) &&
 		e.IntegrationInPhase(v1alpha1.IntegrationPhaseBuildingKit, v1alpha1.IntegrationPhaseResolvingKit) {
-
 		e.PostProcessors = append(e.PostProcessors, func(environment *Environment) error {
 			// trigger integration deploy
 			e.Integration.Status.Phase = v1alpha1.IntegrationPhaseDeploying
@@ -110,41 +105,30 @@ func (t *deploymentTrait) Apply(e *Environment) error {
 	if e.InPhase(v1alpha1.IntegrationKitPhaseReady, v1alpha1.IntegrationPhaseDeploying) ||
 		e.InPhase(v1alpha1.IntegrationKitPhaseReady, v1alpha1.IntegrationPhaseRunning) {
 		maps := e.ComputeConfigMaps()
-		depl := t.getDeploymentFor(e)
+		deployment := t.getDeploymentFor(e)
 
 		e.Resources.AddAll(maps)
-		e.Resources.Add(depl)
+		e.Resources.Add(deployment)
 
 		e.Integration.Status.SetCondition(
 			v1alpha1.IntegrationConditionDeploymentAvailable,
 			corev1.ConditionTrue,
 			v1alpha1.IntegrationConditionDeploymentAvailableReason,
-			depl.Name,
+			deployment.Name,
 		)
-	}
 
-	if e.IntegrationInPhase(v1alpha1.IntegrationPhaseRunning) {
-		// Reconcile the deployment replicas
-		deployment := &appsv1.Deployment{}
-		err := t.client.Get(context.TODO(), client.ObjectKey{Namespace: e.Integration.Namespace, Name: e.Integration.Name}, deployment)
-		if err != nil {
-			return err
-		}
-		replicas := e.Integration.Spec.Replicas
-		// Deployment replicas defaults to 1, so we avoid forcing
-		// an update to nil that will result to another update cycle
-		// back to that default value by the Deployment controller.
-		if replicas == nil && *deployment.Spec.Replicas != 1 ||
-			replicas != nil && *deployment.Spec.Replicas != *replicas {
-			target := deployment.DeepCopy()
-			target.Spec.Replicas = replicas
-			err := t.client.Patch(context.TODO(), target, client.MergeFrom(deployment))
-			if err != nil {
-				return err
+		if e.IntegrationInPhase(v1alpha1.IntegrationPhaseRunning) {
+			// Reconcile the deployment replicas
+			replicas := e.Integration.Spec.Replicas
+			// Deployment replicas defaults to 1, so we avoid forcing
+			// an update to nil that will result to another update cycle
+			// back to that default value by the Deployment controller.
+			if replicas == nil {
+				one := int32(1)
+				replicas = &one
 			}
+			deployment.Spec.Replicas = replicas
 		}
-
-		return nil
 	}
 
 	return nil
diff --git a/pkg/trait/deployment_test.go b/pkg/trait/deployment_test.go
index 7fa8450..15a30df 100644
--- a/pkg/trait/deployment_test.go
+++ b/pkg/trait/deployment_test.go
@@ -24,9 +24,8 @@ import (
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/apache/camel-k/pkg/util/kubernetes"
 	"github.com/apache/camel-k/pkg/util/test"
-	"github.com/stretchr/testify/assert"
 
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	"github.com/stretchr/testify/assert"
 
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
@@ -132,14 +131,13 @@ func TestApplyDeploymentTraitWhileRunningIntegrationDoesSucceed(t *testing.T) {
 
 	assert.Nil(t, err)
 
-	deployment := &appsv1.Deployment{}
-	err = deploymentTrait.client.Get(context.TODO(), client.ObjectKey{Namespace: "namespace", Name: "integration-name"}, deployment)
-	assert.Nil(t, err)
+	deployment := environment.Resources.GetDeployment(func(deployment *appsv1.Deployment) bool { return true })
+	assert.NotNil(t, deployment)
+	assert.Equal(t, "integration-name", deployment.Name)
 	assert.Equal(t, int32(3), *deployment.Spec.Replicas)
 }
 
 func createNominalDeploymentTest() (*deploymentTrait, *Environment) {
-
 	trait := newDeploymentTrait()
 	enabled := true
 	trait.Enabled = &enabled


[camel-k] 09/13: chore: Remove conflict checking as patch is now used instead of update

Posted by as...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit a3c3cf48556e03c54101c0c9b1ecde5a344f1766
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Tue Nov 26 15:37:31 2019 +0100

    chore: Remove conflict checking as patch is now used instead of update
---
 pkg/controller/integration/integration_controller.go | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go
index 3e28398..16849e8 100644
--- a/pkg/controller/integration/integration_controller.go
+++ b/pkg/controller/integration/integration_controller.go
@@ -19,8 +19,6 @@ package integration
 import (
 	"context"
 
-	"github.com/pkg/errors"
-
 	appsv1 "k8s.io/api/apps/v1"
 	k8serrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -280,16 +278,6 @@ func (r *ReconcileIntegration) Reconcile(request reconcile.Request) (reconcile.R
 
 			newTarget, err := a.Handle(ctx, target)
 			if err != nil {
-				// Some traits, like the deployment and knative service ones,
-				// update owned resources in the running phase, so it's better
-				// handling update conflicts gracefully, consistently with the
-				// primary integration update requests.
-				if cause := errors.Cause(err); k8serrors.IsConflict(cause) {
-					log.Error(cause, "conflict")
-					return reconcile.Result{
-						Requeue: true,
-					}, nil
-				}
 				return reconcile.Result{}, err
 			}
 


[camel-k] 02/13: chore(replicas): Use JSON merge patch to update deployment replicas

Posted by as...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 940746c0ed94f6a6caa52892d8df7b5a5fe1e656
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Fri Nov 22 14:03:17 2019 +0100

    chore(replicas): Use JSON merge patch to update deployment replicas
---
 pkg/trait/deployment.go | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/pkg/trait/deployment.go b/pkg/trait/deployment.go
index daf3f09..29f8b52 100644
--- a/pkg/trait/deployment.go
+++ b/pkg/trait/deployment.go
@@ -137,8 +137,9 @@ func (t *deploymentTrait) Apply(e *Environment) error {
 		// back to that default value by the Deployment controller.
 		if replicas == nil && *deployment.Spec.Replicas != 1 ||
 			replicas != nil && *deployment.Spec.Replicas != *replicas {
-			deployment.Spec.Replicas = replicas
-			err := t.client.Update(context.TODO(), deployment)
+			target := deployment.DeepCopy()
+			target.Spec.Replicas = replicas
+			err := t.client.Patch(context.TODO(), target, client.MergeFrom(deployment))
 			if err != nil {
 				return err
 			}