77 "math"
88 "slices"
99 "strconv"
10- "strings"
1110 "time"
1211
1312 "gopkg.in/yaml.v2"
@@ -560,7 +559,6 @@ func (r *keeperReconciler) evaluateReplicaConditions() {
560559 var errorIDs , notReadyIDs , notUpdatedIDs []string
561560
562561 replicasByMode := map [string ][]v1.KeeperReplicaID {}
563- replicaVersions := map [string ]string {}
564562
565563 r .Cluster .Status .ReadyReplicas = 0
566564 for id , replica := range r .ReplicaState {
@@ -580,18 +578,12 @@ func (r *keeperReconciler) evaluateReplicaConditions() {
580578 if replica .HasDiff (r .revs ) || ! replica .Updated () {
581579 notUpdatedIDs = append (notUpdatedIDs , idStr )
582580 }
583-
584- if replica .Status .Version != "" {
585- replicaVersions [idStr ] = replica .Status .Version
586- }
587581 }
588582
589583 r .SetCondition (chctrl .ReplicaStartupCondition (errorIDs ))
590584 r .SetCondition (chctrl .HealthyCondition (notReadyIDs ))
591585 r .SetCondition (chctrl .ConfigSyncCondition (nil , notUpdatedIDs , nil ))
592- versionCond , versionEvents := keeperVersionSyncCondition (replicaVersions , len (notUpdatedIDs ) > 0 )
593- r .SetCondition (versionCond , versionEvents ... )
594- r .evaluateUpgradeCondition (replicaVersions )
586+ r .evaluateVersionConditions (len (notUpdatedIDs ) > 0 )
595587
596588 // Ready condition — keeper-specific logic.
597589 exists := len (r .ReplicaState )
@@ -670,75 +662,51 @@ func (r *keeperReconciler) evaluateReplicaConditions() {
670662 )
671663}
672664
673- func (r * keeperReconciler ) evaluateUpgradeCondition (replicaVersions map [string ]string ) {
674- version , ok := keeperObservedVersion (replicaVersions )
675- if ok {
676- r .Cluster .Status .Version = version
677- }
678-
679- if r .Checker == nil || ! ok {
680- meta .RemoveStatusCondition (r .Cluster .GetStatus ().GetConditions (), v1 .ConditionTypeVersionUpgraded )
681- return
682- }
683-
684- cond , event := chctrl .GetUpgradeCondition (* r .Checker , chctrl.VersionProbeResult {Version : version }, r .Cluster .Spec .UpgradeChannel )
685- r .SetCondition (cond , event ... )
686- }
665+ func (r * keeperReconciler ) evaluateVersionConditions (isUpdating bool ) {
666+ versionByReplica := map [string ]string {}
667+ distinct := map [string ]struct {}{}
668+ observedVersion := ""
687669
688- func keeperVersionSyncCondition (replicaVersions map [string ]string , isUpdating bool ) (metav1.Condition , []chctrl.EventSpec ) {
689- newCond := func (status metav1.ConditionStatus , reason v1.ConditionReason , message string ) metav1.Condition {
690- return metav1.Condition {
691- Type : v1 .ConditionTypeVersionInSync ,
692- Status : status ,
693- Reason : reason ,
694- Message : message ,
670+ for id , s := range r .ReplicaState {
671+ if s .Status .Version != "" {
672+ versionByReplica [strconv .FormatInt (int64 (id ), 10 )] = s .Status .Version
673+ distinct [s .Status .Version ] = struct {}{}
674+ observedVersion = s .Status .Version
695675 }
696676 }
697677
698- if len (replicaVersions ) == 0 {
699- return newCond (metav1 .ConditionUnknown , v1 .ConditionReasonVersionPending , "No Keeper replica version has been observed yet" ), nil
678+ // Record the version only when all observed replicas agree, otherwise keep the last known one.
679+ if len (distinct ) == 1 {
680+ r .Cluster .Status .Version = observedVersion
700681 }
701682
702- var observed []string
703- for id , version := range replicaVersions {
704- observed = append (observed , fmt .Sprintf ("%s: %s" , id , version ))
705- }
683+ // No running replica has reported a version yet — report pending and skip evaluation.
684+ if len (versionByReplica ) == 0 {
685+ r .SetCondition (metav1.Condition {
686+ Type : v1 .ConditionTypeVersionInSync ,
687+ Status : metav1 .ConditionUnknown ,
688+ Reason : v1 .ConditionReasonVersionPending ,
689+ Message : "No Keeper replica has reported a version yet" ,
690+ })
691+ meta .RemoveStatusCondition (r .Cluster .GetStatus ().GetConditions (), v1 .ConditionTypeVersionUpgraded )
706692
707- if version , ok := keeperObservedVersion (replicaVersions ); ok {
708- return newCond (metav1 .ConditionTrue , v1 .ConditionReasonVersionMatch ,
709- "All observed Keeper replicas report version " + version ), nil
693+ return
710694 }
711695
712- slices .Sort (observed )
713- cond := newCond (metav1 .ConditionFalse , v1 .ConditionReasonVersionMismatch ,
714- "Keeper replica versions differ: " + strings .Join (observed , ", " ))
715-
716- if isUpdating {
717- return cond , nil
696+ version := r .Cluster .Status .Version
697+ if version == "" {
698+ version = observedVersion
718699 }
719700
720- return cond , []chctrl.EventSpec {{
721- Type : corev1 .EventTypeWarning ,
722- Reason : v1 .EventReasonVersionDiverge ,
723- Action : v1 .EventActionVersionCheck ,
724- Message : cond .Message ,
725- }}
726- }
727-
728- func keeperObservedVersion (replicaVersions map [string ]string ) (string , bool ) {
729- var result string
730- for _ , version := range replicaVersions {
731- if result == "" {
732- result = version
733- continue
734- }
701+ cond , event := chctrl .GetVersionSyncCondition (version , versionByReplica , isUpdating )
702+ r .SetCondition (cond , event ... )
735703
736- if version != result {
737- return "" , false
738- }
704+ if r .Checker != nil {
705+ cond , event = chctrl .GetUpgradeCondition (* r .Checker , version , r .Cluster .Spec .UpgradeChannel )
706+ r .SetCondition (cond , event ... )
707+ } else {
708+ meta .RemoveStatusCondition (r .Cluster .GetStatus ().GetConditions (), v1 .ConditionTypeVersionUpgraded )
739709 }
740-
741- return result , result != ""
742710}
743711
744712func (r * keeperReconciler ) updateReplica (ctx context.Context , log ctrlutil.Logger , replicaID v1.KeeperReplicaID ) (* ctrl.Result , error ) {
0 commit comments