@@ -294,7 +294,7 @@ func (r *PGClusterReconciler) Reconcile(ctx context.Context, request reconcile.R
294
294
}
295
295
296
296
var opRes controllerutil.OperationResult
297
- if err := retry .RetryOnConflict (retry .DefaultRetry , func () error {
297
+ if err := retry .OnError (retry .DefaultRetry , func ( err error ) bool { return err != nil } , func () error {
298
298
var err error
299
299
opRes , err = controllerutil .CreateOrUpdate (ctx , r .Client , postgresCluster , func () error {
300
300
var err error
@@ -334,7 +334,44 @@ func (r *PGClusterReconciler) reconcilePatroniVersionCheck(ctx context.Context,
334
334
cr .Annotations = make (map [string ]string )
335
335
}
336
336
337
- if cr .Status .Postgres .Version == cr .Spec .PostgresVersion && cr .Status .PatroniVersion != "" {
337
+ // This annotation is used for unit-tests only. Allows to skip the patroni version check
338
+ if _ , ok := cr .Annotations [pNaming .InternalAnnotationDisablePatroniVersionCheck ]; ok {
339
+ cr .Annotations [pNaming .AnnotationPatroniVersion ] = cr .Status .PatroniVersion
340
+ return nil
341
+ }
342
+
343
+ getImageIDFromPod := func (pod * corev1.Pod , containerName string ) string {
344
+ idx := slices .IndexFunc (pod .Status .ContainerStatuses , func (s corev1.ContainerStatus ) bool {
345
+ return s .Name == containerName
346
+ })
347
+ if idx == - 1 {
348
+ return ""
349
+ }
350
+ return pod .Status .ContainerStatuses [idx ].ImageID
351
+ }
352
+
353
+ pods := new (corev1.PodList )
354
+ instances , err := naming .AsSelector (naming .ClusterInstances (cr .Name ))
355
+ if err != nil {
356
+ return err
357
+ }
358
+ if err = r .Client .List (ctx , pods , client .InNamespace (cr .Namespace ), client.MatchingLabelsSelector {Selector : instances }); err != nil {
359
+ return err
360
+ }
361
+
362
+ // Collecting all image IDs from instance pods. Under normal conditions, this slice will contain a single image ID, as all pods typically use the same image.
363
+ // During an image update, it may contain multiple different image IDs as the update progresses.
364
+ imageIDs := []string {}
365
+ for _ , pod := range pods .Items {
366
+ imageID := getImageIDFromPod (& pod , naming .ContainerDatabase )
367
+ if imageID != "" && ! slices .Contains (imageIDs , imageID ) {
368
+ imageIDs = append (imageIDs , imageID )
369
+ }
370
+ }
371
+
372
+ // If the imageIDs slice contains the imageID from the status, we skip checking the Patroni version.
373
+ // This ensures that the Patroni version is only checked after all pods have been updated.
374
+ if slices .Contains (imageIDs , cr .Status .Postgres .ImageID ) && cr .Status .PatroniVersion != "" {
338
375
cr .Annotations [pNaming .AnnotationPatroniVersion ] = cr .Status .PatroniVersion
339
376
return nil
340
377
}
@@ -348,7 +385,7 @@ func (r *PGClusterReconciler) reconcilePatroniVersionCheck(ctx context.Context,
348
385
ObjectMeta : meta ,
349
386
}
350
387
351
- err : = r .Client .Get (ctx , client .ObjectKeyFromObject (p ), p )
388
+ err = r .Client .Get (ctx , client .ObjectKeyFromObject (p ), p )
352
389
if client .IgnoreNotFound (err ) != nil {
353
390
return errors .Wrap (err , "failed to get patroni version check pod" )
354
391
}
@@ -418,6 +455,7 @@ func (r *PGClusterReconciler) reconcilePatroniVersionCheck(ctx context.Context,
418
455
419
456
cr .Status .PatroniVersion = patroniVersion
420
457
cr .Status .Postgres .Version = cr .Spec .PostgresVersion
458
+ cr .Status .Postgres .ImageID = getImageIDFromPod (p , pNaming .ContainerPatroniVersionCheck )
421
459
422
460
if err := r .Client .Status ().Patch (ctx , cr .DeepCopy (), client .MergeFrom (orig )); err != nil {
423
461
return errors .Wrap (err , "failed to patch patroni version" )
0 commit comments