Code change:
I'm writing a scheduler plugin using the scheduler framework, and in my plugin I'd like to add a using the provided by the . Adding such a Indexer lead to a runtime crash like The reason for this is that I'm not sure the scheduler framework wants to explicitely disallow adding Indexers using the facilities. If this is the case, it should be more explicit somehow because the current behaviour is surprising. If the scheduler framework doesn't want to add this limitation, then adding indexers should not lead to runtime crashes add a new scheduler plugin trying to add indexers. Sample code (relevant minimal portions only) I'm not sure this is a real bug and not a deliberate decision; a research was inconcusive, and a (admittedly quick) search in the past issues was not fruitful either. The fix could be as trivial as <detailsconsole $ kubectl version Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.2", GitCommit:"", GitTreeState:"clean", BuildDate:"2020-01-18T23:30:10Z", GoVersion:"go1.13.5", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.5+", GitCommit:"", GitTreeState:"clean", BuildDate:"2022-05-10T16:30:48Z", GoVersion:"go1.17.5", Compiler:"gc", Platform:"linux/amd64"} </detailsbut applies also on latest master (see above) <detailsany </details<detailsany </details<detailsnot relevant </details<details</details<details</details
This issue is currently awaiting triage. If a SIG or subproject determines this is a relevant issue, they will accept it by applying the label and provide further guidance. The label can be by org members by writing in a comment. <detailsInstructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
/sig scheduling

Related discussion:
text: return s, fwk, nil } <ins> func TestInitPluginsWithIndexers(t *testing.T) { tests := []struct { name string // the plugin registration ordering must not matter, being map traversal random entrypoints map[string]frameworkruntime.PluginFactory wantErr     string }{ { name: "register indexer, no conflicts", entrypoints: map[string]frameworkruntime.PluginFactory{ "AddIndexer": func(obj runtime.Object, handle framework.Handle) (framework.Plugin, error) { podInformer := handle.SharedInformerFactory().Core().V1().Pods() err := podInformer.Informer().GetIndexer().AddIndexers(cache.Indexers{ "nodeName": indexByPodSpecNodeName, }) return &TestPlugin{name: "AddIndexer"}, err }, }, }, { name: "register the same indexer name multiple times, conflict", // order of registration doesn't matter entrypoints: map[string]frameworkruntime.PluginFactory{ "AddIndexer1": func(obj runtime.Object, handle framework.Handle) (framework.Plugin, error) { podInformer := handle.SharedInformerFactory().Core().V1().Pods() err := podInformer.Informer().GetIndexer().AddIndexers(cache.Indexers{ "nodeName": indexByPodSpecNodeName, }) return &TestPlugin{name: "AddIndexer1"}, err }, "AddIndexer2": func(obj runtime.Object, handle framework.Handle) (framework.Plugin, error) { podInformer := handle.SharedInformerFactory().Core().V1().Pods() err := podInformer.Informer().GetIndexer().AddIndexers(cache.Indexers{ "nodeName": indexByPodAnnotationNodeName, }) return &TestPlugin{name: "AddIndexer1"}, err }, }, wantErr: "indexer conflict", }, { name: "register the same indexer body with different names, no conflicts", // order of registration doesn't matter entrypoints: map[string]frameworkruntime.PluginFactory{ "AddIndexer1": func(obj runtime.Object, handle framework.Handle) (framework.Plugin, error) { podInformer := handle.SharedInformerFactory().Core().V1().Pods() err := podInformer.Informer().GetIndexer().AddIndexers(cache.Indexers{ "nodeName1": indexByPodSpecNodeName, }) return &TestPlugin{name: "AddIndexer1"}, err }, "AddIndexer2": func(obj runtime.Object, handle framework.Handle) (framework.Plugin, error) { podInformer := handle.SharedInformerFactory().Core().V1().Pods() err := podInformer.Informer().GetIndexer().AddIndexers(cache.Indexers{ "nodeName2": indexByPodAnnotationNodeName, }) return &TestPlugin{name: "AddIndexer2"}, err }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { fakeInformerFactory := NewInformerFactory(&fake.Clientset{}, 0*time.Second) var registerPluginFuncs []st.RegisterPluginFunc for name, entrypoint := range tt.entrypoints { registerPluginFuncs = append(registerPluginFuncs, // anything supported by TestPlugin is fine st.RegisterFilterPlugin(name, entrypoint), ) } // we always need this registerPluginFuncs = append(registerPluginFuncs, st.RegisterQueueSortPlugin(queuesort.Name, queuesort.New), st.RegisterBindPlugin(defaultbinder.Name, defaultbinder.New), ) _, err := st.NewFramework(registerPluginFuncs, "test", frameworkruntime.WithInformerFactory(fakeInformerFactory)) if len(tt.wantErr) > 0 { if err == nil || !strings.Contains(err.Error(), tt.wantErr) { t.Errorf("got error %q, want %q", err, tt.wantErr) } return } if err != nil { t.Fatalf("Failed to create scheduler: %v", err) } }) } } func indexByPodSpecNodeName(obj interface{}) ([]string, error) { pod, ok := obj.(*v1.Pod) if !ok { return []string{}, nil } if len(pod.Spec.NodeName) == 0 { return []string{}, nil } return []string{pod.Spec.NodeName}, nil } func indexByPodAnnotationNodeName(obj interface{}) ([]string, error) { pod, ok := obj.(*v1.Pod) if !ok { return []string{}, nil } if len(pod.Annotations) == 0 { return []string{}, nil } nodeName, ok := pod.Annotations["node-name"] if !ok { return []string{}, nil } return []string{nodeName}, nil } </ins>