mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 03:11:40 +00:00
kube-scheduler: move stopCh creation out of scheduler factory code
Enforces clean ownership of the channel.
This commit is contained in:
parent
cb95edafe8
commit
d91feb6d18
@ -160,6 +160,7 @@ func run(cmd *cobra.Command, args []string, opts *options.Options) error {
|
|||||||
storageClassInformer,
|
storageClassInformer,
|
||||||
c.Recorder,
|
c.Recorder,
|
||||||
c.ComponentConfig.AlgorithmSource,
|
c.ComponentConfig.AlgorithmSource,
|
||||||
|
stopCh,
|
||||||
scheduler.WithName(c.ComponentConfig.SchedulerName),
|
scheduler.WithName(c.ComponentConfig.SchedulerName),
|
||||||
scheduler.WithHardPodAffinitySymmetricWeight(c.ComponentConfig.HardPodAffinitySymmetricWeight),
|
scheduler.WithHardPodAffinitySymmetricWeight(c.ComponentConfig.HardPodAffinitySymmetricWeight),
|
||||||
scheduler.WithEquivalenceClassCacheEnabled(c.ComponentConfig.EnableContentionProfiling),
|
scheduler.WithEquivalenceClassCacheEnabled(c.ComponentConfig.EnableContentionProfiling),
|
||||||
|
@ -37,6 +37,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/informers/apps/v1:go_default_library",
|
"//staging/src/k8s.io/client-go/informers/apps/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/informers/core/v1:go_default_library",
|
"//staging/src/k8s.io/client-go/informers/core/v1:go_default_library",
|
||||||
|
@ -37,6 +37,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/runtime"
|
"k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
appsinformers "k8s.io/client-go/informers/apps/v1"
|
appsinformers "k8s.io/client-go/informers/apps/v1"
|
||||||
coreinformers "k8s.io/client-go/informers/core/v1"
|
coreinformers "k8s.io/client-go/informers/core/v1"
|
||||||
@ -127,7 +128,7 @@ type Config struct {
|
|||||||
Recorder record.EventRecorder
|
Recorder record.EventRecorder
|
||||||
|
|
||||||
// Close this to shut down the scheduler.
|
// Close this to shut down the scheduler.
|
||||||
StopEverything chan struct{}
|
StopEverything <-chan struct{}
|
||||||
|
|
||||||
// VolumeBinder handles PVC/PV binding for the pod.
|
// VolumeBinder handles PVC/PV binding for the pod.
|
||||||
VolumeBinder *volumebinder.VolumeBinder
|
VolumeBinder *volumebinder.VolumeBinder
|
||||||
@ -200,7 +201,7 @@ type configFactory struct {
|
|||||||
storageClassLister storagelisters.StorageClassLister
|
storageClassLister storagelisters.StorageClassLister
|
||||||
|
|
||||||
// Close this to stop all reflectors
|
// Close this to stop all reflectors
|
||||||
StopEverything chan struct{}
|
StopEverything <-chan struct{}
|
||||||
|
|
||||||
scheduledPodsHasSynced cache.InformerSynced
|
scheduledPodsHasSynced cache.InformerSynced
|
||||||
|
|
||||||
@ -253,12 +254,16 @@ type ConfigFactoryArgs struct {
|
|||||||
DisablePreemption bool
|
DisablePreemption bool
|
||||||
PercentageOfNodesToScore int32
|
PercentageOfNodesToScore int32
|
||||||
BindTimeoutSeconds int64
|
BindTimeoutSeconds int64
|
||||||
|
StopCh <-chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConfigFactory initializes the default implementation of a Configurator. To encourage eventual privatization of the struct type, we only
|
// NewConfigFactory initializes the default implementation of a Configurator. To encourage eventual privatization of the struct type, we only
|
||||||
// return the interface.
|
// return the interface.
|
||||||
func NewConfigFactory(args *ConfigFactoryArgs) Configurator {
|
func NewConfigFactory(args *ConfigFactoryArgs) Configurator {
|
||||||
stopEverything := make(chan struct{})
|
stopEverything := args.StopCh
|
||||||
|
if stopEverything == nil {
|
||||||
|
stopEverything = wait.NeverStop
|
||||||
|
}
|
||||||
schedulerCache := schedulerinternalcache.New(30*time.Second, stopEverything)
|
schedulerCache := schedulerinternalcache.New(30*time.Second, stopEverything)
|
||||||
|
|
||||||
// storageClassInformer is only enabled through VolumeScheduling feature gate
|
// storageClassInformer is only enabled through VolumeScheduling feature gate
|
||||||
|
@ -52,7 +52,9 @@ const (
|
|||||||
|
|
||||||
func TestCreate(t *testing.T) {
|
func TestCreate(t *testing.T) {
|
||||||
client := fake.NewSimpleClientset()
|
client := fake.NewSimpleClientset()
|
||||||
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight)
|
stopCh := make(chan struct{})
|
||||||
|
defer close(stopCh)
|
||||||
|
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight, stopCh)
|
||||||
factory.Create()
|
factory.Create()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +65,9 @@ func TestCreateFromConfig(t *testing.T) {
|
|||||||
var policy schedulerapi.Policy
|
var policy schedulerapi.Policy
|
||||||
|
|
||||||
client := fake.NewSimpleClientset()
|
client := fake.NewSimpleClientset()
|
||||||
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight)
|
stopCh := make(chan struct{})
|
||||||
|
defer close(stopCh)
|
||||||
|
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight, stopCh)
|
||||||
|
|
||||||
// Pre-register some predicate and priority functions
|
// Pre-register some predicate and priority functions
|
||||||
RegisterFitPredicate("PredicateOne", PredicateOne)
|
RegisterFitPredicate("PredicateOne", PredicateOne)
|
||||||
@ -101,7 +105,9 @@ func TestCreateFromConfigWithHardPodAffinitySymmetricWeight(t *testing.T) {
|
|||||||
var policy schedulerapi.Policy
|
var policy schedulerapi.Policy
|
||||||
|
|
||||||
client := fake.NewSimpleClientset()
|
client := fake.NewSimpleClientset()
|
||||||
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight)
|
stopCh := make(chan struct{})
|
||||||
|
defer close(stopCh)
|
||||||
|
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight, stopCh)
|
||||||
|
|
||||||
// Pre-register some predicate and priority functions
|
// Pre-register some predicate and priority functions
|
||||||
RegisterFitPredicate("PredicateOne", PredicateOne)
|
RegisterFitPredicate("PredicateOne", PredicateOne)
|
||||||
@ -140,7 +146,9 @@ func TestCreateFromEmptyConfig(t *testing.T) {
|
|||||||
var policy schedulerapi.Policy
|
var policy schedulerapi.Policy
|
||||||
|
|
||||||
client := fake.NewSimpleClientset()
|
client := fake.NewSimpleClientset()
|
||||||
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight)
|
stopCh := make(chan struct{})
|
||||||
|
defer close(stopCh)
|
||||||
|
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight, stopCh)
|
||||||
|
|
||||||
configData = []byte(`{}`)
|
configData = []byte(`{}`)
|
||||||
if err := runtime.DecodeInto(latestschedulerapi.Codec, configData, &policy); err != nil {
|
if err := runtime.DecodeInto(latestschedulerapi.Codec, configData, &policy); err != nil {
|
||||||
@ -155,7 +163,9 @@ func TestCreateFromEmptyConfig(t *testing.T) {
|
|||||||
// The predicate/priority from DefaultProvider will be used.
|
// The predicate/priority from DefaultProvider will be used.
|
||||||
func TestCreateFromConfigWithUnspecifiedPredicatesOrPriorities(t *testing.T) {
|
func TestCreateFromConfigWithUnspecifiedPredicatesOrPriorities(t *testing.T) {
|
||||||
client := fake.NewSimpleClientset()
|
client := fake.NewSimpleClientset()
|
||||||
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight)
|
stopCh := make(chan struct{})
|
||||||
|
defer close(stopCh)
|
||||||
|
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight, stopCh)
|
||||||
|
|
||||||
RegisterFitPredicate("PredicateOne", PredicateOne)
|
RegisterFitPredicate("PredicateOne", PredicateOne)
|
||||||
RegisterPriorityFunction("PriorityOne", PriorityOne, 1)
|
RegisterPriorityFunction("PriorityOne", PriorityOne, 1)
|
||||||
@ -188,7 +198,9 @@ func TestCreateFromConfigWithUnspecifiedPredicatesOrPriorities(t *testing.T) {
|
|||||||
// Empty predicate/priority sets will be used.
|
// Empty predicate/priority sets will be used.
|
||||||
func TestCreateFromConfigWithEmptyPredicatesOrPriorities(t *testing.T) {
|
func TestCreateFromConfigWithEmptyPredicatesOrPriorities(t *testing.T) {
|
||||||
client := fake.NewSimpleClientset()
|
client := fake.NewSimpleClientset()
|
||||||
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight)
|
stopCh := make(chan struct{})
|
||||||
|
defer close(stopCh)
|
||||||
|
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight, stopCh)
|
||||||
|
|
||||||
RegisterFitPredicate("PredicateOne", PredicateOne)
|
RegisterFitPredicate("PredicateOne", PredicateOne)
|
||||||
RegisterPriorityFunction("PriorityOne", PriorityOne, 1)
|
RegisterPriorityFunction("PriorityOne", PriorityOne, 1)
|
||||||
@ -240,7 +252,9 @@ func TestDefaultErrorFunc(t *testing.T) {
|
|||||||
Spec: apitesting.V1DeepEqualSafePodSpec(),
|
Spec: apitesting.V1DeepEqualSafePodSpec(),
|
||||||
}
|
}
|
||||||
client := fake.NewSimpleClientset(&v1.PodList{Items: []v1.Pod{*testPod}})
|
client := fake.NewSimpleClientset(&v1.PodList{Items: []v1.Pod{*testPod}})
|
||||||
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight)
|
stopCh := make(chan struct{})
|
||||||
|
defer close(stopCh)
|
||||||
|
factory := newConfigFactory(client, v1.DefaultHardPodAffinitySymmetricWeight, stopCh)
|
||||||
queue := &internalqueue.FIFO{FIFO: cache.NewFIFO(cache.MetaNamespaceKeyFunc)}
|
queue := &internalqueue.FIFO{FIFO: cache.NewFIFO(cache.MetaNamespaceKeyFunc)}
|
||||||
podBackoff := util.CreatePodBackoff(1*time.Millisecond, 1*time.Second)
|
podBackoff := util.CreatePodBackoff(1*time.Millisecond, 1*time.Second)
|
||||||
errFunc := factory.MakeDefaultErrorFunc(podBackoff, queue)
|
errFunc := factory.MakeDefaultErrorFunc(podBackoff, queue)
|
||||||
@ -370,7 +384,9 @@ func testBind(binding *v1.Binding, t *testing.T) {
|
|||||||
func TestInvalidHardPodAffinitySymmetricWeight(t *testing.T) {
|
func TestInvalidHardPodAffinitySymmetricWeight(t *testing.T) {
|
||||||
client := fake.NewSimpleClientset()
|
client := fake.NewSimpleClientset()
|
||||||
// factory of "default-scheduler"
|
// factory of "default-scheduler"
|
||||||
factory := newConfigFactory(client, -1)
|
stopCh := make(chan struct{})
|
||||||
|
factory := newConfigFactory(client, -1, stopCh)
|
||||||
|
defer close(stopCh)
|
||||||
_, err := factory.Create()
|
_, err := factory.Create()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("expected err: invalid hardPodAffinitySymmetricWeight, got nothing")
|
t.Errorf("expected err: invalid hardPodAffinitySymmetricWeight, got nothing")
|
||||||
@ -399,7 +415,9 @@ func TestInvalidFactoryArgs(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
factory := newConfigFactory(client, test.hardPodAffinitySymmetricWeight)
|
stopCh := make(chan struct{})
|
||||||
|
factory := newConfigFactory(client, test.hardPodAffinitySymmetricWeight, stopCh)
|
||||||
|
defer close(stopCh)
|
||||||
_, err := factory.Create()
|
_, err := factory.Create()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("expected err: %s, got nothing", test.expectErr)
|
t.Errorf("expected err: %s, got nothing", test.expectErr)
|
||||||
@ -501,7 +519,7 @@ func TestSkipPodUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newConfigFactory(client clientset.Interface, hardPodAffinitySymmetricWeight int32) Configurator {
|
func newConfigFactory(client clientset.Interface, hardPodAffinitySymmetricWeight int32, stopCh <-chan struct{}) Configurator {
|
||||||
informerFactory := informers.NewSharedInformerFactory(client, 0)
|
informerFactory := informers.NewSharedInformerFactory(client, 0)
|
||||||
return NewConfigFactory(&ConfigFactoryArgs{
|
return NewConfigFactory(&ConfigFactoryArgs{
|
||||||
v1.DefaultSchedulerName,
|
v1.DefaultSchedulerName,
|
||||||
@ -521,6 +539,7 @@ func newConfigFactory(client clientset.Interface, hardPodAffinitySymmetricWeight
|
|||||||
disablePodPreemption,
|
disablePodPreemption,
|
||||||
schedulerapi.DefaultPercentageOfNodesToScore,
|
schedulerapi.DefaultPercentageOfNodesToScore,
|
||||||
bindTimeoutSeconds,
|
bindTimeoutSeconds,
|
||||||
|
stopCh,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,12 +59,6 @@ type Scheduler struct {
|
|||||||
config *factory.Config
|
config *factory.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
// StopEverything closes the scheduler config's StopEverything channel, to shut
|
|
||||||
// down the Scheduler.
|
|
||||||
func (sched *Scheduler) StopEverything() {
|
|
||||||
close(sched.config.StopEverything)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache returns the cache in scheduler for test to check the data in scheduler.
|
// Cache returns the cache in scheduler for test to check the data in scheduler.
|
||||||
func (sched *Scheduler) Cache() schedulerinternalcache.Cache {
|
func (sched *Scheduler) Cache() schedulerinternalcache.Cache {
|
||||||
return sched.config.SchedulerCache
|
return sched.config.SchedulerCache
|
||||||
@ -147,6 +141,7 @@ func New(client clientset.Interface,
|
|||||||
storageClassInformer storageinformers.StorageClassInformer,
|
storageClassInformer storageinformers.StorageClassInformer,
|
||||||
recorder record.EventRecorder,
|
recorder record.EventRecorder,
|
||||||
schedulerAlgorithmSource kubeschedulerconfig.SchedulerAlgorithmSource,
|
schedulerAlgorithmSource kubeschedulerconfig.SchedulerAlgorithmSource,
|
||||||
|
stopCh <-chan struct{},
|
||||||
opts ...func(o *schedulerOptions)) (*Scheduler, error) {
|
opts ...func(o *schedulerOptions)) (*Scheduler, error) {
|
||||||
|
|
||||||
options := defaultSchedulerOptions
|
options := defaultSchedulerOptions
|
||||||
@ -230,6 +225,7 @@ func New(client clientset.Interface,
|
|||||||
// Additional tweaks to the config produced by the configurator.
|
// Additional tweaks to the config produced by the configurator.
|
||||||
config.Recorder = recorder
|
config.Recorder = recorder
|
||||||
config.DisablePreemption = options.disablePreemption
|
config.DisablePreemption = options.disablePreemption
|
||||||
|
config.StopEverything = stopCh
|
||||||
// Create the scheduler.
|
// Create the scheduler.
|
||||||
sched := NewFromConfig(config)
|
sched := NewFromConfig(config)
|
||||||
return sched, nil
|
return sched, nil
|
||||||
|
@ -175,6 +175,8 @@ func TestSchedulerCreation(t *testing.T) {
|
|||||||
factory.RegisterPriorityFunction("PriorityOne", PriorityOne, 1)
|
factory.RegisterPriorityFunction("PriorityOne", PriorityOne, 1)
|
||||||
factory.RegisterAlgorithmProvider(testSource, sets.NewString("PredicateOne"), sets.NewString("PriorityOne"))
|
factory.RegisterAlgorithmProvider(testSource, sets.NewString("PredicateOne"), sets.NewString("PriorityOne"))
|
||||||
|
|
||||||
|
stopCh := make(chan struct{})
|
||||||
|
defer close(stopCh)
|
||||||
_, err := New(client,
|
_, err := New(client,
|
||||||
informerFactory.Core().V1().Nodes(),
|
informerFactory.Core().V1().Nodes(),
|
||||||
factory.NewPodInformer(client, 0),
|
factory.NewPodInformer(client, 0),
|
||||||
@ -188,6 +190,7 @@ func TestSchedulerCreation(t *testing.T) {
|
|||||||
informerFactory.Storage().V1().StorageClasses(),
|
informerFactory.Storage().V1().StorageClasses(),
|
||||||
eventBroadcaster.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: "scheduler"}),
|
eventBroadcaster.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: "scheduler"}),
|
||||||
kubeschedulerconfig.SchedulerAlgorithmSource{Provider: &testSource},
|
kubeschedulerconfig.SchedulerAlgorithmSource{Provider: &testSource},
|
||||||
|
stopCh,
|
||||||
WithBindTimeoutSeconds(defaultBindTimeout))
|
WithBindTimeoutSeconds(defaultBindTimeout))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -349,7 +349,7 @@ func TestSchedulerExtender(t *testing.T) {
|
|||||||
}
|
}
|
||||||
policy.APIVersion = "v1"
|
policy.APIVersion = "v1"
|
||||||
|
|
||||||
context = initTestScheduler(t, context, nil, false, &policy)
|
context = initTestScheduler(t, context, false, &policy)
|
||||||
defer cleanupTest(t, context)
|
defer cleanupTest(t, context)
|
||||||
|
|
||||||
DoTestPodScheduling(context.ns, t, clientSet)
|
DoTestPodScheduling(context.ns, t, clientSet)
|
||||||
|
@ -522,7 +522,10 @@ func TestMultiScheduler(t *testing.T) {
|
|||||||
informerFactory2 := informers.NewSharedInformerFactory(context.clientSet, 0)
|
informerFactory2 := informers.NewSharedInformerFactory(context.clientSet, 0)
|
||||||
podInformer2 := factory.NewPodInformer(context.clientSet, 0)
|
podInformer2 := factory.NewPodInformer(context.clientSet, 0)
|
||||||
|
|
||||||
schedulerConfigFactory2 := createConfiguratorWithPodInformer(fooScheduler, clientSet2, podInformer2, informerFactory2)
|
stopCh := make(chan struct{})
|
||||||
|
defer close(stopCh)
|
||||||
|
|
||||||
|
schedulerConfigFactory2 := createConfiguratorWithPodInformer(fooScheduler, clientSet2, podInformer2, informerFactory2, stopCh)
|
||||||
schedulerConfig2, err := schedulerConfigFactory2.Create()
|
schedulerConfig2, err := schedulerConfigFactory2.Create()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Couldn't create scheduler config: %v", err)
|
t.Errorf("Couldn't create scheduler config: %v", err)
|
||||||
@ -530,12 +533,11 @@ func TestMultiScheduler(t *testing.T) {
|
|||||||
eventBroadcaster2 := record.NewBroadcaster()
|
eventBroadcaster2 := record.NewBroadcaster()
|
||||||
schedulerConfig2.Recorder = eventBroadcaster2.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: fooScheduler})
|
schedulerConfig2.Recorder = eventBroadcaster2.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: fooScheduler})
|
||||||
eventBroadcaster2.StartRecordingToSink(&clientv1core.EventSinkImpl{Interface: clientSet2.CoreV1().Events("")})
|
eventBroadcaster2.StartRecordingToSink(&clientv1core.EventSinkImpl{Interface: clientSet2.CoreV1().Events("")})
|
||||||
go podInformer2.Informer().Run(schedulerConfig2.StopEverything)
|
go podInformer2.Informer().Run(stopCh)
|
||||||
informerFactory2.Start(schedulerConfig2.StopEverything)
|
informerFactory2.Start(stopCh)
|
||||||
|
|
||||||
sched2, _ := scheduler.NewFromConfigurator(&scheduler.FakeConfigurator{Config: schedulerConfig2}, nil...)
|
sched2, _ := scheduler.NewFromConfigurator(&scheduler.FakeConfigurator{Config: schedulerConfig2}, nil...)
|
||||||
sched2.Run()
|
sched2.Run()
|
||||||
defer close(schedulerConfig2.StopEverything)
|
|
||||||
|
|
||||||
// 6. **check point-2**:
|
// 6. **check point-2**:
|
||||||
// - testPodWithAnnotationFitsFoo should be scheduled
|
// - testPodWithAnnotationFitsFoo should be scheduled
|
||||||
|
@ -85,13 +85,10 @@ func TestTaintNodeByCondition(t *testing.T) {
|
|||||||
admission.SetExternalKubeClientSet(externalClientset)
|
admission.SetExternalKubeClientSet(externalClientset)
|
||||||
admission.SetExternalKubeInformerFactory(externalInformers)
|
admission.SetExternalKubeInformerFactory(externalInformers)
|
||||||
|
|
||||||
controllerCh := make(chan struct{})
|
|
||||||
defer close(controllerCh)
|
|
||||||
|
|
||||||
// Apply feature gates to enable TaintNodesByCondition
|
// Apply feature gates to enable TaintNodesByCondition
|
||||||
algorithmprovider.ApplyFeatureGates()
|
algorithmprovider.ApplyFeatureGates()
|
||||||
|
|
||||||
context = initTestScheduler(t, context, controllerCh, false, nil)
|
context = initTestScheduler(t, context, false, nil)
|
||||||
cs := context.clientSet
|
cs := context.clientSet
|
||||||
informers := context.informerFactory
|
informers := context.informerFactory
|
||||||
nsName := context.ns.Name
|
nsName := context.ns.Name
|
||||||
@ -120,13 +117,13 @@ func TestTaintNodeByCondition(t *testing.T) {
|
|||||||
t.Errorf("Failed to create node controller: %v", err)
|
t.Errorf("Failed to create node controller: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
go nc.Run(controllerCh)
|
go nc.Run(context.stopCh)
|
||||||
|
|
||||||
// Waiting for all controller sync.
|
// Waiting for all controller sync.
|
||||||
externalInformers.Start(controllerCh)
|
externalInformers.Start(context.stopCh)
|
||||||
externalInformers.WaitForCacheSync(controllerCh)
|
externalInformers.WaitForCacheSync(context.stopCh)
|
||||||
informers.Start(controllerCh)
|
informers.Start(context.stopCh)
|
||||||
informers.WaitForCacheSync(controllerCh)
|
informers.WaitForCacheSync(context.stopCh)
|
||||||
|
|
||||||
// -------------------------------------------
|
// -------------------------------------------
|
||||||
// Test TaintNodeByCondition feature.
|
// Test TaintNodeByCondition feature.
|
||||||
|
@ -65,6 +65,7 @@ type TestContext struct {
|
|||||||
schedulerConfigFactory factory.Configurator
|
schedulerConfigFactory factory.Configurator
|
||||||
schedulerConfig *factory.Config
|
schedulerConfig *factory.Config
|
||||||
scheduler *scheduler.Scheduler
|
scheduler *scheduler.Scheduler
|
||||||
|
stopCh chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// createConfiguratorWithPodInformer creates a configurator for scheduler.
|
// createConfiguratorWithPodInformer creates a configurator for scheduler.
|
||||||
@ -73,6 +74,7 @@ func createConfiguratorWithPodInformer(
|
|||||||
clientSet clientset.Interface,
|
clientSet clientset.Interface,
|
||||||
podInformer coreinformers.PodInformer,
|
podInformer coreinformers.PodInformer,
|
||||||
informerFactory informers.SharedInformerFactory,
|
informerFactory informers.SharedInformerFactory,
|
||||||
|
stopCh <-chan struct{},
|
||||||
) factory.Configurator {
|
) factory.Configurator {
|
||||||
return factory.NewConfigFactory(&factory.ConfigFactoryArgs{
|
return factory.NewConfigFactory(&factory.ConfigFactoryArgs{
|
||||||
SchedulerName: schedulerName,
|
SchedulerName: schedulerName,
|
||||||
@ -92,13 +94,16 @@ func createConfiguratorWithPodInformer(
|
|||||||
DisablePreemption: false,
|
DisablePreemption: false,
|
||||||
PercentageOfNodesToScore: schedulerapi.DefaultPercentageOfNodesToScore,
|
PercentageOfNodesToScore: schedulerapi.DefaultPercentageOfNodesToScore,
|
||||||
BindTimeoutSeconds: 600,
|
BindTimeoutSeconds: 600,
|
||||||
|
StopCh: stopCh,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// initTestMasterAndScheduler initializes a test environment and creates a master with default
|
// initTestMasterAndScheduler initializes a test environment and creates a master with default
|
||||||
// configuration.
|
// configuration.
|
||||||
func initTestMaster(t *testing.T, nsPrefix string, admission admission.Interface) *TestContext {
|
func initTestMaster(t *testing.T, nsPrefix string, admission admission.Interface) *TestContext {
|
||||||
var context TestContext
|
context := TestContext{
|
||||||
|
stopCh: make(chan struct{}),
|
||||||
|
}
|
||||||
|
|
||||||
// 1. Create master
|
// 1. Create master
|
||||||
h := &framework.MasterHolder{Initialized: make(chan struct{})}
|
h := &framework.MasterHolder{Initialized: make(chan struct{})}
|
||||||
@ -138,13 +143,12 @@ func initTestMaster(t *testing.T, nsPrefix string, admission admission.Interface
|
|||||||
func initTestScheduler(
|
func initTestScheduler(
|
||||||
t *testing.T,
|
t *testing.T,
|
||||||
context *TestContext,
|
context *TestContext,
|
||||||
controllerCh chan struct{},
|
|
||||||
setPodInformer bool,
|
setPodInformer bool,
|
||||||
policy *schedulerapi.Policy,
|
policy *schedulerapi.Policy,
|
||||||
) *TestContext {
|
) *TestContext {
|
||||||
// Pod preemption is enabled by default scheduler configuration, but preemption only happens when PodPriority
|
// Pod preemption is enabled by default scheduler configuration, but preemption only happens when PodPriority
|
||||||
// feature gate is enabled at the same time.
|
// feature gate is enabled at the same time.
|
||||||
return initTestSchedulerWithOptions(t, context, controllerCh, setPodInformer, policy, false, false, time.Second)
|
return initTestSchedulerWithOptions(t, context, setPodInformer, policy, false, false, time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
// initTestSchedulerWithOptions initializes a test environment and creates a scheduler with default
|
// initTestSchedulerWithOptions initializes a test environment and creates a scheduler with default
|
||||||
@ -152,7 +156,6 @@ func initTestScheduler(
|
|||||||
func initTestSchedulerWithOptions(
|
func initTestSchedulerWithOptions(
|
||||||
t *testing.T,
|
t *testing.T,
|
||||||
context *TestContext,
|
context *TestContext,
|
||||||
controllerCh chan struct{},
|
|
||||||
setPodInformer bool,
|
setPodInformer bool,
|
||||||
policy *schedulerapi.Policy,
|
policy *schedulerapi.Policy,
|
||||||
disablePreemption bool,
|
disablePreemption bool,
|
||||||
@ -179,7 +182,7 @@ func initTestSchedulerWithOptions(
|
|||||||
}
|
}
|
||||||
|
|
||||||
context.schedulerConfigFactory = createConfiguratorWithPodInformer(
|
context.schedulerConfigFactory = createConfiguratorWithPodInformer(
|
||||||
v1.DefaultSchedulerName, context.clientSet, podInformer, context.informerFactory)
|
v1.DefaultSchedulerName, context.clientSet, podInformer, context.informerFactory, context.stopCh)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -193,11 +196,6 @@ func initTestSchedulerWithOptions(
|
|||||||
t.Fatalf("Couldn't create scheduler config: %v", err)
|
t.Fatalf("Couldn't create scheduler config: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// set controllerCh if provided.
|
|
||||||
if controllerCh != nil {
|
|
||||||
context.schedulerConfig.StopEverything = controllerCh
|
|
||||||
}
|
|
||||||
|
|
||||||
// set DisablePreemption option
|
// set DisablePreemption option
|
||||||
context.schedulerConfig.DisablePreemption = disablePreemption
|
context.schedulerConfig.DisablePreemption = disablePreemption
|
||||||
|
|
||||||
@ -252,21 +250,21 @@ func initDisruptionController(context *TestContext) *disruption.DisruptionContro
|
|||||||
// initTest initializes a test environment and creates master and scheduler with default
|
// initTest initializes a test environment and creates master and scheduler with default
|
||||||
// configuration.
|
// configuration.
|
||||||
func initTest(t *testing.T, nsPrefix string) *TestContext {
|
func initTest(t *testing.T, nsPrefix string) *TestContext {
|
||||||
return initTestScheduler(t, initTestMaster(t, nsPrefix, nil), nil, true, nil)
|
return initTestScheduler(t, initTestMaster(t, nsPrefix, nil), true, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// initTestDisablePreemption initializes a test environment and creates master and scheduler with default
|
// initTestDisablePreemption initializes a test environment and creates master and scheduler with default
|
||||||
// configuration but with pod preemption disabled.
|
// configuration but with pod preemption disabled.
|
||||||
func initTestDisablePreemption(t *testing.T, nsPrefix string) *TestContext {
|
func initTestDisablePreemption(t *testing.T, nsPrefix string) *TestContext {
|
||||||
return initTestSchedulerWithOptions(
|
return initTestSchedulerWithOptions(
|
||||||
t, initTestMaster(t, nsPrefix, nil), nil, true, nil, true, false, time.Second)
|
t, initTestMaster(t, nsPrefix, nil), true, nil, true, false, time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanupTest deletes the scheduler and the test namespace. It should be called
|
// cleanupTest deletes the scheduler and the test namespace. It should be called
|
||||||
// at the end of a test.
|
// at the end of a test.
|
||||||
func cleanupTest(t *testing.T, context *TestContext) {
|
func cleanupTest(t *testing.T, context *TestContext) {
|
||||||
// Kill the scheduler.
|
// Kill the scheduler.
|
||||||
close(context.schedulerConfig.StopEverything)
|
close(context.stopCh)
|
||||||
// Cleanup nodes.
|
// Cleanup nodes.
|
||||||
context.clientSet.CoreV1().Nodes().DeleteCollection(nil, metav1.ListOptions{})
|
context.clientSet.CoreV1().Nodes().DeleteCollection(nil, metav1.ListOptions{})
|
||||||
framework.DeleteTestingNamespace(context.ns, context.httpServer, t)
|
framework.DeleteTestingNamespace(context.ns, context.httpServer, t)
|
||||||
|
@ -901,9 +901,7 @@ func setupCluster(t *testing.T, nsName string, numberOfNodes int, features map[s
|
|||||||
// Set feature gates
|
// Set feature gates
|
||||||
utilfeature.DefaultFeatureGate.SetFromMap(features)
|
utilfeature.DefaultFeatureGate.SetFromMap(features)
|
||||||
|
|
||||||
controllerCh := make(chan struct{})
|
context := initTestSchedulerWithOptions(t, initTestMaster(t, nsName, nil), false, nil, false, disableEquivalenceCache, resyncPeriod)
|
||||||
|
|
||||||
context := initTestSchedulerWithOptions(t, initTestMaster(t, nsName, nil), controllerCh, false, nil, false, disableEquivalenceCache, resyncPeriod)
|
|
||||||
|
|
||||||
clientset := context.clientSet
|
clientset := context.clientSet
|
||||||
ns := context.ns.Name
|
ns := context.ns.Name
|
||||||
@ -912,10 +910,10 @@ func setupCluster(t *testing.T, nsName string, numberOfNodes int, features map[s
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create PV controller: %v", err)
|
t.Fatalf("Failed to create PV controller: %v", err)
|
||||||
}
|
}
|
||||||
go ctrl.Run(controllerCh)
|
go ctrl.Run(context.stopCh)
|
||||||
// Start informer factory after all controllers are configured and running.
|
// Start informer factory after all controllers are configured and running.
|
||||||
informerFactory.Start(controllerCh)
|
informerFactory.Start(context.stopCh)
|
||||||
informerFactory.WaitForCacheSync(controllerCh)
|
informerFactory.WaitForCacheSync(context.stopCh)
|
||||||
|
|
||||||
// Create shared objects
|
// Create shared objects
|
||||||
// Create nodes
|
// Create nodes
|
||||||
@ -936,7 +934,7 @@ func setupCluster(t *testing.T, nsName string, numberOfNodes int, features map[s
|
|||||||
return &testConfig{
|
return &testConfig{
|
||||||
client: clientset,
|
client: clientset,
|
||||||
ns: ns,
|
ns: ns,
|
||||||
stop: controllerCh,
|
stop: context.stopCh,
|
||||||
teardown: func() {
|
teardown: func() {
|
||||||
deleteTestObjects(clientset, ns, nil)
|
deleteTestObjects(clientset, ns, nil)
|
||||||
cleanupTest(t, context)
|
cleanupTest(t, context)
|
||||||
|
@ -66,7 +66,8 @@ func StartScheduler(clientSet clientset.Interface) (factory.Configurator, Shutdo
|
|||||||
evtWatch := evtBroadcaster.StartRecordingToSink(&clientv1core.EventSinkImpl{
|
evtWatch := evtBroadcaster.StartRecordingToSink(&clientv1core.EventSinkImpl{
|
||||||
Interface: clientSet.CoreV1().Events("")})
|
Interface: clientSet.CoreV1().Events("")})
|
||||||
|
|
||||||
schedulerConfigurator := createSchedulerConfigurator(clientSet, informerFactory)
|
stopCh := make(chan struct{})
|
||||||
|
schedulerConfigurator := createSchedulerConfigurator(clientSet, informerFactory, stopCh)
|
||||||
|
|
||||||
sched, err := scheduler.NewFromConfigurator(schedulerConfigurator, func(conf *factory.Config) {
|
sched, err := scheduler.NewFromConfigurator(schedulerConfigurator, func(conf *factory.Config) {
|
||||||
conf.Recorder = evtBroadcaster.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: "scheduler"})
|
conf.Recorder = evtBroadcaster.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: "scheduler"})
|
||||||
@ -75,16 +76,13 @@ func StartScheduler(clientSet clientset.Interface) (factory.Configurator, Shutdo
|
|||||||
glog.Fatalf("Error creating scheduler: %v", err)
|
glog.Fatalf("Error creating scheduler: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
stop := make(chan struct{})
|
informerFactory.Start(stopCh)
|
||||||
informerFactory.Start(stop)
|
|
||||||
|
|
||||||
sched.Run()
|
sched.Run()
|
||||||
|
|
||||||
shutdownFunc := func() {
|
shutdownFunc := func() {
|
||||||
glog.Infof("destroying scheduler")
|
glog.Infof("destroying scheduler")
|
||||||
evtWatch.Stop()
|
evtWatch.Stop()
|
||||||
sched.StopEverything()
|
close(stopCh)
|
||||||
close(stop)
|
|
||||||
glog.Infof("destroyed scheduler")
|
glog.Infof("destroyed scheduler")
|
||||||
}
|
}
|
||||||
return schedulerConfigurator, shutdownFunc
|
return schedulerConfigurator, shutdownFunc
|
||||||
@ -94,6 +92,7 @@ func StartScheduler(clientSet clientset.Interface) (factory.Configurator, Shutdo
|
|||||||
func createSchedulerConfigurator(
|
func createSchedulerConfigurator(
|
||||||
clientSet clientset.Interface,
|
clientSet clientset.Interface,
|
||||||
informerFactory informers.SharedInformerFactory,
|
informerFactory informers.SharedInformerFactory,
|
||||||
|
stopCh <-chan struct{},
|
||||||
) factory.Configurator {
|
) factory.Configurator {
|
||||||
// Enable EnableEquivalenceClassCache for all integration tests.
|
// Enable EnableEquivalenceClassCache for all integration tests.
|
||||||
utilfeature.DefaultFeatureGate.Set("EnableEquivalenceClassCache=true")
|
utilfeature.DefaultFeatureGate.Set("EnableEquivalenceClassCache=true")
|
||||||
@ -115,5 +114,6 @@ func createSchedulerConfigurator(
|
|||||||
EnableEquivalenceClassCache: utilfeature.DefaultFeatureGate.Enabled(features.EnableEquivalenceClassCache),
|
EnableEquivalenceClassCache: utilfeature.DefaultFeatureGate.Enabled(features.EnableEquivalenceClassCache),
|
||||||
DisablePreemption: false,
|
DisablePreemption: false,
|
||||||
PercentageOfNodesToScore: schedulerapi.DefaultPercentageOfNodesToScore,
|
PercentageOfNodesToScore: schedulerapi.DefaultPercentageOfNodesToScore,
|
||||||
|
StopCh: stopCh,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user