You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pc...@apache.org on 2022/12/15 08:17:06 UTC
[camel-k] 01/03: fix: reconciliation loops behaviors
This is an automated email from the ASF dual-hosted git repository.
pcongiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit ff24882004c9645660ae9f5051793f822525144a
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Mon Dec 12 16:57:43 2022 +0100
fix: reconciliation loops behaviors
* Expose trait failures into Integration status
* KameletBinding will report an Error when it cannot create an Integration for any reason
Closes #3389
Closes #3010
---
pkg/apis/camel/v1alpha1/kamelet_binding_types.go | 2 +
pkg/controller/integration/platform_setup.go | 6 ++-
pkg/controller/kameletbinding/initialize.go | 5 ++-
.../kameletbinding/kamelet_binding_controller.go | 47 +++++++++++-----------
pkg/controller/kameletbinding/monitor.go | 8 +++-
5 files changed, 41 insertions(+), 27 deletions(-)
diff --git a/pkg/apis/camel/v1alpha1/kamelet_binding_types.go b/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
index eafd475de..860151824 100644
--- a/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
+++ b/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
@@ -128,6 +128,8 @@ type KameletBindingConditionType string
const (
// KameletBindingConditionReady --
KameletBindingConditionReady KameletBindingConditionType = "Ready"
+ // KameletBindingIntegrationConditionError is used to report the error on the generated Integration
+ KameletBindingIntegrationConditionError KameletBindingConditionType = "IntegrationError"
)
// KameletBindingPhase --
diff --git a/pkg/controller/integration/platform_setup.go b/pkg/controller/integration/platform_setup.go
index 92a90ce80..e18b33823 100644
--- a/pkg/controller/integration/platform_setup.go
+++ b/pkg/controller/integration/platform_setup.go
@@ -20,6 +20,7 @@ package integration
import (
"context"
+ corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
@@ -52,7 +53,10 @@ func (action *platformSetupAction) CanHandle(integration *v1.Integration) bool {
// Handle handles the integrations.
func (action *platformSetupAction) Handle(ctx context.Context, integration *v1.Integration) (*v1.Integration, error) {
if _, err := trait.Apply(ctx, action.client, integration, nil); err != nil {
- return nil, err
+ integration.Status.Phase = v1.IntegrationPhaseError
+ integration.SetReadyCondition(corev1.ConditionFalse,
+ v1.IntegrationConditionInitializationFailedReason, err.Error())
+ return integration, err
}
pl, err := platform.GetForResource(ctx, action.client, integration)
diff --git a/pkg/controller/kameletbinding/initialize.go b/pkg/controller/kameletbinding/initialize.go
index 0ff43d881..6ae2827b7 100644
--- a/pkg/controller/kameletbinding/initialize.go
+++ b/pkg/controller/kameletbinding/initialize.go
@@ -52,7 +52,10 @@ func (action *initializeAction) CanHandle(kameletbinding *v1alpha1.KameletBindin
func (action *initializeAction) Handle(ctx context.Context, kameletbinding *v1alpha1.KameletBinding) (*v1alpha1.KameletBinding, error) {
it, err := CreateIntegrationFor(ctx, action.client, kameletbinding)
if err != nil {
- return nil, err
+ kameletbinding.Status.Phase = v1alpha1.KameletBindingPhaseError
+ kameletbinding.Status.SetErrorCondition(v1alpha1.KameletBindingIntegrationConditionError,
+ "Couldn't create an Integration custom resource", err)
+ return kameletbinding, err
}
if _, err := kubernetes.ReplaceResource(ctx, action.client, it); err != nil {
diff --git a/pkg/controller/kameletbinding/kamelet_binding_controller.go b/pkg/controller/kameletbinding/kamelet_binding_controller.go
index b14574217..8709c3e38 100644
--- a/pkg/controller/kameletbinding/kamelet_binding_controller.go
+++ b/pkg/controller/kameletbinding/kamelet_binding_controller.go
@@ -19,7 +19,6 @@ package kameletbinding
import (
"context"
- "time"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
@@ -41,6 +40,7 @@ import (
camelevent "github.com/apache/camel-k/pkg/event"
"github.com/apache/camel-k/pkg/platform"
+ "github.com/apache/camel-k/pkg/util/log"
"github.com/apache/camel-k/pkg/util/monitoring"
)
@@ -180,7 +180,6 @@ func (r *ReconcileKameletBinding) Reconcile(ctx context.Context, request reconci
NewMonitorAction(),
}
- var targetPhase v1alpha1.KameletBindingPhase
var err error
target := instance.DeepCopy()
@@ -193,31 +192,21 @@ func (r *ReconcileKameletBinding) Reconcile(ctx context.Context, request reconci
if a.CanHandle(target) {
targetLog.Infof("Invoking action %s", a.Name())
- phaseFrom := target.Status.Phase
-
target, err = a.Handle(ctx, target)
if err != nil {
camelevent.NotifyKameletBindingError(ctx, r.client, r.recorder, &instance, target, err)
+ // Update the kameletbinding (mostly just to update its phase) if the new instance is returned
+ if target != nil {
+ _ = r.update(ctx, &instance, target, &targetLog)
+ }
return reconcile.Result{}, err
}
if target != nil {
- target.Status.ObservedGeneration = instance.Generation
-
- if err := r.client.Status().Patch(ctx, target, ctrl.MergeFrom(&instance)); err != nil {
+ if err := r.update(ctx, &instance, target, &targetLog); err != nil {
camelevent.NotifyKameletBindingError(ctx, r.client, r.recorder, &instance, target, err)
return reconcile.Result{}, err
}
-
- targetPhase = target.Status.Phase
-
- if targetPhase != phaseFrom {
- targetLog.Info(
- "state transition",
- "phase-from", phaseFrom,
- "phase-to", target.Status.Phase,
- )
- }
}
// handle one action at time so the resource
@@ -227,12 +216,24 @@ func (r *ReconcileKameletBinding) Reconcile(ctx context.Context, request reconci
}
}
- if targetPhase == v1alpha1.KameletBindingPhaseReady {
- return reconcile.Result{}, nil
+ return reconcile.Result{}, nil
+}
+
+func (r *ReconcileKameletBinding) update(ctx context.Context, base *v1alpha1.KameletBinding, target *v1alpha1.KameletBinding, log *log.Logger) error {
+ target.Status.ObservedGeneration = base.Generation
+
+ if err := r.client.Status().Patch(ctx, target, ctrl.MergeFrom(base)); err != nil {
+ camelevent.NotifyKameletBindingError(ctx, r.client, r.recorder, base, target, err)
+ return err
}
- // Requeue
- return reconcile.Result{
- RequeueAfter: 5 * time.Second,
- }, nil
+ if target.Status.Phase != base.Status.Phase {
+ log.Info(
+ "state transition",
+ "phase-from", base.Status.Phase,
+ "phase-to", target.Status.Phase,
+ )
+ }
+
+ return nil
}
diff --git a/pkg/controller/kameletbinding/monitor.go b/pkg/controller/kameletbinding/monitor.go
index 04a4e546c..752342b1f 100644
--- a/pkg/controller/kameletbinding/monitor.go
+++ b/pkg/controller/kameletbinding/monitor.go
@@ -49,7 +49,8 @@ func (action *monitorAction) Name() string {
func (action *monitorAction) CanHandle(kameletbinding *v1alpha1.KameletBinding) bool {
return kameletbinding.Status.Phase == v1alpha1.KameletBindingPhaseCreating ||
- kameletbinding.Status.Phase == v1alpha1.KameletBindingPhaseError ||
+ (kameletbinding.Status.Phase == v1alpha1.KameletBindingPhaseError &&
+ kameletbinding.Status.GetCondition(v1alpha1.KameletBindingIntegrationConditionError) == nil) ||
kameletbinding.Status.Phase == v1alpha1.KameletBindingPhaseReady
}
@@ -85,7 +86,10 @@ func (action *monitorAction) Handle(ctx context.Context, kameletbinding *v1alpha
// Check if the integration needs to be changed
expected, err := CreateIntegrationFor(ctx, action.client, kameletbinding)
if err != nil {
- return nil, err
+ kameletbinding.Status.Phase = v1alpha1.KameletBindingPhaseError
+ kameletbinding.Status.SetErrorCondition(v1alpha1.KameletBindingIntegrationConditionError,
+ "Couldn't create an Integration custom resource", err)
+ return kameletbinding, err
}
semanticEquality := equality.Semantic.DeepDerivative(expected.Spec, it.Spec)