diff --git a/pkg/descheduler/descheduler.go b/pkg/descheduler/descheduler.go index 2a444a2e5..502f4338f 100644 --- a/pkg/descheduler/descheduler.go +++ b/pkg/descheduler/descheduler.go @@ -139,7 +139,10 @@ func (d *descheduler) runDeschedulerLoop(ctx context.Context, nodes []*v1.Node) if d.rs.DryRun { klog.V(3).Infof("Building a cached client from the cluster for the dry run") // Create a new cache so we start from scratch without any leftovers - fakeClient, err := cachedClient(d.rs.Client, d.podLister, d.nodeLister, d.namespaceLister, d.priorityClassLister) + fakeClient := fakeclientset.NewSimpleClientset() + // simulate a pod eviction by deleting a pod + fakeClient.PrependReactor("create", "pods", podEvictionReactionFnc(fakeClient)) + err := cachedClient(d.rs.Client, fakeClient, d.podLister, d.nodeLister, d.namespaceLister, d.priorityClassLister) if err != nil { return err } @@ -308,16 +311,8 @@ func validateVersionCompatibility(discovery discovery.DiscoveryInterface, versio return nil } -func cachedClient( - realClient clientset.Interface, - podLister listersv1.PodLister, - nodeLister listersv1.NodeLister, - namespaceLister listersv1.NamespaceLister, - priorityClassLister schedulingv1.PriorityClassLister, -) (clientset.Interface, error) { - fakeClient := fakeclientset.NewSimpleClientset() - // simulate a pod eviction by deleting a pod - fakeClient.PrependReactor("create", "pods", func(action core.Action) (bool, runtime.Object, error) { +func podEvictionReactionFnc(fakeClient *fakeclientset.Clientset) func(action core.Action) (bool, runtime.Object, error) { + return func(action core.Action) (bool, runtime.Object, error) { if action.GetSubresource() == "eviction" { createAct, matched := action.(core.CreateActionImpl) if !matched { @@ -334,54 +329,63 @@ func cachedClient( } // fallback to the default reactor return false, nil, nil - }) + } +} +func cachedClient( + realClient clientset.Interface, + fakeClient *fakeclientset.Clientset, + podLister listersv1.PodLister, + nodeLister listersv1.NodeLister, + namespaceLister listersv1.NamespaceLister, + priorityClassLister schedulingv1.PriorityClassLister, +) error { klog.V(3).Infof("Pulling resources for the cached client from the cluster") pods, err := podLister.List(labels.Everything()) if err != nil { - return nil, fmt.Errorf("unable to list pods: %v", err) + return fmt.Errorf("unable to list pods: %v", err) } for _, item := range pods { if _, err := fakeClient.CoreV1().Pods(item.Namespace).Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { - return nil, fmt.Errorf("unable to copy pod: %v", err) + return fmt.Errorf("unable to copy pod: %v", err) } } nodes, err := nodeLister.List(labels.Everything()) if err != nil { - return nil, fmt.Errorf("unable to list nodes: %v", err) + return fmt.Errorf("unable to list nodes: %v", err) } for _, item := range nodes { if _, err := fakeClient.CoreV1().Nodes().Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { - return nil, fmt.Errorf("unable to copy node: %v", err) + return fmt.Errorf("unable to copy node: %v", err) } } namespaces, err := namespaceLister.List(labels.Everything()) if err != nil { - return nil, fmt.Errorf("unable to list namespaces: %v", err) + return fmt.Errorf("unable to list namespaces: %v", err) } for _, item := range namespaces { if _, err := fakeClient.CoreV1().Namespaces().Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { - return nil, fmt.Errorf("unable to copy namespace: %v", err) + return fmt.Errorf("unable to copy namespace: %v", err) } } priorityClasses, err := priorityClassLister.List(labels.Everything()) if err != nil { - return nil, fmt.Errorf("unable to list priorityclasses: %v", err) + return fmt.Errorf("unable to list priorityclasses: %v", err) } for _, item := range priorityClasses { if _, err := fakeClient.SchedulingV1().PriorityClasses().Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { - return nil, fmt.Errorf("unable to copy priorityclass: %v", err) + return fmt.Errorf("unable to copy priorityclass: %v", err) } } - return fakeClient, nil + return nil } func RunDeschedulerStrategies(ctx context.Context, rs *options.DeschedulerServer, deschedulerPolicy *api.DeschedulerPolicy, evictionPolicyGroupVersion string) error { diff --git a/pkg/descheduler/descheduler_test.go b/pkg/descheduler/descheduler_test.go index 0a5d39f42..6e5ce01b0 100644 --- a/pkg/descheduler/descheduler_test.go +++ b/pkg/descheduler/descheduler_test.go @@ -98,7 +98,7 @@ func TestTaintsUpdated(t *testing.T) { } var evictedPods []string - client.PrependReactor("create", "pods", podEvictionReactionFuc(&evictedPods)) + client.PrependReactor("create", "pods", podEvictionReactionTestingFnc(&evictedPods)) internalDeschedulerPolicy := &api.DeschedulerPolicy{} scope := scope{} @@ -164,7 +164,7 @@ func TestDuplicate(t *testing.T) { } var evictedPods []string - client.PrependReactor("create", "pods", podEvictionReactionFuc(&evictedPods)) + client.PrependReactor("create", "pods", podEvictionReactionTestingFnc(&evictedPods)) internalDeschedulerPolicy := &api.DeschedulerPolicy{} scope := scope{} @@ -312,7 +312,7 @@ func TestValidateVersionCompatibility(t *testing.T) { } } -func podEvictionReactionFuc(evictedPods *[]string) func(action core.Action) (bool, runtime.Object, error) { +func podEvictionReactionTestingFnc(evictedPods *[]string) func(action core.Action) (bool, runtime.Object, error) { return func(action core.Action) (bool, runtime.Object, error) { if action.GetSubresource() == "eviction" { createAct, matched := action.(core.CreateActionImpl) @@ -380,7 +380,7 @@ func TestPodEvictorReset(t *testing.T) { rs.EventClient = eventClient var evictedPods []string - client.PrependReactor("create", "pods", podEvictionReactionFuc(&evictedPods)) + client.PrependReactor("create", "pods", podEvictionReactionTestingFnc(&evictedPods)) sharedInformerFactory := informers.NewSharedInformerFactoryWithOptions(rs.Client, 0, informers.WithTransform(trimManagedFields)) eventBroadcaster, eventRecorder := utils.GetRecorderAndBroadcaster(ctx, client)