mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-19 04:26:39 +00:00
fix: update CR's status with retry.RetryOnConflict (#1015)
This commit is contained in:
@@ -27,6 +27,8 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/util/retry"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
@@ -77,13 +79,13 @@ func (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
||||
app.Status.Phase = v1alpha2.ApplicationRollingOut
|
||||
app.Status.SetConditions(readyCondition("Rolling"))
|
||||
// do not process apps still in rolling out
|
||||
return ctrl.Result{RequeueAfter: RolloutReconcileWaitTime}, r.Status().Update(ctx, app)
|
||||
return ctrl.Result{RequeueAfter: RolloutReconcileWaitTime}, r.UpdateStatus(ctx, app)
|
||||
}
|
||||
|
||||
applog.Info("Start Rendering")
|
||||
|
||||
app.Status.Phase = v1alpha2.ApplicationRendering
|
||||
handler := &appHandler{r.Client, app, applog}
|
||||
handler := &appHandler{r, app, applog}
|
||||
|
||||
app.Status.Conditions = []v1alpha1.Condition{}
|
||||
|
||||
@@ -149,7 +151,7 @@ func (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
||||
})
|
||||
}
|
||||
app.Status.Components = refComps
|
||||
return ctrl.Result{}, r.Status().Update(ctx, app)
|
||||
return ctrl.Result{}, r.UpdateStatus(ctx, app)
|
||||
}
|
||||
|
||||
// SetupWithManager install to manager
|
||||
@@ -160,6 +162,18 @@ func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
Complete(r)
|
||||
}
|
||||
|
||||
// UpdateStatus updates v1alpha2.Application's Status with retry.RetryOnConflict
|
||||
func (r *Reconciler) UpdateStatus(ctx context.Context, app *v1alpha2.Application, opts ...client.UpdateOption) error {
|
||||
status := app.DeepCopy().Status
|
||||
return retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
|
||||
if err = r.Get(ctx, types.NamespacedName{Namespace: app.Namespace, Name: app.Name}, app); err != nil {
|
||||
return
|
||||
}
|
||||
app.Status = status
|
||||
return r.Status().Update(ctx, app, opts...)
|
||||
})
|
||||
}
|
||||
|
||||
// Setup adds a controller that reconciles ApplicationDeployment.
|
||||
func Setup(mgr ctrl.Manager, _ core.Args, _ logging.Logger) error {
|
||||
dm, err := discoverymapper.New(mgr.GetConfig())
|
||||
|
||||
@@ -40,13 +40,13 @@ func readyCondition(tpy string) runtimev1alpha1.Condition {
|
||||
}
|
||||
|
||||
type appHandler struct {
|
||||
c client.Client
|
||||
r *Reconciler
|
||||
app *v1alpha2.Application
|
||||
l logr.Logger
|
||||
}
|
||||
|
||||
func (ret *appHandler) Err(err error) (ctrl.Result, error) {
|
||||
nerr := ret.c.Status().Update(context.Background(), ret.app)
|
||||
nerr := ret.r.UpdateStatus(context.Background(), ret.app)
|
||||
if err == nil && nerr == nil {
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
@@ -92,7 +92,7 @@ func (ret *appHandler) statusAggregate(appfile *appfile.Appfile) ([]v1alpha2.App
|
||||
}
|
||||
}
|
||||
|
||||
workloadHealth, err := wl.EvalHealth(pCtx, ret.c, ret.app.Namespace)
|
||||
workloadHealth, err := wl.EvalHealth(pCtx, ret.r, ret.app.Namespace)
|
||||
if err != nil {
|
||||
return nil, false, errors.WithMessagef(err, "app=%s, comp=%s, check health error", appfile.Name, wl.Name)
|
||||
}
|
||||
@@ -101,7 +101,7 @@ func (ret *appHandler) statusAggregate(appfile *appfile.Appfile) ([]v1alpha2.App
|
||||
status.Healthy = false
|
||||
healthy = false
|
||||
}
|
||||
status.Message, err = wl.EvalStatus(pCtx, ret.c, ret.app.Namespace)
|
||||
status.Message, err = wl.EvalStatus(pCtx, ret.r, ret.app.Namespace)
|
||||
if err != nil {
|
||||
return nil, false, errors.WithMessagef(err, "app=%s, comp=%s, evaluate workload status message error", appfile.Name, wl.Name)
|
||||
}
|
||||
@@ -111,7 +111,7 @@ func (ret *appHandler) statusAggregate(appfile *appfile.Appfile) ([]v1alpha2.App
|
||||
Type: trait.Name,
|
||||
Healthy: true,
|
||||
}
|
||||
traitHealth, err := trait.EvalHealth(pCtx, ret.c, ret.app.Namespace)
|
||||
traitHealth, err := trait.EvalHealth(pCtx, ret.r, ret.app.Namespace)
|
||||
if err != nil {
|
||||
return nil, false, errors.WithMessagef(err, "app=%s, comp=%s, trait=%s, check health error", appfile.Name, wl.Name, trait.Name)
|
||||
}
|
||||
@@ -120,7 +120,7 @@ func (ret *appHandler) statusAggregate(appfile *appfile.Appfile) ([]v1alpha2.App
|
||||
traitStatus.Healthy = false
|
||||
healthy = false
|
||||
}
|
||||
traitStatus.Message, err = trait.EvalStatus(pCtx, ret.c, ret.app.Namespace)
|
||||
traitStatus.Message, err = trait.EvalStatus(pCtx, ret.r, ret.app.Namespace)
|
||||
if err != nil {
|
||||
return nil, false, errors.WithMessagef(err, "app=%s, comp=%s, trait=%s, evaluate status message error", appfile.Name, wl.Name, trait.Name)
|
||||
}
|
||||
@@ -167,12 +167,12 @@ func CreateOrUpdateAppConfig(ctx context.Context, client client.Client, appConfi
|
||||
// Sync perform synchronization operations
|
||||
func (ret *appHandler) Sync(ctx context.Context, ac *v1alpha2.ApplicationConfiguration, comps []*v1alpha2.Component) error {
|
||||
for _, comp := range comps {
|
||||
if err := CreateOrUpdateComponent(ctx, ret.c, comp.DeepCopy()); err != nil {
|
||||
if err := CreateOrUpdateComponent(ctx, ret.r, comp.DeepCopy()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := CreateOrUpdateAppConfig(ctx, ret.c, ac); err != nil {
|
||||
if err := CreateOrUpdateAppConfig(ctx, ret.r, ac); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ func (ret *appHandler) Sync(ctx context.Context, ac *v1alpha2.ApplicationConfigu
|
||||
}
|
||||
// Component not exits in current Application, should be deleted
|
||||
var oldC = &v1alpha2.Component{ObjectMeta: metav1.ObjectMeta{Name: comp.Name, Namespace: ac.Namespace}}
|
||||
if err := ret.c.Delete(ctx, oldC); err != nil {
|
||||
if err := ret.r.Delete(ctx, oldC); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
+21
-7
@@ -27,6 +27,8 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/util/retry"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
@@ -245,7 +247,7 @@ func (r *OAMApplicationReconciler) Reconcile(req reconcile.Request) (result reco
|
||||
"error", err, "requeue-after", result.RequeueAfter)
|
||||
r.record.Event(ac, event.Warning(reasonCannotFinalizeWorkloads, err))
|
||||
ac.SetConditions(v1alpha1.ReconcileError(errors.Wrap(err, errFinalizeWorkloads)))
|
||||
return reconcile.Result{}, errors.Wrap(r.client.Status().Update(ctx, ac), errUpdateAppConfigStatus)
|
||||
return reconcile.Result{}, errors.Wrap(r.UpdateStatus(ctx, ac), errUpdateAppConfigStatus)
|
||||
}
|
||||
return reconcile.Result{}, errors.Wrap(r.client.Update(ctx, ac), errUpdateAppConfigStatus)
|
||||
}
|
||||
@@ -260,12 +262,12 @@ func (r *OAMApplicationReconciler) Reconcile(req reconcile.Request) (result reco
|
||||
r.record.Event(ac, event.Warning(reasonCannotExecutePosthooks, err))
|
||||
ac.SetConditions(v1alpha1.ReconcileError(errors.Wrap(err, errExecutePosthooks)))
|
||||
result = exeResult
|
||||
returnErr = errors.Wrap(r.client.Status().Update(ctx, ac), errUpdateAppConfigStatus)
|
||||
returnErr = errors.Wrap(r.UpdateStatus(ctx, ac), errUpdateAppConfigStatus)
|
||||
return
|
||||
}
|
||||
r.record.Event(ac, event.Normal(reasonExecutePosthook, "Successfully executed a posthook", "posthook name", name))
|
||||
}
|
||||
returnErr = errors.Wrap(r.client.Status().Update(ctx, ac), errUpdateAppConfigStatus)
|
||||
returnErr = errors.Wrap(r.UpdateStatus(ctx, ac), errUpdateAppConfigStatus)
|
||||
|
||||
// Make sure if error occurs, reconcile will not happen too frequency
|
||||
if returnErr != nil && result.RequeueAfter < shortWait {
|
||||
@@ -280,7 +282,7 @@ func (r *OAMApplicationReconciler) Reconcile(req reconcile.Request) (result reco
|
||||
log.Debug("Failed to execute pre-hooks", "hook name", name, "error", err, "requeue-after", result.RequeueAfter)
|
||||
r.record.Event(ac, event.Warning(reasonCannotExecutePrehooks, err))
|
||||
ac.SetConditions(v1alpha1.ReconcileError(errors.Wrap(err, errExecutePrehooks)))
|
||||
return result, errors.Wrap(r.client.Status().Update(ctx, ac), errUpdateAppConfigStatus)
|
||||
return result, errors.Wrap(r.UpdateStatus(ctx, ac), errUpdateAppConfigStatus)
|
||||
}
|
||||
r.record.Event(ac, event.Normal(reasonExecutePrehook, "Successfully executed a prehook", "prehook name ", name))
|
||||
}
|
||||
@@ -292,7 +294,7 @@ func (r *OAMApplicationReconciler) Reconcile(req reconcile.Request) (result reco
|
||||
log.Info("Cannot render components", "error", err, "requeue-after", time.Now().Add(shortWait))
|
||||
r.record.Event(ac, event.Warning(reasonCannotRenderComponents, err))
|
||||
ac.SetConditions(v1alpha1.ReconcileError(errors.Wrap(err, errRenderComponents)))
|
||||
return errResult, errors.Wrap(r.client.Status().Update(ctx, ac), errUpdateAppConfigStatus)
|
||||
return errResult, errors.Wrap(r.UpdateStatus(ctx, ac), errUpdateAppConfigStatus)
|
||||
}
|
||||
log.Debug("Successfully rendered components", "workloads", len(workloads))
|
||||
r.record.Event(ac, event.Normal(reasonRenderComponents, "Successfully rendered components", "workloads", strconv.Itoa(len(workloads))))
|
||||
@@ -302,7 +304,7 @@ func (r *OAMApplicationReconciler) Reconcile(req reconcile.Request) (result reco
|
||||
log.Debug("Cannot apply components", "error", err, "requeue-after", time.Now().Add(shortWait))
|
||||
r.record.Event(ac, event.Warning(reasonCannotApplyComponents, err))
|
||||
ac.SetConditions(v1alpha1.ReconcileError(errors.Wrap(err, errApplyComponents)))
|
||||
return errResult, errors.Wrap(r.client.Status().Update(ctx, ac), errUpdateAppConfigStatus)
|
||||
return errResult, errors.Wrap(r.UpdateStatus(ctx, ac), errUpdateAppConfigStatus)
|
||||
}
|
||||
log.Debug("Successfully applied components", "workloads", len(workloads))
|
||||
r.record.Event(ac, event.Normal(reasonApplyComponents, "Successfully applied components", "workloads", strconv.Itoa(len(workloads))))
|
||||
@@ -322,7 +324,7 @@ func (r *OAMApplicationReconciler) Reconcile(req reconcile.Request) (result reco
|
||||
log.Debug("Cannot garbage collect component", "error", err, "requeue-after", time.Now().Add(shortWait))
|
||||
record.Event(ac, event.Warning(reasonCannotGGComponents, err))
|
||||
ac.SetConditions(v1alpha1.ReconcileError(errors.Wrap(err, errGCComponent)))
|
||||
return errResult, errors.Wrap(r.client.Status().Update(ctx, ac), errUpdateAppConfigStatus)
|
||||
return errResult, errors.Wrap(r.UpdateStatus(ctx, ac), errUpdateAppConfigStatus)
|
||||
}
|
||||
log.Debug("Garbage collected resource")
|
||||
record.Event(ac, event.Normal(reasonGGComponent, "Successfully garbage collected component"))
|
||||
@@ -342,6 +344,18 @@ func (r *OAMApplicationReconciler) Reconcile(req reconcile.Request) (result reco
|
||||
return reconcile.Result{RequeueAfter: waitTime}, nil
|
||||
}
|
||||
|
||||
// UpdateStatus updates v1alpha2.ApplicationConfiguration's Status with retry.RetryOnConflict
|
||||
func (r *OAMApplicationReconciler) UpdateStatus(ctx context.Context, ac *v1alpha2.ApplicationConfiguration, opts ...client.UpdateOption) error {
|
||||
status := ac.DeepCopy().Status
|
||||
return retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
|
||||
if err = r.client.Get(ctx, types.NamespacedName{Namespace: ac.Namespace, Name: ac.Name}, ac); err != nil {
|
||||
return
|
||||
}
|
||||
ac.Status = status
|
||||
return r.client.Status().Update(ctx, ac, opts...)
|
||||
})
|
||||
}
|
||||
|
||||
func (r *OAMApplicationReconciler) updateStatus(ctx context.Context, ac, acPatch *v1alpha2.ApplicationConfiguration, workloads []Workload) {
|
||||
ac.Status.Workloads = make([]v1alpha2.WorkloadStatus, len(workloads))
|
||||
historyWorkloads := make([]v1alpha2.HistoryWorkload, 0)
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||
@@ -191,7 +192,7 @@ func (c *ComponentHandler) createControllerRevision(mt metav1.Object, obj runtim
|
||||
return nil, false
|
||||
}
|
||||
|
||||
err = c.Client.Status().Update(context.Background(), comp)
|
||||
err = c.UpdateStatus(context.Background(), comp)
|
||||
if err != nil {
|
||||
c.Logger.Info(fmt.Sprintf("update component status latestRevision %s err %v", revisionName, err), "componentName", mt.GetName())
|
||||
return nil, false
|
||||
@@ -277,6 +278,18 @@ func (c *ComponentHandler) cleanupControllerRevision(curComp *v1alpha2.Component
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateStatus updates v1alpha2.Component's Status with retry.RetryOnConflict
|
||||
func (c *ComponentHandler) UpdateStatus(ctx context.Context, comp *v1alpha2.Component, opts ...client.UpdateOption) error {
|
||||
status := comp.DeepCopy().Status
|
||||
return retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
|
||||
if err = c.Client.Get(ctx, types.NamespacedName{Namespace: comp.Namespace, Name: comp.Name}, comp); err != nil {
|
||||
return
|
||||
}
|
||||
comp.Status = status
|
||||
return c.Client.Status().Update(ctx, comp, opts...)
|
||||
})
|
||||
}
|
||||
|
||||
// ConstructRevisionName will generate revisionName from componentName
|
||||
// will be <componentName>-v<RevisionNumber>, for example: comp-v1
|
||||
func ConstructRevisionName(componentName string, revision int64) string {
|
||||
|
||||
+15
-1
@@ -23,6 +23,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/util/retry"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
@@ -172,7 +174,7 @@ func (r *Reconciler) Reconcile(req reconcile.Request) (reconcile.Result, error)
|
||||
hs.Status.ScopeHealthCondition = scopeCondition
|
||||
hs.Status.WorkloadHealthConditions = wlConditions
|
||||
|
||||
return reconcile.Result{RequeueAfter: interval - elapsed}, errors.Wrap(r.client.Status().Update(ctx, hs), errUpdateHealthScopeStatus)
|
||||
return reconcile.Result{RequeueAfter: interval - elapsed}, errors.Wrap(r.UpdateStatus(ctx, hs), errUpdateHealthScopeStatus)
|
||||
}
|
||||
|
||||
// GetScopeHealthStatus get the status of the healthscope based on workload resources.
|
||||
@@ -257,3 +259,15 @@ func (r *Reconciler) GetScopeHealthStatus(ctx context.Context, healthScope *v1al
|
||||
|
||||
return scopeCondition, workloadHealthConditions
|
||||
}
|
||||
|
||||
// UpdateStatus updates v1alpha2.HealthScope's Status with retry.RetryOnConflict
|
||||
func (r *Reconciler) UpdateStatus(ctx context.Context, hs *v1alpha2.HealthScope, opts ...client.UpdateOption) error {
|
||||
status := hs.DeepCopy().Status
|
||||
return retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
|
||||
if err = r.client.Get(ctx, types.NamespacedName{Namespace: hs.Namespace, Name: hs.Name}, hs); err != nil {
|
||||
return
|
||||
}
|
||||
hs.Status = status
|
||||
return r.client.Status().Update(ctx, hs, opts...)
|
||||
})
|
||||
}
|
||||
|
||||
+15
-1
@@ -29,6 +29,8 @@ import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/util/retry"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/builder"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
@@ -172,12 +174,24 @@ func (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
||||
},
|
||||
)
|
||||
|
||||
if err := r.Status().Update(ctx, &workload); err != nil {
|
||||
if err := r.UpdateStatus(ctx, &workload); err != nil {
|
||||
return util.ReconcileWaitResult, err
|
||||
}
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &workload, cpv1alpha1.ReconcileSuccess())
|
||||
}
|
||||
|
||||
// UpdateStatus updates v1alpha2.ContainerizedWorkload's Status with retry.RetryOnConflict
|
||||
func (r *Reconciler) UpdateStatus(ctx context.Context, workload *v1alpha2.ContainerizedWorkload, opts ...client.UpdateOption) error {
|
||||
status := workload.DeepCopy().Status
|
||||
return retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
|
||||
if err = r.Get(ctx, types.NamespacedName{Namespace: workload.Namespace, Name: workload.Name}, workload); err != nil {
|
||||
return
|
||||
}
|
||||
workload.Status = status
|
||||
return r.Status().Update(ctx, workload, opts...)
|
||||
})
|
||||
}
|
||||
|
||||
// SetupWithManager setups up k8s controller.
|
||||
func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
src := &v1alpha2.ContainerizedWorkload{}
|
||||
|
||||
@@ -31,7 +31,9 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"k8s.io/utils/pointer"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
@@ -163,7 +165,7 @@ func (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
||||
|
||||
r.gcOrphanServiceMonitor(ctx, mLog, &metricsTrait)
|
||||
(&metricsTrait).SetConditions(cpv1alpha1.ReconcileSuccess())
|
||||
return ctrl.Result{}, errors.Wrap(r.Status().Update(ctx, &metricsTrait), common.ErrUpdateStatus)
|
||||
return ctrl.Result{}, errors.Wrap(r.UpdateStatus(ctx, &metricsTrait), common.ErrUpdateStatus)
|
||||
}
|
||||
|
||||
// fetch the label of the service that is associated with the workload
|
||||
@@ -336,6 +338,18 @@ func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
Complete(r)
|
||||
}
|
||||
|
||||
// UpdateStatus updates v1alpha1.MetricsTrait's Status with retry.RetryOnConflict
|
||||
func (r *Reconciler) UpdateStatus(ctx context.Context, mt *v1alpha1.MetricsTrait, opts ...client.UpdateOption) error {
|
||||
status := mt.DeepCopy().Status
|
||||
return retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
|
||||
if err = r.Get(ctx, types.NamespacedName{Namespace: mt.Namespace, Name: mt.Name}, mt); err != nil {
|
||||
return
|
||||
}
|
||||
mt.Status = status
|
||||
return r.Status().Update(ctx, mt, opts...)
|
||||
})
|
||||
}
|
||||
|
||||
// Setup adds a controller that reconciles MetricsTrait.
|
||||
func Setup(mgr ctrl.Manager) error {
|
||||
dm, err := discoverymapper.New(mgr.GetConfig())
|
||||
|
||||
+15
-1
@@ -30,7 +30,9 @@ import (
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/client-go/util/retry"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
@@ -151,7 +153,7 @@ func (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
||||
})
|
||||
}
|
||||
|
||||
if err := r.Status().Update(ctx, &workload); err != nil {
|
||||
if err := r.UpdateStatus(ctx, &workload); err != nil {
|
||||
return util.ReconcileWaitResult, err
|
||||
}
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &workload, cpv1alpha1.ReconcileSuccess())
|
||||
@@ -277,6 +279,18 @@ func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
Complete(r)
|
||||
}
|
||||
|
||||
// UpdateStatus updates *v1alpha1.PodSpecWorkload's Status with retry.RetryOnConflict
|
||||
func (r *Reconciler) UpdateStatus(ctx context.Context, workload *v1alpha1.PodSpecWorkload, opts ...client.UpdateOption) error {
|
||||
status := workload.DeepCopy().Status
|
||||
return retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
|
||||
if err = r.Get(ctx, types.NamespacedName{Namespace: workload.Namespace, Name: workload.Name}, workload); err != nil {
|
||||
return
|
||||
}
|
||||
workload.Status = status
|
||||
return r.Status().Update(ctx, workload, opts...)
|
||||
})
|
||||
}
|
||||
|
||||
// Setup adds a controller that reconciles PodSpecWorkload.
|
||||
func Setup(mgr ctrl.Manager) error {
|
||||
reconciler := Reconciler{
|
||||
|
||||
@@ -23,11 +23,10 @@ import (
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/controller/utils"
|
||||
|
||||
standardv1alpha1 "github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/common"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/standard.oam.dev/v1alpha1/routes/ingress"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/utils"
|
||||
|
||||
runtimev1alpha1 "github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
|
||||
"github.com/crossplane/crossplane-runtime/pkg/event"
|
||||
@@ -39,7 +38,9 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"k8s.io/utils/pointer"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
@@ -146,9 +147,9 @@ func (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
||||
routeTrait.Status.Status, conditions = routeIngress.CheckStatus(&routeTrait)
|
||||
routeTrait.Status.Conditions = conditions
|
||||
if routeTrait.Status.Status != ingress.StatusReady {
|
||||
return ctrl.Result{RequeueAfter: requeueNotReady}, r.Status().Update(ctx, &routeTrait)
|
||||
return ctrl.Result{RequeueAfter: requeueNotReady}, r.UpdateStatus(ctx, &routeTrait)
|
||||
}
|
||||
err = r.Status().Update(ctx, &routeTrait)
|
||||
err = r.UpdateStatus(ctx, &routeTrait)
|
||||
if err != nil {
|
||||
return oamutil.ReconcileWaitResult, err
|
||||
}
|
||||
@@ -247,6 +248,18 @@ func (r *Reconciler) fillBackendByCreatedService(ctx context.Context, mLog logr.
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateStatus updates standardv1alpha1.Route's Status with retry.RetryOnConflict
|
||||
func (r *Reconciler) UpdateStatus(ctx context.Context, route *standardv1alpha1.Route, opts ...client.UpdateOption) error {
|
||||
status := route.DeepCopy().Status
|
||||
return retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
|
||||
if err = r.Get(ctx, types.NamespacedName{Namespace: route.Namespace, Name: route.Name}, route); err != nil {
|
||||
return
|
||||
}
|
||||
route.Status = status
|
||||
return r.Status().Update(ctx, route, opts...)
|
||||
})
|
||||
}
|
||||
|
||||
// DiscoverPortsLabel assume the workload or it's childResource will always having spec.template as PodTemplate if discoverable
|
||||
func DiscoverPortsLabel(ctx context.Context, workload *unstructured.Unstructured, r client.Reader, dm discoverymapper.DiscoveryMapper, childResources []*unstructured.Unstructured) ([]intstr.IntOrString, map[string]string, error) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user