@@ -14,6 +14,12 @@ import (
1414 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
1515)
1616
17+ // Custom Resources that uses "status" subresource
18+ // must implement this interface.
19+ type StatusPatchGenerator interface {
20+ GenerateStatusPatch (previousState runtime.Object ) client.Patch
21+ }
22+
1723func SetupReconciler [T any , PT interface {
1824 * T
1925 client.Object
@@ -61,10 +67,12 @@ func (r *Reconciler[T, PT]) Reconcile(ctx gocontext.Context, req ctrl.Request) (
6167 return ctrl.Result {}, err
6268 }
6369
70+ original := obj .DeepCopyObject ()
71+
6472 resourceName := fmt .Sprintf ("%s[%s]" , obj .GetObjectKind ().GroupVersionKind ().Kind , obj .GetUID ())
6573
6674 if ! obj .GetDeletionTimestamp ().IsZero () {
67- logger .Infof ("[kopper] deleting %s" , resourceName )
75+ logger .V ( 2 ). Infof ("[kopper] deleting %s" , resourceName )
6876 if err := r .OnDeleteFunc (r .DutyContext , string (obj .GetUID ())); err != nil {
6977 logger .Errorf ("[kopper] failed to delete %s: %v" , resourceName , err )
7078 return ctrl.Result {Requeue : true , RequeueAfter : 2 * time .Minute }, err
@@ -86,14 +94,24 @@ func (r *Reconciler[T, PT]) Reconcile(ctx gocontext.Context, req ctrl.Request) (
8694 return ctrl.Result {Requeue : true , RequeueAfter : 2 * time .Minute }, err
8795 }
8896
89- if err := r .Status ().Update (r .DutyContext , obj ); err != nil {
90- logger .Errorf ("[kopper] failed to update status %s: %v" , resourceName , err )
91- return ctrl.Result {Requeue : true , RequeueAfter : 2 * time .Minute }, err
97+ if mgr , ok := any (obj ).(StatusPatchGenerator ); ok {
98+ if patch := mgr .GenerateStatusPatch (original ); patch != nil {
99+ if err := r .Status ().Patch (r .DutyContext , obj , patch ); err != nil {
100+ logger .Errorf ("[kopper] failed to update status %s: %v" , resourceName , err )
101+ return ctrl.Result {Requeue : true , RequeueAfter : 2 * time .Minute }, err
102+ }
103+ }
104+ } else {
105+ // TODO: only for backward compatibility
106+ // remove later ..
107+ if err := r .Status ().Update (r .DutyContext , obj ); err != nil {
108+ logger .Errorf ("[kopper] failed to update status %s: %v" , resourceName , err )
109+ return ctrl.Result {Requeue : true , RequeueAfter : 2 * time .Minute }, err
110+ }
92111 }
93112
94- logger .Infof ("[kopper] upserted %s" , resourceName )
113+ logger .V ( 2 ). Infof ("[kopper] upserted %s" , resourceName )
95114 return ctrl.Result {}, nil
96-
97115}
98116
99117// SetupWithManager sets up the controller with the Manager.
0 commit comments