mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 10:20:51 +00:00
* Add tracker types and tests * Modify ResourceEventHandler interface's OnAdd member * Add additional ResourceEventHandlerDetailedFuncs struct * Fix SharedInformer to let users track HasSynced for their handlers * Fix in-tree controllers which weren't computing HasSynced correctly * Deprecate the cache.Pop function
163 lines
4.7 KiB
Go
163 lines
4.7 KiB
Go
/*
|
|
Copyright 2017 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package node
|
|
|
|
import (
|
|
"time"
|
|
|
|
"k8s.io/klog/v2"
|
|
|
|
corev1 "k8s.io/api/core/v1"
|
|
storagev1 "k8s.io/api/storage/v1"
|
|
"k8s.io/apimachinery/pkg/util/wait"
|
|
corev1informers "k8s.io/client-go/informers/core/v1"
|
|
storageinformers "k8s.io/client-go/informers/storage/v1"
|
|
"k8s.io/client-go/tools/cache"
|
|
)
|
|
|
|
type graphPopulator struct {
|
|
graph *Graph
|
|
}
|
|
|
|
func AddGraphEventHandlers(
|
|
graph *Graph,
|
|
nodes corev1informers.NodeInformer,
|
|
pods corev1informers.PodInformer,
|
|
pvs corev1informers.PersistentVolumeInformer,
|
|
attachments storageinformers.VolumeAttachmentInformer,
|
|
) {
|
|
g := &graphPopulator{
|
|
graph: graph,
|
|
}
|
|
|
|
podHandler, _ := pods.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
|
AddFunc: g.addPod,
|
|
UpdateFunc: g.updatePod,
|
|
DeleteFunc: g.deletePod,
|
|
})
|
|
|
|
pvsHandler, _ := pvs.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
|
AddFunc: g.addPV,
|
|
UpdateFunc: g.updatePV,
|
|
DeleteFunc: g.deletePV,
|
|
})
|
|
|
|
attachHandler, _ := attachments.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
|
AddFunc: g.addVolumeAttachment,
|
|
UpdateFunc: g.updateVolumeAttachment,
|
|
DeleteFunc: g.deleteVolumeAttachment,
|
|
})
|
|
|
|
go cache.WaitForNamedCacheSync("node_authorizer", wait.NeverStop,
|
|
podHandler.HasSynced, pvsHandler.HasSynced, attachHandler.HasSynced)
|
|
}
|
|
|
|
func (g *graphPopulator) addPod(obj interface{}) {
|
|
g.updatePod(nil, obj)
|
|
}
|
|
|
|
func (g *graphPopulator) updatePod(oldObj, obj interface{}) {
|
|
pod := obj.(*corev1.Pod)
|
|
if len(pod.Spec.NodeName) == 0 {
|
|
// No node assigned
|
|
klog.V(5).Infof("updatePod %s/%s, no node", pod.Namespace, pod.Name)
|
|
return
|
|
}
|
|
if oldPod, ok := oldObj.(*corev1.Pod); ok && oldPod != nil {
|
|
if (pod.Spec.NodeName == oldPod.Spec.NodeName) && (pod.UID == oldPod.UID) {
|
|
// Node and uid are unchanged, all object references in the pod spec are immutable
|
|
klog.V(5).Infof("updatePod %s/%s, node unchanged", pod.Namespace, pod.Name)
|
|
return
|
|
}
|
|
}
|
|
|
|
klog.V(4).Infof("updatePod %s/%s for node %s", pod.Namespace, pod.Name, pod.Spec.NodeName)
|
|
startTime := time.Now()
|
|
g.graph.AddPod(pod)
|
|
klog.V(5).Infof("updatePod %s/%s for node %s completed in %v", pod.Namespace, pod.Name, pod.Spec.NodeName, time.Since(startTime))
|
|
}
|
|
|
|
func (g *graphPopulator) deletePod(obj interface{}) {
|
|
if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok {
|
|
obj = tombstone.Obj
|
|
}
|
|
pod, ok := obj.(*corev1.Pod)
|
|
if !ok {
|
|
klog.Infof("unexpected type %T", obj)
|
|
return
|
|
}
|
|
if len(pod.Spec.NodeName) == 0 {
|
|
klog.V(5).Infof("deletePod %s/%s, no node", pod.Namespace, pod.Name)
|
|
return
|
|
}
|
|
|
|
klog.V(4).Infof("deletePod %s/%s for node %s", pod.Namespace, pod.Name, pod.Spec.NodeName)
|
|
startTime := time.Now()
|
|
g.graph.DeletePod(pod.Name, pod.Namespace)
|
|
klog.V(5).Infof("deletePod %s/%s for node %s completed in %v", pod.Namespace, pod.Name, pod.Spec.NodeName, time.Since(startTime))
|
|
}
|
|
|
|
func (g *graphPopulator) addPV(obj interface{}) {
|
|
g.updatePV(nil, obj)
|
|
}
|
|
|
|
func (g *graphPopulator) updatePV(oldObj, obj interface{}) {
|
|
pv := obj.(*corev1.PersistentVolume)
|
|
// TODO: skip add if uid, pvc, and secrets are all identical between old and new
|
|
g.graph.AddPV(pv)
|
|
}
|
|
|
|
func (g *graphPopulator) deletePV(obj interface{}) {
|
|
if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok {
|
|
obj = tombstone.Obj
|
|
}
|
|
pv, ok := obj.(*corev1.PersistentVolume)
|
|
if !ok {
|
|
klog.Infof("unexpected type %T", obj)
|
|
return
|
|
}
|
|
g.graph.DeletePV(pv.Name)
|
|
}
|
|
|
|
func (g *graphPopulator) addVolumeAttachment(obj interface{}) {
|
|
g.updateVolumeAttachment(nil, obj)
|
|
}
|
|
|
|
func (g *graphPopulator) updateVolumeAttachment(oldObj, obj interface{}) {
|
|
attachment := obj.(*storagev1.VolumeAttachment)
|
|
if oldObj != nil {
|
|
// skip add if node name is identical
|
|
oldAttachment := oldObj.(*storagev1.VolumeAttachment)
|
|
if oldAttachment.Spec.NodeName == attachment.Spec.NodeName {
|
|
return
|
|
}
|
|
}
|
|
g.graph.AddVolumeAttachment(attachment.Name, attachment.Spec.NodeName)
|
|
}
|
|
|
|
func (g *graphPopulator) deleteVolumeAttachment(obj interface{}) {
|
|
if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok {
|
|
obj = tombstone.Obj
|
|
}
|
|
attachment, ok := obj.(*storagev1.VolumeAttachment)
|
|
if !ok {
|
|
klog.Infof("unexpected type %T", obj)
|
|
return
|
|
}
|
|
g.graph.DeleteVolumeAttachment(attachment.Name)
|
|
}
|