github.com/kubewharf/katalyst-core@v0.5.3/pkg/scheduler/plugins/nodeovercommitment/cache/handler.go (about) 1 /* 2 Copyright 2022 The Katalyst Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package cache 18 19 import ( 20 "fmt" 21 22 v1 "k8s.io/api/core/v1" 23 utilruntime "k8s.io/apimachinery/pkg/util/runtime" 24 "k8s.io/client-go/informers" 25 clientgocache "k8s.io/client-go/tools/cache" 26 "k8s.io/klog/v2" 27 28 "github.com/kubewharf/katalyst-api/pkg/apis/node/v1alpha1" 29 "github.com/kubewharf/katalyst-api/pkg/client/informers/externalversions" 30 schedulercache "github.com/kubewharf/katalyst-core/pkg/scheduler/cache" 31 "github.com/kubewharf/katalyst-core/pkg/scheduler/eventhandlers" 32 "github.com/kubewharf/katalyst-core/pkg/util/native" 33 ) 34 35 const ( 36 OvercommitPodHandler = "OvercommitPodHandler" 37 OvercommitCNRHandler = "OvercommitCNRHandler" 38 ) 39 40 // RegisterPodHandler register handler to scheduler event handlers 41 func RegisterPodHandler() { 42 eventhandlers.RegisterEventHandler(OvercommitPodHandler, func(informerFactory informers.SharedInformerFactory, _ externalversions.SharedInformerFactory) { 43 podInformer := informerFactory.Core().V1().Pods() 44 podInformer.Informer().AddEventHandler( 45 clientgocache.FilteringResourceEventHandler{ 46 FilterFunc: func(obj interface{}) bool { 47 switch t := obj.(type) { 48 case *v1.Pod: 49 return native.IsAssignedPod(t) 50 case clientgocache.DeletedFinalStateUnknown: 51 if _, ok := t.Obj.(*v1.Pod); ok { 52 // The carried object may be stale, so we don't use it to check if 53 // it's assigned or not. Attempting to cleanup anyways. 54 return true 55 } 56 utilruntime.HandleError(fmt.Errorf("unable to convert object %T to *v1.Pod", obj)) 57 return false 58 default: 59 utilruntime.HandleError(fmt.Errorf("unable to handle object: %T", obj)) 60 return false 61 } 62 }, 63 Handler: clientgocache.ResourceEventHandlerFuncs{ 64 AddFunc: addPod, 65 UpdateFunc: updatePod, 66 DeleteFunc: deletePod, 67 }, 68 }, 69 ) 70 }) 71 } 72 73 // RegisterCNRHandler register handler to scheduler event handlers 74 func RegisterCNRHandler() { 75 eventhandlers.RegisterEventHandler(OvercommitCNRHandler, func(_ informers.SharedInformerFactory, internalInformerFactory externalversions.SharedInformerFactory) { 76 cnrInformer := internalInformerFactory.Node().V1alpha1().CustomNodeResources() 77 cnrInformer.Informer().AddEventHandler( 78 clientgocache.ResourceEventHandlerFuncs{ 79 AddFunc: addCNR, 80 UpdateFunc: updateCNR, 81 DeleteFunc: deleteCNR, 82 }) 83 }) 84 } 85 86 func addPod(obj interface{}) { 87 pod, ok := obj.(*v1.Pod) 88 if !ok { 89 klog.ErrorS(nil, "Cannot convert to *v1.Pod", "obj", obj) 90 return 91 } 92 klog.V(6).InfoS("Add event for scheduled pod", "pod", klog.KObj(pod)) 93 94 if err := GetCache().AddPod(pod); err != nil { 95 klog.Errorf("%v cache AddPod failed, pod: %v, err: %v", OvercommitPodHandler, klog.KObj(pod), err) 96 } 97 } 98 99 func updatePod(_, newObj interface{}) { 100 newPod, ok := newObj.(*v1.Pod) 101 if !ok { 102 klog.ErrorS(nil, "Cannot convert to *v1.Pod", "obj", newObj) 103 return 104 } 105 klog.V(6).InfoS("Add event for scheduled pod", "pod", klog.KObj(newPod)) 106 107 if err := GetCache().AddPod(newPod); err != nil { 108 klog.Errorf("%v cache AddPod failed, pod: %v, err: %v", OvercommitPodHandler, klog.KObj(newPod), err) 109 } 110 } 111 112 func deletePod(obj interface{}) { 113 var pod *v1.Pod 114 switch t := obj.(type) { 115 case *v1.Pod: 116 pod = t 117 case clientgocache.DeletedFinalStateUnknown: 118 var ok bool 119 pod, ok = t.Obj.(*v1.Pod) 120 if !ok { 121 klog.ErrorS(nil, "Cannot convert to *v1.Pod", "obj", t.Obj) 122 return 123 } 124 default: 125 klog.ErrorS(nil, "Cannot convert to *v1.Pod", "obj", t) 126 return 127 } 128 klog.V(6).InfoS("Delete event for scheduled pod", "pod", klog.KObj(pod)) 129 130 if err := GetCache().RemovePod(pod); err != nil { 131 klog.ErrorS(err, "Scheduler cache RemovePod failed", "pod", klog.KObj(pod)) 132 } 133 } 134 135 func addCNR(obj interface{}) { 136 cnr, ok := obj.(*v1alpha1.CustomNodeResource) 137 if !ok { 138 klog.Errorf("cannot convert obj to CNR: %v", obj) 139 return 140 } 141 142 GetCache().AddOrUpdateCNR(cnr) 143 } 144 145 func updateCNR(_, newObj interface{}) { 146 newCNR, ok := newObj.(*v1alpha1.CustomNodeResource) 147 if !ok { 148 klog.Errorf("cannot convert obj to CNR: %v", newObj) 149 return 150 } 151 152 GetCache().AddOrUpdateCNR(newCNR) 153 } 154 155 func deleteCNR(obj interface{}) { 156 var cnr *v1alpha1.CustomNodeResource 157 switch t := obj.(type) { 158 case *v1alpha1.CustomNodeResource: 159 cnr = t 160 case clientgocache.DeletedFinalStateUnknown: 161 var ok bool 162 cnr, ok = t.Obj.(*v1alpha1.CustomNodeResource) 163 if !ok { 164 klog.ErrorS(nil, "Cannot convert to *apis.CNR", "obj", t.Obj) 165 return 166 } 167 default: 168 klog.ErrorS(nil, "Cannot convert to *apis.CNR", "obj", t) 169 return 170 } 171 172 schedulercache.GetCache().RemoveCNR(cnr) 173 }