From ffe285ea2adb8b01882812d40bc0dc89b4f51790 Mon Sep 17 00:00:00 2001 From: junqian Date: Mon, 5 Jul 2021 19:39:34 +0800 Subject: [PATCH] ensure work with given replicas Signed-off-by: junqian --- pkg/controllers/binding/binding_controller.go | 2 +- .../cluster_resource_binding_controller.go | 2 +- pkg/util/helper/binding.go | 40 +++++++++++++++---- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/pkg/controllers/binding/binding_controller.go b/pkg/controllers/binding/binding_controller.go index fc004d2df..6375a2711 100644 --- a/pkg/controllers/binding/binding_controller.go +++ b/pkg/controllers/binding/binding_controller.go @@ -92,7 +92,7 @@ func (c *ResourceBindingController) syncBinding(binding *workv1alpha1.ResourceBi return controllerruntime.Result{Requeue: true}, err } - err = helper.EnsureWork(c.Client, workload, clusterNames, c.OverrideManager, binding, apiextensionsv1.NamespaceScoped) + err = helper.EnsureWork(c.Client, workload, clusterNames, binding.Spec.Clusters, c.OverrideManager, binding, apiextensionsv1.NamespaceScoped) if err != nil { klog.Errorf("Failed to transform resourceBinding(%s/%s) to works. Error: %v.", binding.GetNamespace(), binding.GetName(), err) diff --git a/pkg/controllers/binding/cluster_resource_binding_controller.go b/pkg/controllers/binding/cluster_resource_binding_controller.go index 98cc0875d..c2481ecf6 100644 --- a/pkg/controllers/binding/cluster_resource_binding_controller.go +++ b/pkg/controllers/binding/cluster_resource_binding_controller.go @@ -88,7 +88,7 @@ func (c *ClusterResourceBindingController) syncBinding(binding *workv1alpha1.Clu return controllerruntime.Result{Requeue: true}, err } - err = helper.EnsureWork(c.Client, workload, clusterNames, c.OverrideManager, binding, apiextensionsv1.ClusterScoped) + err = helper.EnsureWork(c.Client, workload, clusterNames, binding.Spec.Clusters, c.OverrideManager, binding, apiextensionsv1.ClusterScoped) if err != nil { klog.Errorf("Failed to transform clusterResourceBinding(%s) to works. Error: %v.", binding.GetName(), err) return controllerruntime.Result{Requeue: true}, err diff --git a/pkg/util/helper/binding.go b/pkg/util/helper/binding.go index 7a5e45675..6e2ad2512 100644 --- a/pkg/util/helper/binding.go +++ b/pkg/util/helper/binding.go @@ -69,6 +69,16 @@ func IsBindingReady(targetClusters []workv1alpha1.TargetCluster) bool { return len(targetClusters) != 0 } +// HasScheduledReplica checks if the scheduler has assigned replicas for each cluster. +func HasScheduledReplica(scheduleResult []workv1alpha1.TargetCluster) bool { + for _, clusterResult := range scheduleResult { + if clusterResult.Replicas > 0 { + return true + } + } + return false +} + // GetBindingClusterNames will get clusterName list from bind clusters field func GetBindingClusterNames(targetClusters []workv1alpha1.TargetCluster) []string { var clusterNames []string @@ -153,12 +163,20 @@ func FetchWorkload(dynamicClient dynamic.Interface, restMapper meta.RESTMapper, // EnsureWork ensure Work to be created or updated. //nolint:gocyclo // Note: ignore the cyclomatic complexity issue to get gocyclo on board. Tracked by: https://github.com/karmada-io/karmada/issues/460 -func EnsureWork(c client.Client, workload *unstructured.Unstructured, clusterNames []string, overrideManager overridemanager.OverrideManager, - binding metav1.Object, scope apiextensionsv1.ResourceScope) error { - referenceRSP, desireReplicaInfos, err := calculateReplicasIfNeeded(c, workload, clusterNames) - if err != nil { - klog.Errorf("Failed to get ReplicaSchedulingPolicy for %s/%s/%s, err is: %v", workload.GetKind(), workload.GetNamespace(), workload.GetName(), err) - return err +func EnsureWork(c client.Client, workload *unstructured.Unstructured, clusterNames []string, scheduleResult []workv1alpha1.TargetCluster, + overrideManager overridemanager.OverrideManager, binding metav1.Object, scope apiextensionsv1.ResourceScope) error { + var desireReplicaInfos map[string]int64 + var referenceRSP *v1alpha1.ReplicaSchedulingPolicy + var err error + hasScheduledReplica := HasScheduledReplica(scheduleResult) + if hasScheduledReplica { + desireReplicaInfos = transScheduleResultToMap(scheduleResult) + } else { + referenceRSP, desireReplicaInfos, err = calculateReplicasIfNeeded(c, workload, clusterNames) + if err != nil { + klog.Errorf("Failed to get ReplicaSchedulingPolicy for %s/%s/%s, err is: %v", workload.GetKind(), workload.GetNamespace(), workload.GetName(), err) + return err + } } var workLabel = make(map[string]string) @@ -192,7 +210,7 @@ func EnsureWork(c client.Client, workload *unstructured.Unstructured, clusterNam workLabel[util.ClusterResourceBindingLabel] = binding.GetName() } - if clonedWorkload.GetKind() == util.DeploymentKind && referenceRSP != nil { + if clonedWorkload.GetKind() == util.DeploymentKind && (referenceRSP != nil || hasScheduledReplica) { err = applyReplicaSchedulingPolicy(clonedWorkload, desireReplicaInfos[clusterName]) if err != nil { klog.Errorf("failed to apply ReplicaSchedulingPolicy for %s/%s/%s in cluster %s, err is: %v", @@ -279,6 +297,14 @@ func EnsureWork(c client.Client, workload *unstructured.Unstructured, clusterNam return nil } +func transScheduleResultToMap(scheduleResult []workv1alpha1.TargetCluster) map[string]int64 { + var desireReplicaInfos = make(map[string]int64) + for _, clusterInfo := range scheduleResult { + desireReplicaInfos[clusterInfo.Name] = int64(clusterInfo.Replicas) + } + return desireReplicaInfos +} + func calculateReplicasIfNeeded(c client.Client, workload *unstructured.Unstructured, clusterNames []string) (*v1alpha1.ReplicaSchedulingPolicy, map[string]int64, error) { var err error var referenceRSP *v1alpha1.ReplicaSchedulingPolicy