mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 06:27:05 +00:00
Merge pull request #95871 from damemi/move-unchanged-scheduler-helpers
Change function signature for MatchNodeSelectorTerms
This commit is contained in:
commit
2729b8e375
@ -15,7 +15,6 @@ go_test(
|
|||||||
"//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/resource:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/resource: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/fields:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -31,6 +30,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/fields: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/apimachinery/pkg/selection:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/selection:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/fields"
|
"k8s.io/apimachinery/pkg/fields"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/selection"
|
"k8s.io/apimachinery/pkg/selection"
|
||||||
|
apierrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
"k8s.io/apimachinery/pkg/util/validation"
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
"k8s.io/kubernetes/pkg/apis/core/helper"
|
"k8s.io/kubernetes/pkg/apis/core/helper"
|
||||||
)
|
)
|
||||||
@ -232,9 +233,9 @@ func containsAccessMode(modes []v1.PersistentVolumeAccessMode, mode v1.Persisten
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeSelectorRequirementsAsSelector converts the []NodeSelectorRequirement api type into a struct that implements
|
// nodeSelectorRequirementsAsSelector converts the []NodeSelectorRequirement api type into a struct that implements
|
||||||
// labels.Selector.
|
// labels.Selector.
|
||||||
func NodeSelectorRequirementsAsSelector(nsm []v1.NodeSelectorRequirement) (labels.Selector, error) {
|
func nodeSelectorRequirementsAsSelector(nsm []v1.NodeSelectorRequirement) (labels.Selector, error) {
|
||||||
if len(nsm) == 0 {
|
if len(nsm) == 0 {
|
||||||
return labels.Nothing(), nil
|
return labels.Nothing(), nil
|
||||||
}
|
}
|
||||||
@ -266,9 +267,9 @@ func NodeSelectorRequirementsAsSelector(nsm []v1.NodeSelectorRequirement) (label
|
|||||||
return selector, nil
|
return selector, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeSelectorRequirementsAsFieldSelector converts the []NodeSelectorRequirement core type into a struct that implements
|
// nodeSelectorRequirementsAsFieldSelector converts the []NodeSelectorRequirement core type into a struct that implements
|
||||||
// fields.Selector.
|
// fields.Selector.
|
||||||
func NodeSelectorRequirementsAsFieldSelector(nsm []v1.NodeSelectorRequirement) (fields.Selector, error) {
|
func nodeSelectorRequirementsAsFieldSelector(nsm []v1.NodeSelectorRequirement) (fields.Selector, error) {
|
||||||
if len(nsm) == 0 {
|
if len(nsm) == 0 {
|
||||||
return fields.Nothing(), nil
|
return fields.Nothing(), nil
|
||||||
}
|
}
|
||||||
@ -315,34 +316,45 @@ func NodeSelectorRequirementKeysExistInNodeSelectorTerms(reqs []v1.NodeSelectorR
|
|||||||
// MatchNodeSelectorTerms checks whether the node labels and fields match node selector terms in ORed;
|
// MatchNodeSelectorTerms checks whether the node labels and fields match node selector terms in ORed;
|
||||||
// nil or empty term matches no objects.
|
// nil or empty term matches no objects.
|
||||||
func MatchNodeSelectorTerms(
|
func MatchNodeSelectorTerms(
|
||||||
nodeSelectorTerms []v1.NodeSelectorTerm,
|
node *v1.Node,
|
||||||
nodeLabels labels.Set,
|
nodeSelector *v1.NodeSelector,
|
||||||
nodeFields fields.Set,
|
) (bool, error) {
|
||||||
) bool {
|
if node == nil {
|
||||||
for _, req := range nodeSelectorTerms {
|
return false, nil
|
||||||
|
}
|
||||||
|
var errors []error
|
||||||
|
for _, req := range nodeSelector.NodeSelectorTerms {
|
||||||
// nil or empty term selects no objects
|
// nil or empty term selects no objects
|
||||||
if len(req.MatchExpressions) == 0 && len(req.MatchFields) == 0 {
|
if len(req.MatchExpressions) == 0 && len(req.MatchFields) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(req.MatchExpressions) != 0 {
|
if len(req.MatchExpressions) != 0 {
|
||||||
labelSelector, err := NodeSelectorRequirementsAsSelector(req.MatchExpressions)
|
labelSelector, err := nodeSelectorRequirementsAsSelector(req.MatchExpressions)
|
||||||
if err != nil || !labelSelector.Matches(nodeLabels) {
|
if err != nil {
|
||||||
|
errors = append(errors, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if labelSelector == nil || !labelSelector.Matches(labels.Set(node.Labels)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(req.MatchFields) != 0 {
|
if len(req.MatchFields) != 0 && len(node.Name) > 0 {
|
||||||
fieldSelector, err := NodeSelectorRequirementsAsFieldSelector(req.MatchFields)
|
fieldSelector, err := nodeSelectorRequirementsAsFieldSelector(req.MatchFields)
|
||||||
if err != nil || !fieldSelector.Matches(nodeFields) {
|
if err != nil {
|
||||||
|
errors = append(errors, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if fieldSelector == nil || !fieldSelector.Matches(fields.Set{"metadata.name": node.Name}) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false, apierrors.NewAggregate(errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TopologySelectorRequirementsAsSelector converts the []TopologySelectorLabelRequirement api type into a struct
|
// TopologySelectorRequirementsAsSelector converts the []TopologySelectorLabelRequirement api type into a struct
|
||||||
|
@ -25,7 +25,6 @@ import (
|
|||||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/fields"
|
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -298,7 +297,7 @@ func TestNodeSelectorRequirementsAsSelector(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i, tc := range tc {
|
for i, tc := range tc {
|
||||||
out, err := NodeSelectorRequirementsAsSelector(tc.in)
|
out, err := nodeSelectorRequirementsAsSelector(tc.in)
|
||||||
if err == nil && tc.expectErr {
|
if err == nil && tc.expectErr {
|
||||||
t.Errorf("[%v]expected error but got none.", i)
|
t.Errorf("[%v]expected error but got none.", i)
|
||||||
}
|
}
|
||||||
@ -594,9 +593,8 @@ func TestGetAvoidPodsFromNode(t *testing.T) {
|
|||||||
|
|
||||||
func TestMatchNodeSelectorTerms(t *testing.T) {
|
func TestMatchNodeSelectorTerms(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
nodeSelectorTerms []v1.NodeSelectorTerm
|
nodeSelector *v1.NodeSelector
|
||||||
nodeLabels labels.Set
|
node *v1.Node
|
||||||
nodeFields fields.Set
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
@ -607,16 +605,15 @@ func TestMatchNodeSelectorTerms(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "nil terms",
|
name: "nil terms",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: nil,
|
nodeSelector: nil,
|
||||||
nodeLabels: nil,
|
node: nil,
|
||||||
nodeFields: nil,
|
|
||||||
},
|
},
|
||||||
want: false,
|
want: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "node label matches matchExpressions terms",
|
name: "node label matches matchExpressions terms",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -624,16 +621,15 @@ func TestMatchNodeSelectorTerms(t *testing.T) {
|
|||||||
Values: []string{"label_1_val"},
|
Values: []string{"label_1_val"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
nodeLabels: map[string]string{"label_1": "label_1_val"},
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"label_1": "label_1_val"}}},
|
||||||
nodeFields: nil,
|
|
||||||
},
|
},
|
||||||
want: true,
|
want: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "node field matches matchFields terms",
|
name: "node field matches matchFields terms",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchFields: []v1.NodeSelectorRequirement{{
|
MatchFields: []v1.NodeSelectorRequirement{{
|
||||||
Key: "metadata.name",
|
Key: "metadata.name",
|
||||||
@ -641,18 +637,15 @@ func TestMatchNodeSelectorTerms(t *testing.T) {
|
|||||||
Values: []string{"host_1"},
|
Values: []string{"host_1"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
nodeLabels: nil,
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "host_1"}},
|
||||||
nodeFields: map[string]string{
|
|
||||||
"metadata.name": "host_1",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
want: true,
|
want: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid node field requirement",
|
name: "invalid node field requirement",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchFields: []v1.NodeSelectorRequirement{{
|
MatchFields: []v1.NodeSelectorRequirement{{
|
||||||
Key: "metadata.name",
|
Key: "metadata.name",
|
||||||
@ -660,18 +653,15 @@ func TestMatchNodeSelectorTerms(t *testing.T) {
|
|||||||
Values: []string{"host_1, host_2"},
|
Values: []string{"host_1, host_2"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
nodeLabels: nil,
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "host_1"}},
|
||||||
nodeFields: map[string]string{
|
|
||||||
"metadata.name": "host_1",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
want: false,
|
want: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "fieldSelectorTerm with node labels",
|
name: "fieldSelectorTerm with node labels",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchFields: []v1.NodeSelectorRequirement{{
|
MatchFields: []v1.NodeSelectorRequirement{{
|
||||||
Key: "metadata.name",
|
Key: "metadata.name",
|
||||||
@ -679,18 +669,17 @@ func TestMatchNodeSelectorTerms(t *testing.T) {
|
|||||||
Values: []string{"host_1"},
|
Values: []string{"host_1"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
nodeLabels: map[string]string{
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "not_host_1", Labels: map[string]string{
|
||||||
"metadata.name": "host_1",
|
"metadata.name": "host_1",
|
||||||
},
|
}}},
|
||||||
nodeFields: nil,
|
|
||||||
},
|
},
|
||||||
want: false,
|
want: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "labelSelectorTerm with node fields",
|
name: "labelSelectorTerm with node fields",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "metadata.name",
|
Key: "metadata.name",
|
||||||
@ -698,18 +687,15 @@ func TestMatchNodeSelectorTerms(t *testing.T) {
|
|||||||
Values: []string{"host_1"},
|
Values: []string{"host_1"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
nodeLabels: nil,
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "host_1"}},
|
||||||
nodeFields: map[string]string{
|
|
||||||
"metadata.name": "host_1",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
want: false,
|
want: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "labelSelectorTerm and fieldSelectorTerm was set, but only node fields",
|
name: "labelSelectorTerm and fieldSelectorTerm was set, but only node fields",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -722,18 +708,15 @@ func TestMatchNodeSelectorTerms(t *testing.T) {
|
|||||||
Values: []string{"host_1"},
|
Values: []string{"host_1"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
nodeLabels: nil,
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "host_1"}},
|
||||||
nodeFields: map[string]string{
|
|
||||||
"metadata.name": "host_1",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
want: false,
|
want: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "labelSelectorTerm and fieldSelectorTerm was set, both node fields and labels (both matched)",
|
name: "labelSelectorTerm and fieldSelectorTerm was set, both node fields and labels (both matched)",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -745,21 +728,19 @@ func TestMatchNodeSelectorTerms(t *testing.T) {
|
|||||||
Operator: v1.NodeSelectorOpIn,
|
Operator: v1.NodeSelectorOpIn,
|
||||||
Values: []string{"host_1"},
|
Values: []string{"host_1"},
|
||||||
}},
|
}},
|
||||||
|
}},
|
||||||
},
|
},
|
||||||
},
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "host_1",
|
||||||
nodeLabels: map[string]string{
|
Labels: map[string]string{
|
||||||
"label_1": "label_1_val",
|
"label_1": "label_1_val",
|
||||||
},
|
}}},
|
||||||
nodeFields: map[string]string{
|
|
||||||
"metadata.name": "host_1",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
want: true,
|
want: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "labelSelectorTerm and fieldSelectorTerm was set, both node fields and labels (one mismatched)",
|
name: "labelSelectorTerm and fieldSelectorTerm was set, both node fields and labels (one mismatched)",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -772,20 +753,18 @@ func TestMatchNodeSelectorTerms(t *testing.T) {
|
|||||||
Values: []string{"host_1"},
|
Values: []string{"host_1"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
nodeLabels: map[string]string{
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "host_1",
|
||||||
|
Labels: map[string]string{
|
||||||
"label_1": "label_1_val-failed",
|
"label_1": "label_1_val-failed",
|
||||||
},
|
}}},
|
||||||
nodeFields: map[string]string{
|
|
||||||
"metadata.name": "host_1",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
want: false,
|
want: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "multi-selector was set, both node fields and labels (one mismatched)",
|
name: "multi-selector was set, both node fields and labels (one mismatched)",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -800,13 +779,11 @@ func TestMatchNodeSelectorTerms(t *testing.T) {
|
|||||||
Values: []string{"host_1"},
|
Values: []string{"host_1"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
nodeLabels: map[string]string{
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "host_1",
|
||||||
|
Labels: map[string]string{
|
||||||
"label_1": "label_1_val-failed",
|
"label_1": "label_1_val-failed",
|
||||||
},
|
}}},
|
||||||
nodeFields: map[string]string{
|
|
||||||
"metadata.name": "host_1",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
want: true,
|
want: true,
|
||||||
},
|
},
|
||||||
@ -814,7 +791,7 @@ func TestMatchNodeSelectorTerms(t *testing.T) {
|
|||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
if got := MatchNodeSelectorTerms(tt.args.nodeSelectorTerms, tt.args.nodeLabels, tt.args.nodeFields); got != tt.want {
|
if got, _ := MatchNodeSelectorTerms(tt.args.node, tt.args.nodeSelector); got != tt.want {
|
||||||
t.Errorf("MatchNodeSelectorTermsORed() = %v, want %v", got, tt.want)
|
t.Errorf("MatchNodeSelectorTermsORed() = %v, want %v", got, tt.want)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -822,33 +799,31 @@ func TestMatchNodeSelectorTerms(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TestMatchNodeSelectorTermsStateless ensures MatchNodeSelectorTerms()
|
// TestMatchNodeSelectorTermsStateless ensures MatchNodeSelectorTerms()
|
||||||
// is invoked in a "stateless" manner, i.e. nodeSelectorTerms should NOT
|
// is invoked in a "stateless" manner, i.e. nodeSelector should NOT
|
||||||
// be deeply modified after invoking
|
// be deeply modified after invoking
|
||||||
func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
nodeSelectorTerms []v1.NodeSelectorTerm
|
nodeSelector *v1.NodeSelector
|
||||||
nodeLabels labels.Set
|
node *v1.Node
|
||||||
nodeFields fields.Set
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
args args
|
args args
|
||||||
want []v1.NodeSelectorTerm
|
want *v1.NodeSelector
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "nil terms",
|
name: "nil terms",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: nil,
|
nodeSelector: nil,
|
||||||
nodeLabels: nil,
|
node: nil,
|
||||||
nodeFields: nil,
|
|
||||||
},
|
},
|
||||||
want: nil,
|
want: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nodeLabels: preordered matchExpressions and nil matchFields",
|
name: "nodeLabels: preordered matchExpressions and nil matchFields",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -856,11 +831,10 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
|||||||
Values: []string{"label_1_val", "label_2_val"},
|
Values: []string{"label_1_val", "label_2_val"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
|
}},
|
||||||
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"label_1": "label_1_val"}}},
|
||||||
},
|
},
|
||||||
nodeLabels: map[string]string{"label_1": "label_1_val"},
|
want: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
nodeFields: nil,
|
|
||||||
},
|
|
||||||
want: []v1.NodeSelectorTerm{
|
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -868,12 +842,12 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
|||||||
Values: []string{"label_1_val", "label_2_val"},
|
Values: []string{"label_1_val", "label_2_val"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nodeLabels: unordered matchExpressions and nil matchFields",
|
name: "nodeLabels: unordered matchExpressions and nil matchFields",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -881,11 +855,10 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
|||||||
Values: []string{"label_2_val", "label_1_val"},
|
Values: []string{"label_2_val", "label_1_val"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
|
}},
|
||||||
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"label_1": "label_1_val"}}},
|
||||||
},
|
},
|
||||||
nodeLabels: map[string]string{"label_1": "label_1_val"},
|
want: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
nodeFields: nil,
|
|
||||||
},
|
|
||||||
want: []v1.NodeSelectorTerm{
|
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -893,12 +866,12 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
|||||||
Values: []string{"label_2_val", "label_1_val"},
|
Values: []string{"label_2_val", "label_1_val"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nodeFields: nil matchExpressions and preordered matchFields",
|
name: "nodeFields: nil matchExpressions and preordered matchFields",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchFields: []v1.NodeSelectorRequirement{{
|
MatchFields: []v1.NodeSelectorRequirement{{
|
||||||
Key: "metadata.name",
|
Key: "metadata.name",
|
||||||
@ -906,13 +879,10 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
|||||||
Values: []string{"host_1", "host_2"},
|
Values: []string{"host_1", "host_2"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
|
}},
|
||||||
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "host_1"}},
|
||||||
},
|
},
|
||||||
nodeLabels: nil,
|
want: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
nodeFields: map[string]string{
|
|
||||||
"metadata.name": "host_1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
want: []v1.NodeSelectorTerm{
|
|
||||||
{
|
{
|
||||||
MatchFields: []v1.NodeSelectorRequirement{{
|
MatchFields: []v1.NodeSelectorRequirement{{
|
||||||
Key: "metadata.name",
|
Key: "metadata.name",
|
||||||
@ -920,12 +890,12 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
|||||||
Values: []string{"host_1", "host_2"},
|
Values: []string{"host_1", "host_2"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nodeFields: nil matchExpressions and unordered matchFields",
|
name: "nodeFields: nil matchExpressions and unordered matchFields",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchFields: []v1.NodeSelectorRequirement{{
|
MatchFields: []v1.NodeSelectorRequirement{{
|
||||||
Key: "metadata.name",
|
Key: "metadata.name",
|
||||||
@ -933,13 +903,10 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
|||||||
Values: []string{"host_2", "host_1"},
|
Values: []string{"host_2", "host_1"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
|
}},
|
||||||
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "host_1"}},
|
||||||
},
|
},
|
||||||
nodeLabels: nil,
|
want: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
nodeFields: map[string]string{
|
|
||||||
"metadata.name": "host_1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
want: []v1.NodeSelectorTerm{
|
|
||||||
{
|
{
|
||||||
MatchFields: []v1.NodeSelectorRequirement{{
|
MatchFields: []v1.NodeSelectorRequirement{{
|
||||||
Key: "metadata.name",
|
Key: "metadata.name",
|
||||||
@ -947,12 +914,12 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
|||||||
Values: []string{"host_2", "host_1"},
|
Values: []string{"host_2", "host_1"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nodeLabels and nodeFields: ordered matchExpressions and ordered matchFields",
|
name: "nodeLabels and nodeFields: ordered matchExpressions and ordered matchFields",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -965,15 +932,13 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
|||||||
Values: []string{"host_1", "host_2"},
|
Values: []string{"host_1", "host_2"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
nodeLabels: map[string]string{
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "host_1",
|
||||||
|
Labels: map[string]string{
|
||||||
"label_1": "label_1_val",
|
"label_1": "label_1_val",
|
||||||
|
}}},
|
||||||
},
|
},
|
||||||
nodeFields: map[string]string{
|
want: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
"metadata.name": "host_1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
want: []v1.NodeSelectorTerm{
|
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -986,12 +951,12 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
|||||||
Values: []string{"host_1", "host_2"},
|
Values: []string{"host_1", "host_2"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nodeLabels and nodeFields: ordered matchExpressions and unordered matchFields",
|
name: "nodeLabels and nodeFields: ordered matchExpressions and unordered matchFields",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -1004,15 +969,13 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
|||||||
Values: []string{"host_2", "host_1"},
|
Values: []string{"host_2", "host_1"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
nodeLabels: map[string]string{
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "host_1",
|
||||||
|
Labels: map[string]string{
|
||||||
"label_1": "label_1_val",
|
"label_1": "label_1_val",
|
||||||
|
}}},
|
||||||
},
|
},
|
||||||
nodeFields: map[string]string{
|
want: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
"metadata.name": "host_1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
want: []v1.NodeSelectorTerm{
|
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -1025,12 +988,12 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
|||||||
Values: []string{"host_2", "host_1"},
|
Values: []string{"host_2", "host_1"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nodeLabels and nodeFields: unordered matchExpressions and ordered matchFields",
|
name: "nodeLabels and nodeFields: unordered matchExpressions and ordered matchFields",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -1043,15 +1006,13 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
|||||||
Values: []string{"host_1", "host_2"},
|
Values: []string{"host_1", "host_2"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
nodeLabels: map[string]string{
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "host_1",
|
||||||
|
Labels: map[string]string{
|
||||||
"label_1": "label_1_val",
|
"label_1": "label_1_val",
|
||||||
|
}}},
|
||||||
},
|
},
|
||||||
nodeFields: map[string]string{
|
want: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
"metadata.name": "host_1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
want: []v1.NodeSelectorTerm{
|
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -1064,12 +1025,12 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
|||||||
Values: []string{"host_1", "host_2"},
|
Values: []string{"host_1", "host_2"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nodeLabels and nodeFields: unordered matchExpressions and unordered matchFields",
|
name: "nodeLabels and nodeFields: unordered matchExpressions and unordered matchFields",
|
||||||
args: args{
|
args: args{
|
||||||
nodeSelectorTerms: []v1.NodeSelectorTerm{
|
nodeSelector: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -1082,15 +1043,13 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
|||||||
Values: []string{"host_2", "host_1"},
|
Values: []string{"host_2", "host_1"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
nodeLabels: map[string]string{
|
node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "host_1",
|
||||||
|
Labels: map[string]string{
|
||||||
"label_1": "label_1_val",
|
"label_1": "label_1_val",
|
||||||
|
}}},
|
||||||
},
|
},
|
||||||
nodeFields: map[string]string{
|
want: &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
"metadata.name": "host_1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
want: []v1.NodeSelectorTerm{
|
|
||||||
{
|
{
|
||||||
MatchExpressions: []v1.NodeSelectorRequirement{{
|
MatchExpressions: []v1.NodeSelectorRequirement{{
|
||||||
Key: "label_1",
|
Key: "label_1",
|
||||||
@ -1103,16 +1062,16 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) {
|
|||||||
Values: []string{"host_2", "host_1"},
|
Values: []string{"host_2", "host_1"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
MatchNodeSelectorTerms(tt.args.nodeSelectorTerms, tt.args.nodeLabels, tt.args.nodeFields)
|
MatchNodeSelectorTerms(tt.args.node, tt.args.nodeSelector)
|
||||||
if !apiequality.Semantic.DeepEqual(tt.args.nodeSelectorTerms, tt.want) {
|
if !apiequality.Semantic.DeepEqual(tt.args.nodeSelector, tt.want) {
|
||||||
// fail when tt.args.nodeSelectorTerms is deeply modified
|
// fail when tt.args.nodeSelector is deeply modified
|
||||||
t.Errorf("MatchNodeSelectorTerms() got = %v, want %v", tt.args.nodeSelectorTerms, tt.want)
|
t.Errorf("MatchNodeSelectorTerms() got = %v, want %v", tt.args.nodeSelector, tt.want)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ go_library(
|
|||||||
"//pkg/scheduler/framework:go_default_library",
|
"//pkg/scheduler/framework: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/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/fields: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/apps/v1:go_default_library",
|
"//staging/src/k8s.io/client-go/listers/apps/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
|
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
|
||||||
|
@ -18,7 +18,6 @@ package helper
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/fields"
|
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
||||||
)
|
)
|
||||||
@ -61,8 +60,7 @@ func PodMatchesNodeSelectorAndAffinityTerms(pod *v1.Pod, node *v1.Node) bool {
|
|||||||
|
|
||||||
// Match node selector for requiredDuringSchedulingIgnoredDuringExecution.
|
// Match node selector for requiredDuringSchedulingIgnoredDuringExecution.
|
||||||
if nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution != nil {
|
if nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution != nil {
|
||||||
nodeSelectorTerms := nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms
|
nodeAffinityMatches = nodeAffinityMatches && nodeMatchesNodeSelectorTerms(node, nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution)
|
||||||
nodeAffinityMatches = nodeAffinityMatches && nodeMatchesNodeSelectorTerms(node, nodeSelectorTerms)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -71,8 +69,8 @@ func PodMatchesNodeSelectorAndAffinityTerms(pod *v1.Pod, node *v1.Node) bool {
|
|||||||
|
|
||||||
// nodeMatchesNodeSelectorTerms checks if a node's labels satisfy a list of node selector terms,
|
// nodeMatchesNodeSelectorTerms checks if a node's labels satisfy a list of node selector terms,
|
||||||
// terms are ORed, and an empty list of terms will match nothing.
|
// terms are ORed, and an empty list of terms will match nothing.
|
||||||
func nodeMatchesNodeSelectorTerms(node *v1.Node, nodeSelectorTerms []v1.NodeSelectorTerm) bool {
|
func nodeMatchesNodeSelectorTerms(node *v1.Node, nodeSelector *v1.NodeSelector) bool {
|
||||||
return v1helper.MatchNodeSelectorTerms(nodeSelectorTerms, node.Labels, fields.Set{
|
// TODO(@alculquicondor, #95738): parse this error earlier in the plugin so we only need to do it once per pod
|
||||||
"metadata.name": node.Name,
|
matches, _ := v1helper.MatchNodeSelectorTerms(node, nodeSelector)
|
||||||
})
|
return matches
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ go_library(
|
|||||||
"//pkg/scheduler/framework:go_default_library",
|
"//pkg/scheduler/framework:go_default_library",
|
||||||
"//pkg/scheduler/framework/plugins/helper:go_default_library",
|
"//pkg/scheduler/framework/plugins/helper: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/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -21,7 +21,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||||
@ -88,12 +87,12 @@ func (pl *NodeAffinity) Score(ctx context.Context, state *framework.CycleState,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Avoid computing it for all nodes if this becomes a performance problem.
|
// TODO: Avoid computing it for all nodes if this becomes a performance problem.
|
||||||
nodeSelector, err := v1helper.NodeSelectorRequirementsAsSelector(preferredSchedulingTerm.Preference.MatchExpressions)
|
matches, err := v1helper.MatchNodeSelectorTerms(node, &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{preferredSchedulingTerm.Preference}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, framework.AsStatus(err)
|
return 0, framework.AsStatus(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if nodeSelector.Matches(labels.Set(node.Labels)) {
|
if matches {
|
||||||
count += int64(preferredSchedulingTerm.Weight)
|
count += int64(preferredSchedulingTerm.Weight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/resource: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/apis/meta/v1/unstructured:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured: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/sets:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
|
@ -35,7 +35,6 @@ import (
|
|||||||
storage "k8s.io/api/storage/v1"
|
storage "k8s.io/api/storage/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
|
||||||
apiruntime "k8s.io/apimachinery/pkg/runtime"
|
apiruntime "k8s.io/apimachinery/pkg/runtime"
|
||||||
utypes "k8s.io/apimachinery/pkg/types"
|
utypes "k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
@ -165,18 +164,20 @@ func GetClassForVolume(kubeClient clientset.Interface, pv *v1.PersistentVolume)
|
|||||||
// CheckNodeAffinity looks at the PV node affinity, and checks if the node has the same corresponding labels
|
// CheckNodeAffinity looks at the PV node affinity, and checks if the node has the same corresponding labels
|
||||||
// This ensures that we don't mount a volume that doesn't belong to this node
|
// This ensures that we don't mount a volume that doesn't belong to this node
|
||||||
func CheckNodeAffinity(pv *v1.PersistentVolume, nodeLabels map[string]string) error {
|
func CheckNodeAffinity(pv *v1.PersistentVolume, nodeLabels map[string]string) error {
|
||||||
return checkVolumeNodeAffinity(pv, nodeLabels)
|
return checkVolumeNodeAffinity(pv, &v1.Node{ObjectMeta: metav1.ObjectMeta{Labels: nodeLabels}})
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkVolumeNodeAffinity(pv *v1.PersistentVolume, nodeLabels map[string]string) error {
|
func checkVolumeNodeAffinity(pv *v1.PersistentVolume, node *v1.Node) error {
|
||||||
if pv.Spec.NodeAffinity == nil {
|
if pv.Spec.NodeAffinity == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if pv.Spec.NodeAffinity.Required != nil {
|
if pv.Spec.NodeAffinity.Required != nil {
|
||||||
terms := pv.Spec.NodeAffinity.Required.NodeSelectorTerms
|
terms := pv.Spec.NodeAffinity.Required
|
||||||
klog.V(10).Infof("Match for Required node selector terms %+v", terms)
|
klog.V(10).Infof("Match for Required node selector terms %+v", terms)
|
||||||
if !v1helper.MatchNodeSelectorTerms(terms, labels.Set(nodeLabels), nil) {
|
if matches, err := v1helper.MatchNodeSelectorTerms(node, terms); err != nil {
|
||||||
|
return err
|
||||||
|
} else if !matches {
|
||||||
return fmt.Errorf("no matching NodeSelectorTerms")
|
return fmt.Errorf("no matching NodeSelectorTerms")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user