@@ -14,6 +14,8 @@ import (
1414 "github.com/fluxcd/pkg/apis/meta"
1515 "github.com/fluxcd/pkg/runtime/conditions"
1616 "github.com/fluxcd/pkg/runtime/patch"
17+ rreconcile "github.com/fluxcd/pkg/runtime/reconcile"
18+ "github.com/open-component-model/ocm-controller/pkg/status"
1719 corev1 "k8s.io/api/core/v1"
1820 apierrors "k8s.io/apimachinery/pkg/api/errors"
1921 "k8s.io/apimachinery/pkg/runtime"
@@ -22,7 +24,6 @@ import (
2224 ctrl "sigs.k8s.io/controller-runtime"
2325 "sigs.k8s.io/controller-runtime/pkg/builder"
2426 "sigs.k8s.io/controller-runtime/pkg/client"
25- "sigs.k8s.io/controller-runtime/pkg/log"
2627 "sigs.k8s.io/controller-runtime/pkg/predicate"
2728
2829 ocmv1 "github.com/open-component-model/ocm-controller/api/v1alpha1"
@@ -56,8 +57,6 @@ type SyncReconciler struct {
5657// Reconcile is part of the main kubernetes reconciliation loop which aims to
5758// move the current state of the cluster closer to the desired state.
5859func (r * SyncReconciler ) Reconcile (ctx context.Context , req ctrl.Request ) (_ ctrl.Result , err error ) {
59- log := log .FromContext (ctx )
60-
6160 obj := & v1alpha1.Sync {}
6261 if err = r .Get (ctx , req .NamespacedName , obj ); err != nil {
6362 if apierrors .IsNotFound (err ) {
@@ -66,7 +65,6 @@ func (r *SyncReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctr
6665
6766 return ctrl.Result {}, fmt .Errorf ("failed to get git sync object: %w" , err )
6867 }
69- log .V (4 ).Info ("found reconciling object" , "sync" , obj )
7068
7169 // The replication controller doesn't need a shouldReconcile, because it should always reconcile,
7270 // that is its purpose.
@@ -79,39 +77,46 @@ func (r *SyncReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctr
7977 return
8078 }
8179
82- // Set status observed generation option if the component is stalled or ready.
83- if conditions .IsReady (obj ) {
84- obj .Status .ObservedGeneration = obj .Generation
85- }
86-
87- // Update the object.
88- if perr := patchHelper .Patch (ctx , obj ); perr != nil {
89- err = errors .Join (err , perr )
80+ if derr := status .UpdateStatus (ctx , patchHelper , obj , r .EventRecorder , obj .GetRequeueAfter ()); derr != nil {
81+ err = errors .Join (err , derr )
9082 }
9183 }()
9284
85+ // Starts the progression by setting ReconcilingCondition.
86+ // This will be checked in defer.
87+ // Should only be deleted on a success.
88+ rreconcile .ProgressiveStatus (false , obj , meta .ProgressingReason , "reconciliation in progress for resource: %s" , obj .Name )
89+
9390 // it's important that this happens here so any residual status condition can be overwritten / set.
9491 if obj .Status .Digest != "" {
95- log .Info ("Sync object already synced; status contains digest information" , "digest" , obj .Status .Digest )
9692 event .New (r .EventRecorder , obj , eventv1 .EventSeverityInfo , fmt .Sprintf ("sync object already synced with digest %s" , obj .Status .Digest ), nil )
9793 conditions .MarkTrue (obj , meta .ReadyCondition , meta .SucceededReason , "Reconciliation success" )
9894
9995 return ctrl.Result {}, nil
10096 }
10197
98+ if obj .Generation != obj .Status .ObservedGeneration {
99+ rreconcile .ProgressiveStatus (
100+ false ,
101+ obj ,
102+ meta .ProgressingReason ,
103+ "processing object: new generation %d -> %d" ,
104+ obj .Status .ObservedGeneration ,
105+ obj .Generation ,
106+ )
107+ }
108+
102109 snapshot := & ocmv1.Snapshot {}
103110 if err = r .Get (ctx , types.NamespacedName {
104111 Namespace : obj .Namespace ,
105112 Name : obj .Spec .SnapshotRef .Name ,
106113 }, snapshot ); err != nil {
107114 err = fmt .Errorf ("failed to find snapshot: %w" , err )
108- r . markAndEmitEvent ( obj , v1alpha1 .SnapshotGetFailedReason , err )
115+ status . MarkNotReady ( r . EventRecorder , obj , v1alpha1 .SnapshotGetFailedReason , err . Error () )
109116
110117 return ctrl.Result {}, err
111118 }
112119
113- log .V (4 ).Info ("found target snapshot" )
114-
115120 namespace := obj .Spec .RepositoryRef .Namespace
116121 if namespace == "" {
117122 namespace = obj .Namespace
@@ -123,26 +128,22 @@ func (r *SyncReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctr
123128 Name : obj .Spec .RepositoryRef .Name ,
124129 }, repository ); err != nil {
125130 err = fmt .Errorf ("failed to find repository: %w" , err )
126- r . markAndEmitEvent ( obj , v1alpha1 .RepositoryGetFailedReason , err )
131+ status . MarkNotReady ( r . EventRecorder , obj , v1alpha1 .RepositoryGetFailedReason , err . Error () )
127132
128133 return ctrl.Result {}, err
129134 }
130135
131- log .V (4 ).Info ("found target repository" )
132-
133136 authSecret := & corev1.Secret {}
134137 if err = r .Get (ctx , types.NamespacedName {
135138 Namespace : repository .Namespace ,
136139 Name : repository .Spec .Credentials .SecretRef .Name ,
137140 }, authSecret ); err != nil {
138141 err = fmt .Errorf ("failed to find authentication secret: %w" , err )
139- r . markAndEmitEvent ( obj , v1alpha1 .CredentialsNotFoundReason , err )
142+ status . MarkNotReady ( r . EventRecorder , obj , v1alpha1 .CredentialsNotFoundReason , err . Error () )
140143
141144 return ctrl.Result {}, err
142145 }
143146
144- log .V (4 ).Info ("found authentication secret" )
145-
146147 baseBranch := obj .Spec .CommitTemplate .BaseBranch
147148 if baseBranch == "" {
148149 baseBranch = "main"
@@ -153,15 +154,13 @@ func (r *SyncReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctr
153154 targetBranch = fmt .Sprintf ("branch-%d" , time .Now ().Unix ())
154155 } else if targetBranch == "" && ! obj .Spec .AutomaticPullRequestCreation {
155156 err = fmt .Errorf ("branch cannot be empty if automatic pull request creation is not enabled" )
156- r . markAndEmitEvent ( obj , v1alpha1 .GitRepositoryPushFailedReason , err )
157+ status . MarkNotReady ( r . EventRecorder , obj , v1alpha1 .GitRepositoryPushFailedReason , err . Error () )
157158
158159 return ctrl.Result {}, err
159160 }
160161
161- log . Info ( "preparing to push snapshot content" , " base" , baseBranch , " target" , targetBranch )
162+ rreconcile . ProgressiveStatus ( false , obj , meta . ProgressingReason , "preparing to push snapshot content with base branch %s and target %s" , baseBranch , targetBranch )
162163
163- // trim any trailing `/` and then just add.
164- log .V (4 ).Info ("crafting artifact URL to download from" , "url" , snapshot .Status .RepositoryURL )
165164 opts := & pkg.PushOptions {
166165 URL : repository .GetRepositoryURL (),
167166 Message : obj .Spec .CommitTemplate .Message ,
@@ -179,41 +178,33 @@ func (r *SyncReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctr
179178 digest , err = r .Git .Push (ctx , opts )
180179 if err != nil {
181180 err = fmt .Errorf ("failed to push to git repository: %w" , err )
182- r . markAndEmitEvent ( obj , v1alpha1 .GitRepositoryPushFailedReason , err )
181+ status . MarkNotReady ( r . EventRecorder , obj , v1alpha1 .GitRepositoryPushFailedReason , err . Error () )
183182
184183 return ctrl.Result {}, err
185184 }
186185
187- log .Info ("target content pushed with digest" , "base" , baseBranch , "target" , targetBranch , "digest" , digest )
188-
189186 obj .Status .Digest = digest
190187
191188 if obj .Spec .AutomaticPullRequestCreation {
192- log . Info ( "automatic pull-request creation is enabled, preparing to create a pull request" )
189+ rreconcile . ProgressiveStatus ( false , obj , meta . ProgressingReason , "creating pull request" )
193190
194191 id , err := r .Provider .CreatePullRequest (ctx , targetBranch , * obj , * repository )
195192 if err != nil {
196193 err = fmt .Errorf ("failed to create pull request: %w" , err )
197- r . markAndEmitEvent ( obj , v1alpha1 .CreatePullRequestFailedReason , err )
194+ status . MarkNotReady ( r . EventRecorder , obj , v1alpha1 .CreatePullRequestFailedReason , err . Error () )
198195
199196 return ctrl.Result {}, err
200197 }
201198
202199 obj .Status .PullRequestID = id
203200 }
204201
205- log .Info ("successfully reconciled sync object" )
206202 conditions .MarkTrue (obj , meta .ReadyCondition , meta .SucceededReason , "Reconciliation success" )
207203 event .New (r .EventRecorder , obj , eventv1 .EventSeverityInfo , "Reconciliation success" , nil )
208204
209205 return ctrl.Result {}, nil
210206}
211207
212- func (r * SyncReconciler ) markAndEmitEvent (obj * v1alpha1.Sync , reason string , err error ) {
213- event .New (r .EventRecorder , obj , eventv1 .EventSeverityError , err .Error (), nil )
214- conditions .MarkFalse (obj , meta .ReadyCondition , reason , err .Error ())
215- }
216-
217208// SetupWithManager sets up the controller with the Manager.
218209func (r * SyncReconciler ) SetupWithManager (mgr ctrl.Manager ) error {
219210 return ctrl .NewControllerManagedBy (mgr ).
0 commit comments