77 "math"
88 "slices"
99 "strconv"
10+ "strings"
1011 "time"
1112
1213 "gopkg.in/yaml.v2"
@@ -92,7 +93,6 @@ type keeperReconciler struct {
9293func (r * keeperReconciler ) sync (ctx context.Context , log ctrlutil.Logger ) (ctrl.Result , error ) {
9394 log .Info ("Enter Keeper Reconcile" , "spec" , r .Cluster .Spec , "status" , r .Cluster .Status )
9495
95- meta .RemoveStatusCondition (& r .Cluster .Status .Conditions , v1 .ConditionTypeVersionInSync )
9696 meta .RemoveStatusCondition (& r .Cluster .Status .Conditions , v1 .ConditionTypeVersionUpgraded )
9797
9898 r .SetUnknownConditions (v1 .ConditionReasonStepFailed , "Reconcile stopped before condition evaluation" ,
@@ -101,6 +101,7 @@ func (r *keeperReconciler) sync(ctx context.Context, log ctrlutil.Logger) (ctrl.
101101 v1 .ConditionTypeHealthy ,
102102 v1 .ConditionTypeClusterSizeAligned ,
103103 v1 .ConditionTypeConfigurationInSync ,
104+ v1 .ConditionTypeVersionInSync ,
104105 v1 .ConditionTypeReady ,
105106 v1 .KeeperConditionTypeScaleAllowed ,
106107 })
@@ -565,6 +566,7 @@ func (r *keeperReconciler) evaluateReplicaConditions() {
565566 var errorIDs , notReadyIDs , notUpdatedIDs []string
566567
567568 replicasByMode := map [string ][]v1.KeeperReplicaID {}
569+ replicaVersions := map [string ]string {}
568570
569571 r .Cluster .Status .ReadyReplicas = 0
570572 for id , replica := range r .ReplicaState {
@@ -584,11 +586,17 @@ func (r *keeperReconciler) evaluateReplicaConditions() {
584586 if replica .HasDiff (r .revs ) || ! replica .Updated () {
585587 notUpdatedIDs = append (notUpdatedIDs , idStr )
586588 }
589+
590+ if replica .Status .Version != "" {
591+ replicaVersions [idStr ] = replica .Status .Version
592+ }
587593 }
588594
589595 r .SetCondition (chctrl .ReplicaStartupCondition (errorIDs ))
590596 r .SetCondition (chctrl .HealthyCondition (notReadyIDs ))
591597 r .SetCondition (chctrl .ConfigSyncCondition (nil , notUpdatedIDs , nil ))
598+ versionCond , versionEvents := keeperVersionSyncCondition (replicaVersions , len (notUpdatedIDs ) > 0 )
599+ r .SetCondition (versionCond , versionEvents ... )
592600
593601 // Ready condition — keeper-specific logic.
594602 exists := len (r .ReplicaState )
@@ -667,6 +675,54 @@ func (r *keeperReconciler) evaluateReplicaConditions() {
667675 )
668676}
669677
678+ func keeperVersionSyncCondition (replicaVersions map [string ]string , isUpdating bool ) (metav1.Condition , []chctrl.EventSpec ) {
679+ newCond := func (status metav1.ConditionStatus , reason v1.ConditionReason , message string ) metav1.Condition {
680+ return metav1.Condition {
681+ Type : v1 .ConditionTypeVersionInSync ,
682+ Status : status ,
683+ Reason : reason ,
684+ Message : message ,
685+ }
686+ }
687+
688+ if len (replicaVersions ) == 0 {
689+ return newCond (metav1 .ConditionUnknown , v1 .ConditionReasonVersionPending , "No Keeper replica version has been observed yet" ), nil
690+ }
691+
692+ versions := map [string ]struct {}{}
693+ var observed []string
694+ for id , version := range replicaVersions {
695+ versions [version ] = struct {}{}
696+ observed = append (observed , fmt .Sprintf ("%s: %s" , id , version ))
697+ }
698+
699+ if len (versions ) == 1 {
700+ var version string
701+ for _ , v := range replicaVersions {
702+ version = v
703+ break
704+ }
705+
706+ return newCond (metav1 .ConditionTrue , v1 .ConditionReasonVersionMatch ,
707+ fmt .Sprintf ("All observed Keeper replicas report version %s" , version )), nil
708+ }
709+
710+ slices .Sort (observed )
711+ cond := newCond (metav1 .ConditionFalse , v1 .ConditionReasonVersionMismatch ,
712+ fmt .Sprintf ("Keeper replica versions differ: %s" , strings .Join (observed , ", " )))
713+
714+ if isUpdating {
715+ return cond , nil
716+ }
717+
718+ return cond , []chctrl.EventSpec {{
719+ Type : corev1 .EventTypeWarning ,
720+ Reason : v1 .EventReasonVersionDiverge ,
721+ Action : v1 .EventActionVersionCheck ,
722+ Message : cond .Message ,
723+ }}
724+ }
725+
670726func (r * keeperReconciler ) updateReplica (ctx context.Context , log ctrlutil.Logger , replicaID v1.KeeperReplicaID ) (* ctrl.Result , error ) {
671727 log = log .With ("replica_id" , replicaID )
672728 log .Info ("updating replica" )
0 commit comments