mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-26 05:03:09 +00:00
Merge pull request #85899 from gongguan/slim_down_lister
slim down some lister expansions
This commit is contained in:
commit
fcc35b0468
@ -231,7 +231,7 @@ func (dc *DeploymentController) addReplicaSet(obj interface{}) {
|
|||||||
// getDeploymentsForReplicaSet returns a list of Deployments that potentially
|
// getDeploymentsForReplicaSet returns a list of Deployments that potentially
|
||||||
// match a ReplicaSet.
|
// match a ReplicaSet.
|
||||||
func (dc *DeploymentController) getDeploymentsForReplicaSet(rs *apps.ReplicaSet) []*apps.Deployment {
|
func (dc *DeploymentController) getDeploymentsForReplicaSet(rs *apps.ReplicaSet) []*apps.Deployment {
|
||||||
deployments, err := dc.dLister.GetDeploymentsForReplicaSet(rs)
|
deployments, err := util.GetDeploymentsForReplicaSet(dc.dLister, rs)
|
||||||
if err != nil || len(deployments) == 0 {
|
if err != nil || len(deployments) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,13 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes/typed/apps/v1:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes/typed/apps/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/client-go/listers/apps/v1:go_default_library",
|
||||||
"//vendor/k8s.io/klog:go_default_library",
|
"//vendor/k8s.io/klog:go_default_library",
|
||||||
"//vendor/k8s.io/utils/integer:go_default_library",
|
"//vendor/k8s.io/utils/integer:go_default_library",
|
||||||
],
|
],
|
||||||
@ -46,6 +48,7 @@ go_test(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library",
|
||||||
|
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/testing:go_default_library",
|
"//staging/src/k8s.io/client-go/testing:go_default_library",
|
||||||
],
|
],
|
||||||
|
@ -24,18 +24,19 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/klog"
|
|
||||||
|
|
||||||
apps "k8s.io/api/apps/v1"
|
apps "k8s.io/api/apps/v1"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
intstrutil "k8s.io/apimachinery/pkg/util/intstr"
|
intstrutil "k8s.io/apimachinery/pkg/util/intstr"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
appsclient "k8s.io/client-go/kubernetes/typed/apps/v1"
|
appsclient "k8s.io/client-go/kubernetes/typed/apps/v1"
|
||||||
|
appslisters "k8s.io/client-go/listers/apps/v1"
|
||||||
|
"k8s.io/klog"
|
||||||
"k8s.io/kubernetes/pkg/controller"
|
"k8s.io/kubernetes/pkg/controller"
|
||||||
labelsutil "k8s.io/kubernetes/pkg/util/labels"
|
labelsutil "k8s.io/kubernetes/pkg/util/labels"
|
||||||
"k8s.io/utils/integer"
|
"k8s.io/utils/integer"
|
||||||
@ -912,3 +913,38 @@ func HasProgressDeadline(d *apps.Deployment) bool {
|
|||||||
func HasRevisionHistoryLimit(d *apps.Deployment) bool {
|
func HasRevisionHistoryLimit(d *apps.Deployment) bool {
|
||||||
return d.Spec.RevisionHistoryLimit != nil && *d.Spec.RevisionHistoryLimit != math.MaxInt32
|
return d.Spec.RevisionHistoryLimit != nil && *d.Spec.RevisionHistoryLimit != math.MaxInt32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDeploymentsForReplicaSet returns a list of Deployments that potentially
|
||||||
|
// match a ReplicaSet. Only the one specified in the ReplicaSet's ControllerRef
|
||||||
|
// will actually manage it.
|
||||||
|
// Returns an error only if no matching Deployments are found.
|
||||||
|
func GetDeploymentsForReplicaSet(deploymentLister appslisters.DeploymentLister, rs *apps.ReplicaSet) ([]*apps.Deployment, error) {
|
||||||
|
if len(rs.Labels) == 0 {
|
||||||
|
return nil, fmt.Errorf("no deployments found for ReplicaSet %v because it has no labels", rs.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: MODIFY THIS METHOD so that it checks for the podTemplateSpecHash label
|
||||||
|
dList, err := deploymentLister.Deployments(rs.Namespace).List(labels.Everything())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var deployments []*apps.Deployment
|
||||||
|
for _, d := range dList {
|
||||||
|
selector, err := metav1.LabelSelectorAsSelector(d.Spec.Selector)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid label selector: %v", err)
|
||||||
|
}
|
||||||
|
// If a deployment with a nil or empty selector creeps in, it should match nothing, not everything.
|
||||||
|
if selector.Empty() || !selector.Matches(labels.Set(rs.Labels)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
deployments = append(deployments, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(deployments) == 0 {
|
||||||
|
return nil, fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rs.Name, rs.Namespace, rs.Labels)
|
||||||
|
}
|
||||||
|
|
||||||
|
return deployments, nil
|
||||||
|
}
|
||||||
|
@ -34,6 +34,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
"k8s.io/apiserver/pkg/storage/names"
|
"k8s.io/apiserver/pkg/storage/names"
|
||||||
|
"k8s.io/client-go/informers"
|
||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
core "k8s.io/client-go/testing"
|
core "k8s.io/client-go/testing"
|
||||||
"k8s.io/kubernetes/pkg/controller"
|
"k8s.io/kubernetes/pkg/controller"
|
||||||
@ -1402,3 +1403,84 @@ func TestReplicasAnnotationsNeedUpdate(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetDeploymentsForReplicaSet(t *testing.T) {
|
||||||
|
fakeInformerFactory := informers.NewSharedInformerFactory(&fake.Clientset{}, 0*time.Second)
|
||||||
|
var deployments []*apps.Deployment
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
deployment := &apps.Deployment{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: fmt.Sprintf("deployment-%d", i),
|
||||||
|
Namespace: "test",
|
||||||
|
},
|
||||||
|
Spec: apps.DeploymentSpec{
|
||||||
|
Selector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{
|
||||||
|
"app": fmt.Sprintf("test-%d", i),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
deployments = append(deployments, deployment)
|
||||||
|
fakeInformerFactory.Apps().V1().Deployments().Informer().GetStore().Add(deployment)
|
||||||
|
}
|
||||||
|
var rss []*apps.ReplicaSet
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
rs := &apps.ReplicaSet{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Namespace: "test",
|
||||||
|
Name: fmt.Sprintf("test-replicaSet-%d", i),
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app": fmt.Sprintf("test-%d", i),
|
||||||
|
"label": fmt.Sprintf("label-%d", i),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
rss = append(rss, rs)
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
rs *apps.ReplicaSet
|
||||||
|
err error
|
||||||
|
expect []*apps.Deployment
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "GetDeploymentsForReplicaSet for rs-0",
|
||||||
|
rs: rss[0],
|
||||||
|
expect: []*apps.Deployment{deployments[0]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GetDeploymentsForReplicaSet for rs-1",
|
||||||
|
rs: rss[1],
|
||||||
|
expect: []*apps.Deployment{deployments[1]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GetDeploymentsForReplicaSet for rs-2",
|
||||||
|
rs: rss[2],
|
||||||
|
expect: []*apps.Deployment{deployments[2]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GetDeploymentsForReplicaSet for rs-3",
|
||||||
|
rs: rss[3],
|
||||||
|
err: fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rss[3].Name, rss[3].Namespace, rss[3].Labels),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GetDeploymentsForReplicaSet for rs-4",
|
||||||
|
rs: rss[4],
|
||||||
|
err: fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rss[4].Name, rss[4].Namespace, rss[4].Labels),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
get, err := GetDeploymentsForReplicaSet(fakeInformerFactory.Apps().V1().Deployments().Lister(), test.rs)
|
||||||
|
if err != nil {
|
||||||
|
if err.Error() != test.err.Error() {
|
||||||
|
t.Errorf("Error from GetDeploymentsForReplicaSet: %v", err)
|
||||||
|
}
|
||||||
|
} else if !reflect.DeepEqual(get, test.expect) {
|
||||||
|
t.Errorf("Expect deployments %v, but got %v", test.expect, get)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -12,6 +12,7 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/util/runtime"
|
"k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
@ -372,7 +373,7 @@ func (s *Controller) syncLoadBalancerIfNeeded(service *v1.Service, key string) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Controller) ensureLoadBalancer(service *v1.Service) (*v1.LoadBalancerStatus, error) {
|
func (s *Controller) ensureLoadBalancer(service *v1.Service) (*v1.LoadBalancerStatus, error) {
|
||||||
nodes, err := s.nodeLister.ListWithPredicate(getNodeConditionPredicate())
|
nodes, err := listWithPredicate(s.nodeLister, getNodeConditionPredicate())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -601,7 +602,7 @@ func nodeSlicesEqualForLB(x, y []*v1.Node) bool {
|
|||||||
return nodeNames(x).Equal(nodeNames(y))
|
return nodeNames(x).Equal(nodeNames(y))
|
||||||
}
|
}
|
||||||
|
|
||||||
func getNodeConditionPredicate() corelisters.NodeConditionPredicate {
|
func getNodeConditionPredicate() NodeConditionPredicate {
|
||||||
return func(node *v1.Node) bool {
|
return func(node *v1.Node) bool {
|
||||||
// We add the master to the node list, but its unschedulable. So we use this to filter
|
// We add the master to the node list, but its unschedulable. So we use this to filter
|
||||||
// the master.
|
// the master.
|
||||||
@ -645,7 +646,7 @@ func getNodeConditionPredicate() corelisters.NodeConditionPredicate {
|
|||||||
// nodeSyncLoop handles updating the hosts pointed to by all load
|
// nodeSyncLoop handles updating the hosts pointed to by all load
|
||||||
// balancers whenever the set of nodes in the cluster changes.
|
// balancers whenever the set of nodes in the cluster changes.
|
||||||
func (s *Controller) nodeSyncLoop() {
|
func (s *Controller) nodeSyncLoop() {
|
||||||
newHosts, err := s.nodeLister.ListWithPredicate(getNodeConditionPredicate())
|
newHosts, err := listWithPredicate(s.nodeLister, getNodeConditionPredicate())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HandleError(fmt.Errorf("Failed to retrieve current set of nodes from node lister: %v", err))
|
runtime.HandleError(fmt.Errorf("Failed to retrieve current set of nodes from node lister: %v", err))
|
||||||
return
|
return
|
||||||
@ -847,3 +848,24 @@ func (s *Controller) patchStatus(service *v1.Service, previousStatus, newStatus
|
|||||||
_, err := patch(s.kubeClient.CoreV1(), service, updated)
|
_, err := patch(s.kubeClient.CoreV1(), service, updated)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NodeConditionPredicate is a function that indicates whether the given node's conditions meet
|
||||||
|
// some set of criteria defined by the function.
|
||||||
|
type NodeConditionPredicate func(node *v1.Node) bool
|
||||||
|
|
||||||
|
// listWithPredicate gets nodes that matches predicate function.
|
||||||
|
func listWithPredicate(nodeLister corelisters.NodeLister, predicate NodeConditionPredicate) ([]*v1.Node, error) {
|
||||||
|
nodes, err := nodeLister.List(labels.Everything())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var filtered []*v1.Node
|
||||||
|
for i := range nodes {
|
||||||
|
if predicate(nodes[i]) {
|
||||||
|
filtered = append(filtered, nodes[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered, nil
|
||||||
|
}
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -1428,3 +1429,67 @@ func Test_getNodeConditionPredicate(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListWithPredicate(t *testing.T) {
|
||||||
|
fakeInformerFactory := informers.NewSharedInformerFactory(&fake.Clientset{}, 0*time.Second)
|
||||||
|
var nodes []*v1.Node
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
var phase v1.NodePhase
|
||||||
|
if i%2 == 0 {
|
||||||
|
phase = v1.NodePending
|
||||||
|
} else {
|
||||||
|
phase = v1.NodeRunning
|
||||||
|
}
|
||||||
|
node := &v1.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: fmt.Sprintf("node-%d", i),
|
||||||
|
},
|
||||||
|
Status: v1.NodeStatus{
|
||||||
|
Phase: phase,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
nodes = append(nodes, node)
|
||||||
|
fakeInformerFactory.Core().V1().Nodes().Informer().GetStore().Add(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
predicate NodeConditionPredicate
|
||||||
|
expect []*v1.Node
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "ListWithPredicate filter Running node",
|
||||||
|
predicate: func(node *v1.Node) bool {
|
||||||
|
return node.Status.Phase == v1.NodeRunning
|
||||||
|
},
|
||||||
|
expect: []*v1.Node{nodes[1], nodes[3]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ListWithPredicate filter Pending node",
|
||||||
|
predicate: func(node *v1.Node) bool {
|
||||||
|
return node.Status.Phase == v1.NodePending
|
||||||
|
},
|
||||||
|
expect: []*v1.Node{nodes[0], nodes[2], nodes[4]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ListWithPredicate filter Terminated node",
|
||||||
|
predicate: func(node *v1.Node) bool {
|
||||||
|
return node.Status.Phase == v1.NodeTerminated
|
||||||
|
},
|
||||||
|
expect: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
get, err := listWithPredicate(fakeInformerFactory.Core().V1().Nodes().Lister(), test.predicate)
|
||||||
|
sort.Slice(get, func(i, j int) bool {
|
||||||
|
return get[i].Name < get[j].Name
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error from ListWithPredicate: %v", err)
|
||||||
|
} else if !reflect.DeepEqual(get, test.expect) {
|
||||||
|
t.Errorf("Expect nodes %v, but got %v", test.expect, get)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -243,7 +243,6 @@ go_test(
|
|||||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/testing:go_default_library",
|
"//staging/src/k8s.io/client-go/testing:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/tools/record:go_default_library",
|
"//staging/src/k8s.io/client-go/tools/record:go_default_library",
|
||||||
|
@ -39,7 +39,6 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
corelisters "k8s.io/client-go/listers/core/v1"
|
|
||||||
"k8s.io/client-go/tools/record"
|
"k8s.io/client-go/tools/record"
|
||||||
"k8s.io/client-go/util/flowcontrol"
|
"k8s.io/client-go/util/flowcontrol"
|
||||||
cadvisortest "k8s.io/kubernetes/pkg/kubelet/cadvisor/testing"
|
cadvisortest "k8s.io/kubernetes/pkg/kubelet/cadvisor/testing"
|
||||||
@ -446,10 +445,6 @@ func (nl testNodeLister) List(_ labels.Selector) (ret []*v1.Node, err error) {
|
|||||||
return nl.nodes, nil
|
return nl.nodes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (nl testNodeLister) ListWithPredicate(_ corelisters.NodeConditionPredicate) ([]*v1.Node, error) {
|
|
||||||
return nl.nodes, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkPodStatus(t *testing.T, kl *Kubelet, pod *v1.Pod, phase v1.PodPhase) {
|
func checkPodStatus(t *testing.T, kl *Kubelet, pod *v1.Pod, phase v1.PodPhase) {
|
||||||
status, found := kl.statusManager.GetPodStatus(pod.UID)
|
status, found := kl.statusManager.GetPodStatus(pod.UID)
|
||||||
require.True(t, found, "Status of pod %q is not found in the status map", pod.UID)
|
require.True(t, found, "Status of pod %q is not found in the status map", pod.UID)
|
||||||
|
@ -1003,7 +1003,7 @@ func (s *ServiceAffinity) serviceAffinityMetadataProducer(pm *predicateMetadata)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Store services which match the pod.
|
// Store services which match the pod.
|
||||||
matchingPodServices, err := s.serviceLister.GetPodServices(pm.pod)
|
matchingPodServices, err := schedulerlisters.GetPodServices(s.serviceLister, pm.pod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf("Error precomputing service affinity: could not list services: %v", err)
|
klog.Errorf("Error precomputing service affinity: could not list services: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ func (pmf *MetadataFactory) PriorityMetadata(
|
|||||||
|
|
||||||
// getFirstServiceSelector returns one selector of services the given pod.
|
// getFirstServiceSelector returns one selector of services the given pod.
|
||||||
func getFirstServiceSelector(pod *v1.Pod, sl corelisters.ServiceLister) (firstServiceSelector labels.Selector) {
|
func getFirstServiceSelector(pod *v1.Pod, sl corelisters.ServiceLister) (firstServiceSelector labels.Selector) {
|
||||||
if services, err := sl.GetPodServices(pod); err == nil && len(services) > 0 {
|
if services, err := schedulerlisters.GetPodServices(sl, pod); err == nil && len(services) > 0 {
|
||||||
return labels.SelectorFromSet(services[0].Spec.Selector)
|
return labels.SelectorFromSet(services[0].Spec.Selector)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -117,7 +117,7 @@ func getSelector(pod *v1.Pod, sl corelisters.ServiceLister, cl corelisters.Repli
|
|||||||
// Since services, RCs, RSs and SSs match the pod, they won't have conflicting
|
// Since services, RCs, RSs and SSs match the pod, they won't have conflicting
|
||||||
// labels. Merging is safe.
|
// labels. Merging is safe.
|
||||||
|
|
||||||
if services, err := sl.GetPodServices(pod); err == nil {
|
if services, err := schedulerlisters.GetPodServices(sl, pod); err == nil {
|
||||||
for _, service := range services {
|
for _, service := range services {
|
||||||
labelSet = labels.Merge(labelSet, service.Spec.Selector)
|
labelSet = labels.Merge(labelSet, service.Spec.Selector)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
@ -9,6 +9,19 @@ go_library(
|
|||||||
"//pkg/scheduler/nodeinfo:go_default_library",
|
"//pkg/scheduler/nodeinfo:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||||
|
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "go_default_test",
|
||||||
|
srcs = ["listers_test.go"],
|
||||||
|
embed = [":go_default_library"],
|
||||||
|
deps = [
|
||||||
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
||||||
|
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -63,7 +63,16 @@ type ServiceLister []*v1.Service
|
|||||||
|
|
||||||
// Services returns nil.
|
// Services returns nil.
|
||||||
func (f ServiceLister) Services(namespace string) corelisters.ServiceNamespaceLister {
|
func (f ServiceLister) Services(namespace string) corelisters.ServiceNamespaceLister {
|
||||||
return nil
|
var services []*v1.Service
|
||||||
|
for i := range f {
|
||||||
|
if f[i].Namespace == namespace {
|
||||||
|
services = append(services, f[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &serviceNamespaceLister{
|
||||||
|
services: services,
|
||||||
|
namespace: namespace,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// List returns v1.ServiceList, the list of all services.
|
// List returns v1.ServiceList, the list of all services.
|
||||||
@ -71,22 +80,18 @@ func (f ServiceLister) List(labels.Selector) ([]*v1.Service, error) {
|
|||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPodServices gets the services that have the selector that match the labels on the given pod.
|
// serviceNamespaceLister is implementation of ServiceNamespaceLister returned by Services() above.
|
||||||
func (f ServiceLister) GetPodServices(pod *v1.Pod) (services []*v1.Service, err error) {
|
type serviceNamespaceLister struct {
|
||||||
var selector labels.Selector
|
services []*v1.Service
|
||||||
|
namespace string
|
||||||
|
}
|
||||||
|
|
||||||
for i := range f {
|
func (f *serviceNamespaceLister) Get(name string) (*v1.Service, error) {
|
||||||
service := f[i]
|
return nil, fmt.Errorf("not implemented")
|
||||||
// consider only services that are in the same namespace as the pod
|
}
|
||||||
if service.Namespace != pod.Namespace {
|
|
||||||
continue
|
func (f *serviceNamespaceLister) List(selector labels.Selector) ([]*v1.Service, error) {
|
||||||
}
|
return f.services, nil
|
||||||
selector = labels.Set(service.Spec.Selector).AsSelectorPreValidated()
|
|
||||||
if selector.Matches(labels.Set(pod.Labels)) {
|
|
||||||
services = append(services, service)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ corelisters.ReplicationControllerLister = &ControllerLister{}
|
var _ corelisters.ReplicationControllerLister = &ControllerLister{}
|
||||||
|
@ -19,6 +19,7 @@ package listers
|
|||||||
import (
|
import (
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
v1listers "k8s.io/client-go/listers/core/v1"
|
||||||
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
|
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -49,3 +50,27 @@ type SharedLister interface {
|
|||||||
Pods() PodLister
|
Pods() PodLister
|
||||||
NodeInfos() NodeInfoLister
|
NodeInfos() NodeInfoLister
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetPodServices gets the services that have the selector that match the labels on the given pod.
|
||||||
|
// TODO: this should be moved to ServiceAffinity plugin once that plugin is ready.
|
||||||
|
func GetPodServices(serviceLister v1listers.ServiceLister, pod *v1.Pod) ([]*v1.Service, error) {
|
||||||
|
allServices, err := serviceLister.Services(pod.Namespace).List(labels.Everything())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var services []*v1.Service
|
||||||
|
for i := range allServices {
|
||||||
|
service := allServices[i]
|
||||||
|
if service.Spec.Selector == nil {
|
||||||
|
// services with nil selectors match nothing, not everything.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
selector := labels.Set(service.Spec.Selector).AsSelectorPreValidated()
|
||||||
|
if selector.Matches(labels.Set(pod.Labels)) {
|
||||||
|
services = append(services, service)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return services, nil
|
||||||
|
}
|
||||||
|
105
pkg/scheduler/listers/listers_test.go
Normal file
105
pkg/scheduler/listers/listers_test.go
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 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 listers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/client-go/informers"
|
||||||
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetPodServices(t *testing.T) {
|
||||||
|
fakeInformerFactory := informers.NewSharedInformerFactory(&fake.Clientset{}, 0*time.Second)
|
||||||
|
var services []*v1.Service
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
service := &v1.Service{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: fmt.Sprintf("service-%d", i),
|
||||||
|
Namespace: "test",
|
||||||
|
},
|
||||||
|
Spec: v1.ServiceSpec{
|
||||||
|
Selector: map[string]string{
|
||||||
|
"app": fmt.Sprintf("test-%d", i),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
services = append(services, service)
|
||||||
|
fakeInformerFactory.Core().V1().Services().Informer().GetStore().Add(service)
|
||||||
|
}
|
||||||
|
var pods []*v1.Pod
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
pod := &v1.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Namespace: "test",
|
||||||
|
Name: fmt.Sprintf("test-pod-%d", i),
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app": fmt.Sprintf("test-%d", i),
|
||||||
|
"label": fmt.Sprintf("label-%d", i),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
pods = append(pods, pod)
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
pod *v1.Pod
|
||||||
|
expect []*v1.Service
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "GetPodServices for pod-0",
|
||||||
|
pod: pods[0],
|
||||||
|
expect: []*v1.Service{services[0]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GetPodServices for pod-1",
|
||||||
|
pod: pods[1],
|
||||||
|
expect: []*v1.Service{services[1]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GetPodServices for pod-2",
|
||||||
|
pod: pods[2],
|
||||||
|
expect: []*v1.Service{services[2]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GetPodServices for pod-3",
|
||||||
|
pod: pods[3],
|
||||||
|
expect: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GetPodServices for pod-4",
|
||||||
|
pod: pods[4],
|
||||||
|
expect: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
get, err := GetPodServices(fakeInformerFactory.Core().V1().Services().Lister(), test.pod)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error from GetPodServices: %v", err)
|
||||||
|
} else if !reflect.DeepEqual(get, test.expect) {
|
||||||
|
t.Errorf("Expect services %v, but got %v", test.expect, get)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,6 @@ go_library(
|
|||||||
"daemonset.go",
|
"daemonset.go",
|
||||||
"daemonset_expansion.go",
|
"daemonset_expansion.go",
|
||||||
"deployment.go",
|
"deployment.go",
|
||||||
"deployment_expansion.go",
|
|
||||||
"expansion_generated.go",
|
"expansion_generated.go",
|
||||||
"replicaset.go",
|
"replicaset.go",
|
||||||
"replicaset_expansion.go",
|
"replicaset_expansion.go",
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
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 v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
apps "k8s.io/api/apps/v1"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DeploymentListerExpansion allows custom methods to be added to
|
|
||||||
// DeploymentLister.
|
|
||||||
type DeploymentListerExpansion interface {
|
|
||||||
GetDeploymentsForReplicaSet(rs *apps.ReplicaSet) ([]*apps.Deployment, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeploymentNamespaceListerExpansion allows custom methods to be added to
|
|
||||||
// DeploymentNamespaceLister.
|
|
||||||
type DeploymentNamespaceListerExpansion interface{}
|
|
||||||
|
|
||||||
// GetDeploymentsForReplicaSet returns a list of Deployments that potentially
|
|
||||||
// match a ReplicaSet. Only the one specified in the ReplicaSet's ControllerRef
|
|
||||||
// will actually manage it.
|
|
||||||
// Returns an error only if no matching Deployments are found.
|
|
||||||
func (s *deploymentLister) GetDeploymentsForReplicaSet(rs *apps.ReplicaSet) ([]*apps.Deployment, error) {
|
|
||||||
if len(rs.Labels) == 0 {
|
|
||||||
return nil, fmt.Errorf("no deployments found for ReplicaSet %v because it has no labels", rs.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: MODIFY THIS METHOD so that it checks for the podTemplateSpecHash label
|
|
||||||
dList, err := s.Deployments(rs.Namespace).List(labels.Everything())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var deployments []*apps.Deployment
|
|
||||||
for _, d := range dList {
|
|
||||||
selector, err := metav1.LabelSelectorAsSelector(d.Spec.Selector)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("invalid label selector: %v", err)
|
|
||||||
}
|
|
||||||
// If a deployment with a nil or empty selector creeps in, it should match nothing, not everything.
|
|
||||||
if selector.Empty() || !selector.Matches(labels.Set(rs.Labels)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
deployments = append(deployments, d)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(deployments) == 0 {
|
|
||||||
return nil, fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rs.Name, rs.Namespace, rs.Labels)
|
|
||||||
}
|
|
||||||
|
|
||||||
return deployments, nil
|
|
||||||
}
|
|
@ -25,3 +25,11 @@ type ControllerRevisionListerExpansion interface{}
|
|||||||
// ControllerRevisionNamespaceListerExpansion allows custom methods to be added to
|
// ControllerRevisionNamespaceListerExpansion allows custom methods to be added to
|
||||||
// ControllerRevisionNamespaceLister.
|
// ControllerRevisionNamespaceLister.
|
||||||
type ControllerRevisionNamespaceListerExpansion interface{}
|
type ControllerRevisionNamespaceListerExpansion interface{}
|
||||||
|
|
||||||
|
// DeploymentListerExpansion allows custom methods to be added to
|
||||||
|
// DeploymentLister.
|
||||||
|
type DeploymentListerExpansion interface{}
|
||||||
|
|
||||||
|
// DeploymentNamespaceListerExpansion allows custom methods to be added to
|
||||||
|
// DeploymentNamespaceLister.
|
||||||
|
type DeploymentNamespaceListerExpansion interface{}
|
||||||
|
@ -12,7 +12,6 @@ go_library(
|
|||||||
"daemonset.go",
|
"daemonset.go",
|
||||||
"daemonset_expansion.go",
|
"daemonset_expansion.go",
|
||||||
"deployment.go",
|
"deployment.go",
|
||||||
"deployment_expansion.go",
|
|
||||||
"expansion_generated.go",
|
"expansion_generated.go",
|
||||||
"replicaset.go",
|
"replicaset.go",
|
||||||
"replicaset_expansion.go",
|
"replicaset_expansion.go",
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
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 v1beta2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
apps "k8s.io/api/apps/v1beta2"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DeploymentListerExpansion allows custom methods to be added to
|
|
||||||
// DeploymentLister.
|
|
||||||
type DeploymentListerExpansion interface {
|
|
||||||
GetDeploymentsForReplicaSet(rs *apps.ReplicaSet) ([]*apps.Deployment, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeploymentNamespaceListerExpansion allows custom methods to be added to
|
|
||||||
// DeploymentNamespaceLister.
|
|
||||||
type DeploymentNamespaceListerExpansion interface{}
|
|
||||||
|
|
||||||
// GetDeploymentsForReplicaSet returns a list of Deployments that potentially
|
|
||||||
// match a ReplicaSet. Only the one specified in the ReplicaSet's ControllerRef
|
|
||||||
// will actually manage it.
|
|
||||||
// Returns an error only if no matching Deployments are found.
|
|
||||||
func (s *deploymentLister) GetDeploymentsForReplicaSet(rs *apps.ReplicaSet) ([]*apps.Deployment, error) {
|
|
||||||
if len(rs.Labels) == 0 {
|
|
||||||
return nil, fmt.Errorf("no deployments found for ReplicaSet %v because it has no labels", rs.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: MODIFY THIS METHOD so that it checks for the podTemplateSpecHash label
|
|
||||||
dList, err := s.Deployments(rs.Namespace).List(labels.Everything())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var deployments []*apps.Deployment
|
|
||||||
for _, d := range dList {
|
|
||||||
selector, err := metav1.LabelSelectorAsSelector(d.Spec.Selector)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("invalid label selector: %v", err)
|
|
||||||
}
|
|
||||||
// If a deployment with a nil or empty selector creeps in, it should match nothing, not everything.
|
|
||||||
if selector.Empty() || !selector.Matches(labels.Set(rs.Labels)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
deployments = append(deployments, d)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(deployments) == 0 {
|
|
||||||
return nil, fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rs.Name, rs.Namespace, rs.Labels)
|
|
||||||
}
|
|
||||||
|
|
||||||
return deployments, nil
|
|
||||||
}
|
|
@ -25,3 +25,11 @@ type ControllerRevisionListerExpansion interface{}
|
|||||||
// ControllerRevisionNamespaceListerExpansion allows custom methods to be added to
|
// ControllerRevisionNamespaceListerExpansion allows custom methods to be added to
|
||||||
// ControllerRevisionNamespaceLister.
|
// ControllerRevisionNamespaceLister.
|
||||||
type ControllerRevisionNamespaceListerExpansion interface{}
|
type ControllerRevisionNamespaceListerExpansion interface{}
|
||||||
|
|
||||||
|
// DeploymentListerExpansion allows custom methods to be added to
|
||||||
|
// DeploymentLister.
|
||||||
|
type DeploymentListerExpansion interface{}
|
||||||
|
|
||||||
|
// DeploymentNamespaceListerExpansion allows custom methods to be added to
|
||||||
|
// DeploymentNamespaceLister.
|
||||||
|
type DeploymentNamespaceListerExpansion interface{}
|
||||||
|
@ -16,7 +16,6 @@ go_library(
|
|||||||
"limitrange.go",
|
"limitrange.go",
|
||||||
"namespace.go",
|
"namespace.go",
|
||||||
"node.go",
|
"node.go",
|
||||||
"node_expansion.go",
|
|
||||||
"persistentvolume.go",
|
"persistentvolume.go",
|
||||||
"persistentvolumeclaim.go",
|
"persistentvolumeclaim.go",
|
||||||
"pod.go",
|
"pod.go",
|
||||||
@ -26,7 +25,6 @@ go_library(
|
|||||||
"resourcequota.go",
|
"resourcequota.go",
|
||||||
"secret.go",
|
"secret.go",
|
||||||
"service.go",
|
"service.go",
|
||||||
"service_expansion.go",
|
|
||||||
"serviceaccount.go",
|
"serviceaccount.go",
|
||||||
],
|
],
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/client-go/listers/core/v1",
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/client-go/listers/core/v1",
|
||||||
|
@ -58,6 +58,10 @@ type LimitRangeNamespaceListerExpansion interface{}
|
|||||||
// NamespaceLister.
|
// NamespaceLister.
|
||||||
type NamespaceListerExpansion interface{}
|
type NamespaceListerExpansion interface{}
|
||||||
|
|
||||||
|
// NodeListerExpansion allows custom methods to be added to
|
||||||
|
// NodeLister.
|
||||||
|
type NodeListerExpansion interface{}
|
||||||
|
|
||||||
// PersistentVolumeListerExpansion allows custom methods to be added to
|
// PersistentVolumeListerExpansion allows custom methods to be added to
|
||||||
// PersistentVolumeLister.
|
// PersistentVolumeLister.
|
||||||
type PersistentVolumeListerExpansion interface{}
|
type PersistentVolumeListerExpansion interface{}
|
||||||
@ -102,6 +106,14 @@ type SecretListerExpansion interface{}
|
|||||||
// SecretNamespaceLister.
|
// SecretNamespaceLister.
|
||||||
type SecretNamespaceListerExpansion interface{}
|
type SecretNamespaceListerExpansion interface{}
|
||||||
|
|
||||||
|
// ServiceListerExpansion allows custom methods to be added to
|
||||||
|
// ServiceLister.
|
||||||
|
type ServiceListerExpansion interface{}
|
||||||
|
|
||||||
|
// ServiceNamespaceListerExpansion allows custom methods to be added to
|
||||||
|
// ServiceNamespaceLister.
|
||||||
|
type ServiceNamespaceListerExpansion interface{}
|
||||||
|
|
||||||
// ServiceAccountListerExpansion allows custom methods to be added to
|
// ServiceAccountListerExpansion allows custom methods to be added to
|
||||||
// ServiceAccountLister.
|
// ServiceAccountLister.
|
||||||
type ServiceAccountListerExpansion interface{}
|
type ServiceAccountListerExpansion interface{}
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
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 v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"k8s.io/api/core/v1"
|
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NodeConditionPredicate is a function that indicates whether the given node's conditions meet
|
|
||||||
// some set of criteria defined by the function.
|
|
||||||
type NodeConditionPredicate func(node *v1.Node) bool
|
|
||||||
|
|
||||||
// NodeListerExpansion allows custom methods to be added to
|
|
||||||
// NodeLister.
|
|
||||||
type NodeListerExpansion interface {
|
|
||||||
ListWithPredicate(predicate NodeConditionPredicate) ([]*v1.Node, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *nodeLister) ListWithPredicate(predicate NodeConditionPredicate) ([]*v1.Node, error) {
|
|
||||||
nodes, err := l.List(labels.Everything())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var filtered []*v1.Node
|
|
||||||
for i := range nodes {
|
|
||||||
if predicate(nodes[i]) {
|
|
||||||
filtered = append(filtered, nodes[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return filtered, nil
|
|
||||||
}
|
|
@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
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 v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"k8s.io/api/core/v1"
|
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ServiceListerExpansion allows custom methods to be added to
|
|
||||||
// ServiceLister.
|
|
||||||
type ServiceListerExpansion interface {
|
|
||||||
GetPodServices(pod *v1.Pod) ([]*v1.Service, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServiceNamespaceListerExpansion allows custom methods to be added to
|
|
||||||
// ServiceNamespaceLister.
|
|
||||||
type ServiceNamespaceListerExpansion interface{}
|
|
||||||
|
|
||||||
// TODO: Move this back to scheduler as a helper function that takes a Store,
|
|
||||||
// rather than a method of ServiceLister.
|
|
||||||
func (s *serviceLister) GetPodServices(pod *v1.Pod) ([]*v1.Service, error) {
|
|
||||||
allServices, err := s.Services(pod.Namespace).List(labels.Everything())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var services []*v1.Service
|
|
||||||
for i := range allServices {
|
|
||||||
service := allServices[i]
|
|
||||||
if service.Spec.Selector == nil {
|
|
||||||
// services with nil selectors match nothing, not everything.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
selector := labels.Set(service.Spec.Selector).AsSelectorPreValidated()
|
|
||||||
if selector.Matches(labels.Set(pod.Labels)) {
|
|
||||||
services = append(services, service)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return services, nil
|
|
||||||
}
|
|
@ -12,7 +12,6 @@ go_library(
|
|||||||
"daemonset.go",
|
"daemonset.go",
|
||||||
"daemonset_expansion.go",
|
"daemonset_expansion.go",
|
||||||
"deployment.go",
|
"deployment.go",
|
||||||
"deployment_expansion.go",
|
|
||||||
"expansion_generated.go",
|
"expansion_generated.go",
|
||||||
"ingress.go",
|
"ingress.go",
|
||||||
"networkpolicy.go",
|
"networkpolicy.go",
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
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 v1beta1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
extensions "k8s.io/api/extensions/v1beta1"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DeploymentListerExpansion allows custom methods to be added to
|
|
||||||
// DeploymentLister.
|
|
||||||
type DeploymentListerExpansion interface {
|
|
||||||
GetDeploymentsForReplicaSet(rs *extensions.ReplicaSet) ([]*extensions.Deployment, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeploymentNamespaceListerExpansion allows custom methods to be added to
|
|
||||||
// DeploymentNamespaceLister.
|
|
||||||
type DeploymentNamespaceListerExpansion interface{}
|
|
||||||
|
|
||||||
// GetDeploymentsForReplicaSet returns a list of Deployments that potentially
|
|
||||||
// match a ReplicaSet. Only the one specified in the ReplicaSet's ControllerRef
|
|
||||||
// will actually manage it.
|
|
||||||
// Returns an error only if no matching Deployments are found.
|
|
||||||
func (s *deploymentLister) GetDeploymentsForReplicaSet(rs *extensions.ReplicaSet) ([]*extensions.Deployment, error) {
|
|
||||||
if len(rs.Labels) == 0 {
|
|
||||||
return nil, fmt.Errorf("no deployments found for ReplicaSet %v because it has no labels", rs.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: MODIFY THIS METHOD so that it checks for the podTemplateSpecHash label
|
|
||||||
dList, err := s.Deployments(rs.Namespace).List(labels.Everything())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var deployments []*extensions.Deployment
|
|
||||||
for _, d := range dList {
|
|
||||||
selector, err := metav1.LabelSelectorAsSelector(d.Spec.Selector)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("invalid label selector: %v", err)
|
|
||||||
}
|
|
||||||
// If a deployment with a nil or empty selector creeps in, it should match nothing, not everything.
|
|
||||||
if selector.Empty() || !selector.Matches(labels.Set(rs.Labels)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
deployments = append(deployments, d)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(deployments) == 0 {
|
|
||||||
return nil, fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rs.Name, rs.Namespace, rs.Labels)
|
|
||||||
}
|
|
||||||
|
|
||||||
return deployments, nil
|
|
||||||
}
|
|
@ -18,6 +18,14 @@ limitations under the License.
|
|||||||
|
|
||||||
package v1beta1
|
package v1beta1
|
||||||
|
|
||||||
|
// DeploymentListerExpansion allows custom methods to be added to
|
||||||
|
// DeploymentLister.
|
||||||
|
type DeploymentListerExpansion interface{}
|
||||||
|
|
||||||
|
// DeploymentNamespaceListerExpansion allows custom methods to be added to
|
||||||
|
// DeploymentNamespaceLister.
|
||||||
|
type DeploymentNamespaceListerExpansion interface{}
|
||||||
|
|
||||||
// IngressListerExpansion allows custom methods to be added to
|
// IngressListerExpansion allows custom methods to be added to
|
||||||
// IngressLister.
|
// IngressLister.
|
||||||
type IngressListerExpansion interface{}
|
type IngressListerExpansion interface{}
|
||||||
|
Loading…
Reference in New Issue
Block a user