Skip to content

Commit e84b596

Browse files
author
Ryan Zhang
committed
address some comments
Signed-off-by: Ryan Zhang <[email protected]>
1 parent 5ce4192 commit e84b596

File tree

5 files changed

+305
-132
lines changed

5 files changed

+305
-132
lines changed

pkg/controllers/clusterresourceplacement/controller.go

Lines changed: 89 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
738725
func (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.
969953
func (r *Reconciler) setPlacementStatus(

pkg/controllers/clusterresourceplacement/resource_selector.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,17 @@ func generateManifest(object *unstructured.Unstructured) (*workv1alpha1.Manifest
497497
}, nil
498498
}
499499

500+
// generateResourceContent creates a resource content from the unstructured obj.
501+
func generateResourceContent(object *unstructured.Unstructured) (*fleetv1beta1.ResourceContent, error) {
502+
rawContent, err := generateRawContent(object)
503+
if err != nil {
504+
return nil, controller.NewUnexpectedBehaviorError(err)
505+
}
506+
return &fleetv1beta1.ResourceContent{
507+
RawExtension: runtime.RawExtension{Raw: rawContent},
508+
}, nil
509+
}
510+
500511
// selectResourcesForPlacement selects the resources according to the placement resourceSelectors.
501512
// It also generates an array of resource content and resource identifier based on the selected resources.
502513
// It also returns the number of envelope configmaps so the CRP controller can have the right expectation of the number of work objects.
@@ -534,14 +545,3 @@ func (r *Reconciler) selectResourcesForPlacement(placementObj fleetv1beta1.Place
534545
}
535546
return envelopeObjCount, resources, resourcesIDs, nil
536547
}
537-
538-
// generateResourceContent creates a resource content from the unstructured obj.
539-
func generateResourceContent(object *unstructured.Unstructured) (*fleetv1beta1.ResourceContent, error) {
540-
rawContent, err := generateRawContent(object)
541-
if err != nil {
542-
return nil, controller.NewUnexpectedBehaviorError(err)
543-
}
544-
return &fleetv1beta1.ResourceContent{
545-
RawExtension: runtime.RawExtension{Raw: rawContent},
546-
}, nil
547-
}

pkg/controllers/rollout/controller.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,9 @@ func handleResourceOverrideSnapshot(o client.Object, q workqueue.TypedRateLimiti
838838
q.Add(reconcile.Request{
839839
NamespacedName: types.NamespacedName{Name: snapshot.Spec.OverrideSpec.Placement.Name},
840840
})
841+
q.Add(reconcile.Request{
842+
NamespacedName: types.NamespacedName{Namespace: snapshot.GetNamespace(), Name: snapshot.Spec.OverrideSpec.Placement.Name},
843+
})
841844
}
842845

843846
// handleResourceSnapshot parse the resourceBinding label and annotation and enqueue the CRP name associated with the resource resourceBinding

pkg/utils/controller/policy_snapshot_resolver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func DeletePolicySnapshots(ctx context.Context, k8Client client.Client, placemen
5555
return NewAPIServerError(false, err)
5656
}
5757

58-
klog.V(2).InfoS("Deleted policy snapshots", "policySnapshot ", policySnapshotKObj, "placement", placementKObj)
58+
klog.V(2).InfoS("Deleted policy snapshots", "policySnapshot", policySnapshotKObj, "placement", placementKObj)
5959
return nil
6060
}
6161

0 commit comments

Comments
 (0)