@@ -300,9 +300,6 @@ func (r *Reconciler) getOrCreateSchedulingPolicySnapshot(ctx context.Context, pl
300300 latestPolicySnapshot .GetLabels ()[fleetv1beta1 .IsLatestSnapshotLabel ] == strconv .FormatBool (true ) {
301301 // set the latest label to false first to make sure there is only one or none active policy snapshot
302302 labels := latestPolicySnapshot .GetLabels ()
303- if labels == nil {
304- labels = make (map [string ]string )
305- }
306303 labels [fleetv1beta1 .IsLatestSnapshotLabel ] = strconv .FormatBool (false )
307304 latestPolicySnapshot .SetLabels (labels )
308305 if err := r .Client .Update (ctx , latestPolicySnapshot ); err != nil {
@@ -493,9 +490,6 @@ func (r *Reconciler) getOrCreateResourceSnapshot(ctx context.Context, placement
493490 shouldCreateNewMasterResourceSnapshot = true
494491 // set the latest label to false first to make sure there is only one or none active resource snapshot
495492 labels := latestResourceSnapshot .GetLabels ()
496- if labels == nil {
497- labels = make (map [string ]string )
498- }
499493 labels [fleetv1beta1 .IsLatestSnapshotLabel ] = strconv .FormatBool (false )
500494 latestResourceSnapshot .SetLabels (labels )
501495 if err := r .Client .Update (ctx , latestResourceSnapshot ); err != nil {
@@ -677,16 +671,12 @@ func (r *Reconciler) ensureLatestPolicySnapshot(ctx context.Context, placementOb
677671 needUpdate := false
678672 latestKObj := klog .KObj (latest )
679673 labels := latest .GetLabels ()
680- if labels == nil {
681- labels = make (map [string ]string )
682- }
683674 if labels [fleetv1beta1 .IsLatestSnapshotLabel ] != strconv .FormatBool (true ) {
684675 // When latestPolicySnapshot.Spec.PolicyHash == policyHash,
685676 // It could happen when the controller just sets the latest label to false for the old snapshot, and fails to
686677 // create a new policy snapshot.
687678 // And then the customers revert back their policy to the old one again.
688679 // In this case, the "latest" snapshot without isLatest label has the same policy hash as the current policy.
689-
690680 labels [fleetv1beta1 .IsLatestSnapshotLabel ] = strconv .FormatBool (true )
691681 latest .SetLabels (labels )
692682 needUpdate = true
@@ -698,9 +688,6 @@ func (r *Reconciler) ensureLatestPolicySnapshot(ctx context.Context, placementOb
698688 }
699689 if placementGeneration != placementObj .GetGeneration () {
700690 annotations := latest .GetAnnotations ()
701- if annotations == nil {
702- annotations = make (map [string ]string )
703- }
704691 annotations [fleetv1beta1 .CRPGenerationAnnotation ] = strconv .FormatInt (placementObj .GetGeneration (), 10 )
705692 latest .SetAnnotations (annotations )
706693 needUpdate = true
@@ -737,16 +724,13 @@ func (r *Reconciler) ensureLatestPolicySnapshot(ctx context.Context, placementOb
737724// ensureLatestResourceSnapshot ensures the latest resourceSnapshot has the isLatest label, working with interface types.
738725func (r * Reconciler ) ensureLatestResourceSnapshot (ctx context.Context , latest fleetv1beta1.ResourceSnapshotObj ) error {
739726 labels := latest .GetLabels ()
740- if labels != nil && labels [fleetv1beta1 .IsLatestSnapshotLabel ] == strconv .FormatBool (true ) {
727+ if labels [fleetv1beta1 .IsLatestSnapshotLabel ] == strconv .FormatBool (true ) {
741728 return nil
742729 }
743730 // It could happen when the controller just sets the latest label to false for the old snapshot, and fails to
744731 // create a new resource snapshot.
745732 // And then the customers revert back their resource to the old one again.
746733 // In this case, the "latest" snapshot without isLatest label has the same resource hash as the current one.
747- if labels == nil {
748- labels = make (map [string ]string )
749- }
750734 labels [fleetv1beta1 .IsLatestSnapshotLabel ] = strconv .FormatBool (true )
751735 latest .SetLabels (labels )
752736 if err := r .Client .Update (ctx , latest ); err != nil {
@@ -757,6 +741,94 @@ func (r *Reconciler) ensureLatestResourceSnapshot(ctx context.Context, latest fl
757741 return nil
758742}
759743
744+ // lookupLatestSchedulingPolicySnapshot finds the latest snapshots and its policy index.
745+ // There will be only one active policy snapshot if exists.
746+ // It first checks whether there is an active policy snapshot.
747+ // If not, it finds the one whose policyIndex label is the largest.
748+ // The policy index will always start from 0.
749+ // Return error when 1) cannot list the snapshots 2) there are more than one active policy snapshots 3) snapshot has the
750+ // invalid label value.
751+ // 2 & 3 should never happen.
752+ func (r * Reconciler ) lookupLatestSchedulingPolicySnapshot (ctx context.Context , placement fleetv1beta1.PlacementObj ) (fleetv1beta1.PolicySnapshotObj , int , error ) {
753+ placementKey := types.NamespacedName {Name : placement .GetName (), Namespace : placement .GetNamespace ()}
754+ snapshotList , err := controller .FetchLatestPolicySnapshot (ctx , r .Client , placementKey )
755+ if err != nil {
756+ return nil , - 1 , err
757+ }
758+ placementKObj := klog .KObj (placement )
759+ policySnapshotItems := snapshotList .GetPolicySnapshotObjs ()
760+ if len (policySnapshotItems ) == 1 {
761+ policyIndex , err := labels .ParsePolicyIndexFromLabel (policySnapshotItems [0 ])
762+ if err != nil {
763+ klog .ErrorS (err , "Failed to parse the policy index label" , "placement" , placementKObj , "policySnapshot" , klog .KObj (policySnapshotItems [0 ]))
764+ return nil , - 1 , controller .NewUnexpectedBehaviorError (err )
765+ }
766+ return policySnapshotItems [0 ], policyIndex , nil
767+ } else if len (policySnapshotItems ) > 1 {
768+ // It means there are multiple active snapshots and should never happen.
769+ err := fmt .Errorf ("there are %d active schedulingPolicySnapshots owned by placement %v" , len (policySnapshotItems ), placementKey )
770+ klog .ErrorS (err , "Invalid schedulingPolicySnapshots" , "placement" , placementKObj )
771+ return nil , - 1 , controller .NewUnexpectedBehaviorError (err )
772+ }
773+ // When there are no active snapshots, find the one who has the largest policy index.
774+ // It should be rare only when placement controller is crashed before creating the new active snapshot.
775+ sortedList , err := r .listSortedSchedulingPolicySnapshots (ctx , placement )
776+ if err != nil {
777+ return nil , - 1 , err
778+ }
779+
780+ if len (sortedList .GetPolicySnapshotObjs ()) == 0 {
781+ // The policy index of the first snapshot will start from 0.
782+ return nil , - 1 , nil
783+ }
784+ latestSnapshot := sortedList .GetPolicySnapshotObjs ()[len (sortedList .GetPolicySnapshotObjs ())- 1 ]
785+ policyIndex , err := labels .ParsePolicyIndexFromLabel (latestSnapshot )
786+ if err != nil {
787+ klog .ErrorS (err , "Failed to parse the policy index label" , "placement" , placementKObj , "policySnapshot" , klog .KObj (latestSnapshot ))
788+ return nil , - 1 , controller .NewUnexpectedBehaviorError (err )
789+ }
790+ return latestSnapshot , policyIndex , nil
791+ }
792+
793+ // listSortedSchedulingPolicySnapshots returns the policy snapshots sorted by the policy index.
794+ // Now works with both cluster-scoped and namespaced policy snapshots using interface types.
795+ func (r * Reconciler ) listSortedSchedulingPolicySnapshots (ctx context.Context , placementObj fleetv1beta1.PlacementObj ) (fleetv1beta1.PolicySnapshotList , error ) {
796+ placementKey := types.NamespacedName {
797+ Namespace : placementObj .GetNamespace (),
798+ Name : placementObj .GetName (),
799+ }
800+
801+ snapshotList , err := controller .ListPolicySnapshots (ctx , r .Client , placementKey )
802+ if err != nil {
803+ klog .ErrorS (err , "Failed to list all policySnapshots" , "placement" , klog .KObj (placementObj ))
804+ // placement controller needs a scheduling policy snapshot watcher to enqueue the placement request.
805+ // So the snapshots should be read from cache.
806+ return nil , controller .NewAPIServerError (true , err )
807+ }
808+
809+ items := snapshotList .GetPolicySnapshotObjs ()
810+ var errs []error
811+ sort .Slice (items , func (i , j int ) bool {
812+ ii , err := labels .ParsePolicyIndexFromLabel (items [i ])
813+ if err != nil {
814+ klog .ErrorS (err , "Failed to parse the policy index label" , "placement" , klog .KObj (placementObj ), "policySnapshot" , klog .KObj (items [i ]))
815+ errs = append (errs , err )
816+ }
817+ ji , err := labels .ParsePolicyIndexFromLabel (items [j ])
818+ if err != nil {
819+ klog .ErrorS (err , "Failed to parse the policy index label" , "placement" , klog .KObj (placementObj ), "policySnapshot" , klog .KObj (items [j ]))
820+ errs = append (errs , err )
821+ }
822+ return ii < ji
823+ })
824+
825+ if len (errs ) > 0 {
826+ return nil , controller .NewUnexpectedBehaviorError (utilerrors .NewAggregate (errs ))
827+ }
828+
829+ return snapshotList , nil
830+ }
831+
760832// lookupLatestResourceSnapshot finds the latest snapshots and.
761833// There will be only one active resource snapshot if exists.
762834// It first checks whether there is an active resource snapshot.
@@ -876,94 +948,6 @@ func (r *Reconciler) listSortedResourceSnapshots(ctx context.Context, placementO
876948 return snapshotList , nil
877949}
878950
879- // lookupLatestSchedulingPolicySnapshot finds the latest snapshots and its policy index.
880- // There will be only one active policy snapshot if exists.
881- // It first checks whether there is an active policy snapshot.
882- // If not, it finds the one whose policyIndex label is the largest.
883- // The policy index will always start from 0.
884- // Return error when 1) cannot list the snapshots 2) there are more than one active policy snapshots 3) snapshot has the
885- // invalid label value.
886- // 2 & 3 should never happen.
887- func (r * Reconciler ) lookupLatestSchedulingPolicySnapshot (ctx context.Context , placement fleetv1beta1.PlacementObj ) (fleetv1beta1.PolicySnapshotObj , int , error ) {
888- placementKey := types.NamespacedName {Name : placement .GetName (), Namespace : placement .GetNamespace ()}
889- snapshotList , err := controller .FetchLatestPolicySnapshot (ctx , r .Client , placementKey )
890- if err != nil {
891- return nil , - 1 , err
892- }
893- placementKObj := klog .KObj (placement )
894- policySnapshotItems := snapshotList .GetPolicySnapshotObjs ()
895- if len (policySnapshotItems ) == 1 {
896- policyIndex , err := labels .ParsePolicyIndexFromLabel (policySnapshotItems [0 ])
897- if err != nil {
898- klog .ErrorS (err , "Failed to parse the policy index label" , "placement" , placementKObj , "policySnapshot" , klog .KObj (policySnapshotItems [0 ]))
899- return nil , - 1 , controller .NewUnexpectedBehaviorError (err )
900- }
901- return policySnapshotItems [0 ], policyIndex , nil
902- } else if len (policySnapshotItems ) > 1 {
903- // It means there are multiple active snapshots and should never happen.
904- err := fmt .Errorf ("there are %d active schedulingPolicySnapshots owned by placement %v" , len (policySnapshotItems ), placementKey )
905- klog .ErrorS (err , "Invalid schedulingPolicySnapshots" , "placement" , placementKObj )
906- return nil , - 1 , controller .NewUnexpectedBehaviorError (err )
907- }
908- // When there are no active snapshots, find the one who has the largest policy index.
909- // It should be rare only when placement controller is crashed before creating the new active snapshot.
910- sortedList , err := r .listSortedSchedulingPolicySnapshots (ctx , placement )
911- if err != nil {
912- return nil , - 1 , err
913- }
914-
915- if len (sortedList .GetPolicySnapshotObjs ()) == 0 {
916- // The policy index of the first snapshot will start from 0.
917- return nil , - 1 , nil
918- }
919- latestSnapshot := sortedList .GetPolicySnapshotObjs ()[len (sortedList .GetPolicySnapshotObjs ())- 1 ]
920- policyIndex , err := labels .ParsePolicyIndexFromLabel (latestSnapshot )
921- if err != nil {
922- klog .ErrorS (err , "Failed to parse the policy index label" , "placement" , placementKObj , "policySnapshot" , klog .KObj (latestSnapshot ))
923- return nil , - 1 , controller .NewUnexpectedBehaviorError (err )
924- }
925- return latestSnapshot , policyIndex , nil
926- }
927-
928- // listSortedSchedulingPolicySnapshots returns the policy snapshots sorted by the policy index.
929- // Now works with both cluster-scoped and namespaced policy snapshots using interface types.
930- func (r * Reconciler ) listSortedSchedulingPolicySnapshots (ctx context.Context , placementObj fleetv1beta1.PlacementObj ) (fleetv1beta1.PolicySnapshotList , error ) {
931- placementKey := types.NamespacedName {
932- Namespace : placementObj .GetNamespace (),
933- Name : placementObj .GetName (),
934- }
935-
936- snapshotList , err := controller .ListPolicySnapshots (ctx , r .Client , placementKey )
937- if err != nil {
938- klog .ErrorS (err , "Failed to list all policySnapshots" , "placement" , klog .KObj (placementObj ))
939- // placement controller needs a scheduling policy snapshot watcher to enqueue the placement request.
940- // So the snapshots should be read from cache.
941- return nil , controller .NewAPIServerError (true , err )
942- }
943-
944- items := snapshotList .GetPolicySnapshotObjs ()
945- var errs []error
946- sort .Slice (items , func (i , j int ) bool {
947- ii , err := labels .ParsePolicyIndexFromLabel (items [i ])
948- if err != nil {
949- klog .ErrorS (err , "Failed to parse the policy index label" , "placement" , klog .KObj (placementObj ), "policySnapshot" , klog .KObj (items [i ]))
950- errs = append (errs , err )
951- }
952- ji , err := labels .ParsePolicyIndexFromLabel (items [j ])
953- if err != nil {
954- klog .ErrorS (err , "Failed to parse the policy index label" , "placement" , klog .KObj (placementObj ), "policySnapshot" , klog .KObj (items [j ]))
955- errs = append (errs , err )
956- }
957- return ii < ji
958- })
959-
960- if len (errs ) > 0 {
961- return nil , controller .NewUnexpectedBehaviorError (utilerrors .NewAggregate (errs ))
962- }
963-
964- return snapshotList , nil
965- }
966-
967951// setPlacementStatus returns if there is a cluster scheduled by the scheduler.
968952// it returns true if the cluster schedule succeeded, false otherwise.
969953func (r * Reconciler ) setPlacementStatus (
0 commit comments