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  }