github.com/kubewharf/katalyst-core@v0.5.3/pkg/scheduler/eventhandlers/pod_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 eventhandlers
    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  	"k8s.io/client-go/tools/cache"
    26  	"k8s.io/klog/v2"
    27  
    28  	"github.com/kubewharf/katalyst-api/pkg/client/informers/externalversions"
    29  	schedulercache "github.com/kubewharf/katalyst-core/pkg/scheduler/cache"
    30  	"github.com/kubewharf/katalyst-core/pkg/scheduler/util"
    31  	"github.com/kubewharf/katalyst-core/pkg/util/native"
    32  )
    33  
    34  const (
    35  	CommonPodHandler = "CommonPodHandler"
    36  )
    37  
    38  func RegisterCommonPodHandler() {
    39  	RegisterEventHandler(CommonPodHandler, AddPodEventHandler)
    40  }
    41  
    42  // AddPodEventHandler adds Pod event handlers for the scheduler.
    43  func AddPodEventHandler(informerFactory informers.SharedInformerFactory, _ externalversions.SharedInformerFactory) {
    44  	podInformer := informerFactory.Core().V1().Pods()
    45  	podInformer.Informer().AddEventHandler(
    46  		cache.FilteringResourceEventHandler{
    47  			FilterFunc: func(obj interface{}) bool {
    48  				switch t := obj.(type) {
    49  				case *v1.Pod:
    50  					return util.IsReclaimedPod(t) && native.IsAssignedPod(t)
    51  				case cache.DeletedFinalStateUnknown:
    52  					if pod, ok := t.Obj.(*v1.Pod); ok {
    53  						// The carried object may be stale, so we don't use it to check if
    54  						// it's assigned or not. Attempting to cleanup anyways.
    55  						return util.IsReclaimedPod(pod)
    56  					}
    57  					utilruntime.HandleError(fmt.Errorf("unable to convert object %T to *v1.Pod", obj))
    58  					return false
    59  				default:
    60  					utilruntime.HandleError(fmt.Errorf("unable to handle object: %T", obj))
    61  					return false
    62  				}
    63  			},
    64  			Handler: cache.ResourceEventHandlerFuncs{
    65  				AddFunc:    addPodToCache,
    66  				UpdateFunc: updatePodInCache,
    67  				DeleteFunc: deletePodFromCache,
    68  			},
    69  		},
    70  	)
    71  }
    72  
    73  func addPodToCache(obj interface{}) {
    74  	pod, ok := obj.(*v1.Pod)
    75  	if !ok {
    76  		klog.ErrorS(nil, "Cannot convert to *v1.Pod", "obj", obj)
    77  		return
    78  	}
    79  	klog.V(3).InfoS("Add event for scheduled pod", "pod", klog.KObj(pod))
    80  
    81  	if err := schedulercache.GetCache().AddPod(pod); err != nil {
    82  		klog.ErrorS(err, "Scheduler cache AddPod failed", "pod", klog.KObj(pod))
    83  	}
    84  }
    85  
    86  // since we may have the functionality to change pod resources such as VPA,
    87  // we should also handle pod update events.
    88  func updatePodInCache(_, newObj interface{}) {
    89  	newPod, ok := newObj.(*v1.Pod)
    90  	if !ok {
    91  		klog.ErrorS(nil, "Cannot convert to *v1.Pod", "obj", newObj)
    92  		return
    93  	}
    94  	klog.V(3).InfoS("Add event for scheduled pod", "pod", klog.KObj(newPod))
    95  
    96  	if err := schedulercache.GetCache().AddPod(newPod); err != nil {
    97  		klog.ErrorS(err, "Scheduler cache AddPod failed", "pod", klog.KObj(newPod))
    98  	}
    99  }
   100  
   101  func deletePodFromCache(obj interface{}) {
   102  	var pod *v1.Pod
   103  	switch t := obj.(type) {
   104  	case *v1.Pod:
   105  		pod = t
   106  	case cache.DeletedFinalStateUnknown:
   107  		var ok bool
   108  		pod, ok = t.Obj.(*v1.Pod)
   109  		if !ok {
   110  			klog.ErrorS(nil, "Cannot convert to *v1.Pod", "obj", t.Obj)
   111  			return
   112  		}
   113  	default:
   114  		klog.ErrorS(nil, "Cannot convert to *v1.Pod", "obj", t)
   115  		return
   116  	}
   117  	klog.V(3).InfoS("Delete event for scheduled pod", "pod", klog.KObj(pod))
   118  
   119  	if err := schedulercache.GetCache().RemovePod(pod); err != nil {
   120  		klog.ErrorS(err, "Scheduler cache RemovePod failed", "pod", klog.KObj(pod))
   121  	}
   122  }