@@ -294,7 +294,7 @@ func (r *PGClusterReconciler) Reconcile(ctx context.Context, request reconcile.R
294294 }
295295
296296 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 {
298298 var err error
299299 opRes , err = controllerutil .CreateOrUpdate (ctx , r .Client , postgresCluster , func () error {
300300 var err error
@@ -334,7 +334,44 @@ func (r *PGClusterReconciler) reconcilePatroniVersionCheck(ctx context.Context,
334334 cr .Annotations = make (map [string ]string )
335335 }
336336
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 != "" {
338375 cr .Annotations [pNaming .AnnotationPatroniVersion ] = cr .Status .PatroniVersion
339376 return nil
340377 }
@@ -348,7 +385,7 @@ func (r *PGClusterReconciler) reconcilePatroniVersionCheck(ctx context.Context,
348385 ObjectMeta : meta ,
349386 }
350387
351- err : = r .Client .Get (ctx , client .ObjectKeyFromObject (p ), p )
388+ err = r .Client .Get (ctx , client .ObjectKeyFromObject (p ), p )
352389 if client .IgnoreNotFound (err ) != nil {
353390 return errors .Wrap (err , "failed to get patroni version check pod" )
354391 }
@@ -418,6 +455,7 @@ func (r *PGClusterReconciler) reconcilePatroniVersionCheck(ctx context.Context,
418455
419456 cr .Status .PatroniVersion = patroniVersion
420457 cr .Status .Postgres .Version = cr .Spec .PostgresVersion
458+ cr .Status .Postgres .ImageID = getImageIDFromPod (p , pNaming .ContainerPatroniVersionCheck )
421459
422460 if err := r .Client .Status ().Patch (ctx , cr .DeepCopy (), client .MergeFrom (orig )); err != nil {
423461 return errors .Wrap (err , "failed to patch patroni version" )
0 commit comments