volcano.sh/volcano@v1.9.0/pkg/scheduler/plugins/util/k8s/snapshot.go (about)

     1  /*
     2  Copyright 2019 The Kubernetes 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  // Copied from https://github.com/kubernetes/kubernetes/blob/v1.18.3/pkg/scheduler/internal/cache/snapshot.go
    18  // as internal package is not allowed to import
    19  
    20  package k8s
    21  
    22  import (
    23  	"fmt"
    24  
    25  	v1 "k8s.io/api/core/v1"
    26  	"k8s.io/apimachinery/pkg/labels"
    27  	"k8s.io/kubernetes/pkg/scheduler/framework"
    28  
    29  	scheduler "volcano.sh/volcano/pkg/scheduler/framework"
    30  )
    31  
    32  // Snapshot is a snapshot of cache NodeInfo and NodeTree order. The scheduler takes a
    33  // snapshot at the beginning of each scheduling cycle and uses it for its operations in that cycle.
    34  type Snapshot struct {
    35  	// nodeInfoMap a map of node name to a snapshot of its NodeInfo.
    36  	nodeInfoMap map[string]*framework.NodeInfo
    37  	// nodeInfoList is the list of nodes as ordered in the cache's nodeTree.
    38  	nodeInfoList []*framework.NodeInfo
    39  	// havePodsWithAffinityNodeInfoList is the list of nodes with at least one pod declaring affinity terms.
    40  	havePodsWithAffinityNodeInfoList []*framework.NodeInfo
    41  	// havePodsWithRequiredAntiAffinityNodeInfoList is the list of nodes with at least one pod declaring
    42  	// required anti-affinity terms.
    43  	havePodsWithRequiredAntiAffinityNodeInfoList []*framework.NodeInfo
    44  }
    45  
    46  var _ framework.SharedLister = &Snapshot{}
    47  
    48  // NewEmptySnapshot initializes a Snapshot struct and returns it.
    49  func NewEmptySnapshot() *Snapshot {
    50  	return &Snapshot{
    51  		nodeInfoMap: make(map[string]*framework.NodeInfo),
    52  	}
    53  }
    54  
    55  // NewSnapshot initializes a Snapshot struct and returns it.
    56  func NewSnapshot(nodeInfoMap map[string]*framework.NodeInfo) *Snapshot {
    57  	nodeInfoList := make([]*framework.NodeInfo, 0, len(nodeInfoMap))
    58  	havePodsWithAffinityNodeInfoList := make([]*framework.NodeInfo, 0, len(nodeInfoMap))
    59  	havePodsWithRequiredAntiAffinityNodeInfoList := make([]*framework.NodeInfo, 0, len(nodeInfoMap))
    60  	for _, v := range nodeInfoMap {
    61  		nodeInfoList = append(nodeInfoList, v)
    62  		if len(v.PodsWithAffinity) > 0 {
    63  			havePodsWithAffinityNodeInfoList = append(havePodsWithAffinityNodeInfoList, v)
    64  		}
    65  		if len(v.PodsWithRequiredAntiAffinity) > 0 {
    66  			havePodsWithRequiredAntiAffinityNodeInfoList = append(havePodsWithRequiredAntiAffinityNodeInfoList, v)
    67  		}
    68  	}
    69  
    70  	s := NewEmptySnapshot()
    71  	s.nodeInfoMap = nodeInfoMap
    72  	s.nodeInfoList = nodeInfoList
    73  	s.havePodsWithAffinityNodeInfoList = havePodsWithAffinityNodeInfoList
    74  	s.havePodsWithRequiredAntiAffinityNodeInfoList = havePodsWithRequiredAntiAffinityNodeInfoList
    75  
    76  	return s
    77  }
    78  
    79  // Pods returns a PodLister
    80  func (s *Snapshot) Pods() scheduler.PodsLister {
    81  	return podLister(s.nodeInfoList)
    82  }
    83  
    84  // NodeInfos returns a NodeInfoLister.
    85  func (s *Snapshot) NodeInfos() framework.NodeInfoLister {
    86  	return s
    87  }
    88  
    89  // StorageInfos returns a StorageInfoLister.
    90  func (s *Snapshot) StorageInfos() framework.StorageInfoLister {
    91  	return s
    92  }
    93  
    94  type podLister []*framework.NodeInfo
    95  
    96  // List returns the list of pods in the snapshot.
    97  func (p podLister) List(selector labels.Selector) ([]*v1.Pod, error) {
    98  	alwaysTrue := func(*v1.Pod) bool { return true }
    99  	return p.FilteredList(alwaysTrue, selector)
   100  }
   101  
   102  // FilteredList returns a filtered list of pods in the snapshot.
   103  func (p podLister) FilteredList(filter scheduler.PodFilter, selector labels.Selector) ([]*v1.Pod, error) {
   104  	// podFilter is expected to return true for most or all of the pods. We
   105  	// can avoid expensive array growth without wasting too much memory by
   106  	// pre-allocating capacity.
   107  	maxSize := 0
   108  	for _, n := range p {
   109  		maxSize += len(n.Pods)
   110  	}
   111  	pods := make([]*v1.Pod, 0, maxSize)
   112  	for _, n := range p {
   113  		for _, pod := range n.Pods {
   114  			if filter(pod.Pod) && selector.Matches(labels.Set(pod.Pod.Labels)) {
   115  				pods = append(pods, pod.Pod)
   116  			}
   117  		}
   118  	}
   119  	return pods, nil
   120  }
   121  
   122  // List returns the list of nodes in the snapshot.
   123  func (s *Snapshot) List() ([]*framework.NodeInfo, error) {
   124  	return s.nodeInfoList, nil
   125  }
   126  
   127  // HavePodsWithAffinityList returns the list of nodes with at least one pods with inter-pod affinity
   128  func (s *Snapshot) HavePodsWithAffinityList() ([]*framework.NodeInfo, error) {
   129  	return s.havePodsWithAffinityNodeInfoList, nil
   130  }
   131  
   132  // HavePodsWithRequiredAntiAffinityList returns the list of NodeInfos of nodes with pods with required anti-affinity terms.
   133  func (s *Snapshot) HavePodsWithRequiredAntiAffinityList() ([]*framework.NodeInfo, error) {
   134  	return s.havePodsWithRequiredAntiAffinityNodeInfoList, nil
   135  }
   136  
   137  // Get returns the NodeInfo of the given node name.
   138  func (s *Snapshot) Get(nodeName string) (*framework.NodeInfo, error) {
   139  	if v, ok := s.nodeInfoMap[nodeName]; ok && v.Node() != nil {
   140  		return v, nil
   141  	}
   142  	return nil, fmt.Errorf("nodeinfo not found for node name %q", nodeName)
   143  }
   144  
   145  func (s *Snapshot) IsPVCUsedByPods(key string) bool {
   146  	panic("not implemented")
   147  }