diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 5e07baad3e3..ac49eef3634 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -13338,6 +13338,10 @@ "runtimeHandler": { "description": "RuntimeHandler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called \"runc\" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The RuntimeHandler must conform to the DNS Label (RFC 1123) requirements and is immutable.", "type": "string" + }, + "scheduling": { + "$ref": "#/definitions/io.k8s.api.node.v1alpha1.Scheduling", + "description": "Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes." } }, "required": [ @@ -13345,6 +13349,26 @@ ], "type": "object" }, + "io.k8s.api.node.v1alpha1.Scheduling": { + "description": "Scheduling specifies the scheduling constraints for nodes supporting a RuntimeClass.", + "properties": { + "nodeSelector": { + "additionalProperties": { + "type": "string" + }, + "description": "nodeSelector lists labels that must be present on nodes that support this RuntimeClass. Pods using this RuntimeClass can only be scheduled to a node matched by this selector. The RuntimeClass nodeSelector is merged with a pod's existing nodeSelector. Any conflicts will cause the pod to be rejected in admission.", + "type": "object" + }, + "tolerations": { + "description": "tolerations are appended (excluding duplicates) to pods running with this RuntimeClass during admission, effectively unioning the set of nodes tolerated by the pod and the RuntimeClass.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + }, + "type": "array" + } + }, + "type": "object" + }, "io.k8s.api.node.v1beta1.RuntimeClass": { "description": "RuntimeClass defines a class of container runtime supported in the cluster. The RuntimeClass is used to determine which container runtime is used to run all containers in a pod. RuntimeClasses are (currently) manually defined by a user or cluster provisioner, and referenced in the PodSpec. The Kubelet is responsible for resolving the RuntimeClassName reference before running the pod. For more details, see https://git.k8s.io/enhancements/keps/sig-node/runtime-class.md", "properties": { @@ -13363,6 +13387,10 @@ "metadata": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", "description": "More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata" + }, + "scheduling": { + "$ref": "#/definitions/io.k8s.api.node.v1beta1.Scheduling", + "description": "Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes." } }, "required": [ @@ -13412,6 +13440,26 @@ } ] }, + "io.k8s.api.node.v1beta1.Scheduling": { + "description": "Scheduling specifies the scheduling constraints for nodes supporting a RuntimeClass.", + "properties": { + "nodeSelector": { + "additionalProperties": { + "type": "string" + }, + "description": "nodeSelector lists labels that must be present on nodes that support this RuntimeClass. Pods using this RuntimeClass can only be scheduled to a node matched by this selector. The RuntimeClass nodeSelector is merged with a pod's existing nodeSelector. Any conflicts will cause the pod to be rejected in admission.", + "type": "object" + }, + "tolerations": { + "description": "tolerations are appended (excluding duplicates) to pods running with this RuntimeClass during admission, effectively unioning the set of nodes tolerated by the pod and the RuntimeClass.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + }, + "type": "array" + } + }, + "type": "object" + }, "io.k8s.api.policy.v1beta1.AllowedCSIDriver": { "description": "AllowedCSIDriver represents a single inline CSI Driver that is allowed to be used.", "properties": { diff --git a/pkg/apis/node/BUILD b/pkg/apis/node/BUILD index c5f4063c128..ea6be581f4b 100644 --- a/pkg/apis/node/BUILD +++ b/pkg/apis/node/BUILD @@ -11,6 +11,7 @@ go_library( importpath = "k8s.io/kubernetes/pkg/apis/node", visibility = ["//visibility:public"], deps = [ + "//pkg/apis/core:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", diff --git a/pkg/apis/node/types.go b/pkg/apis/node/types.go index a10648f384a..cebc555577e 100644 --- a/pkg/apis/node/types.go +++ b/pkg/apis/node/types.go @@ -18,6 +18,7 @@ package node import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/apis/core" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -45,6 +46,31 @@ type RuntimeClass struct { // The Handler must conform to the DNS Label (RFC 1123) requirements, and is // immutable. Handler string + + // Scheduling holds the scheduling constraints to ensure that pods running + // with this RuntimeClass are scheduled to nodes that support it. + // If scheduling is nil, this RuntimeClass is assumed to be supported by all + // nodes. + // +optional + Scheduling *Scheduling +} + +// Scheduling specifies the scheduling constraints for nodes supporting a +// RuntimeClass. +type Scheduling struct { + // nodeSelector lists labels that must be present on nodes that support this + // RuntimeClass. Pods using this RuntimeClass can only be scheduled to a + // node matched by this selector. The RuntimeClass nodeSelector is merged + // with a pod's existing nodeSelector. Any conflicts will cause the pod to + // be rejected in admission. + // +optional + NodeSelector map[string]string + + // tolerations are appended (excluding duplicates) to pods running with this + // RuntimeClass during admission, effectively unioning the set of nodes + // tolerated by the pod and the RuntimeClass. + // +optional + Tolerations []core.Toleration } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/node/v1alpha1/BUILD b/pkg/apis/node/v1alpha1/BUILD index 3e817dcbc8d..216b1e4f2b7 100644 --- a/pkg/apis/node/v1alpha1/BUILD +++ b/pkg/apis/node/v1alpha1/BUILD @@ -11,7 +11,9 @@ go_library( importpath = "k8s.io/kubernetes/pkg/apis/node/v1alpha1", visibility = ["//visibility:public"], deps = [ + "//pkg/apis/core:go_default_library", "//pkg/apis/node:go_default_library", + "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/node/v1alpha1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", @@ -38,7 +40,9 @@ go_test( srcs = ["conversion_test.go"], embed = [":go_default_library"], deps = [ + "//pkg/apis/core:go_default_library", "//pkg/apis/node:go_default_library", + "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/node/v1alpha1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library", diff --git a/pkg/apis/node/v1alpha1/conversion.go b/pkg/apis/node/v1alpha1/conversion.go index f1e96ea31ae..bbf499bed97 100644 --- a/pkg/apis/node/v1alpha1/conversion.go +++ b/pkg/apis/node/v1alpha1/conversion.go @@ -33,11 +33,19 @@ func addConversionFuncs(s *runtime.Scheme) error { func Convert_v1alpha1_RuntimeClass_To_node_RuntimeClass(in *v1alpha1.RuntimeClass, out *node.RuntimeClass, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta out.Handler = in.Spec.RuntimeHandler + if in.Spec.Scheduling != nil { + out.Scheduling = new(node.Scheduling) + autoConvert_v1alpha1_Scheduling_To_node_Scheduling(in.Spec.Scheduling, out.Scheduling, s) + } return nil } func Convert_node_RuntimeClass_To_v1alpha1_RuntimeClass(in *node.RuntimeClass, out *v1alpha1.RuntimeClass, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta out.Spec.RuntimeHandler = in.Handler + if in.Scheduling != nil { + out.Spec.Scheduling = new(v1alpha1.Scheduling) + autoConvert_node_Scheduling_To_v1alpha1_Scheduling(in.Scheduling, out.Spec.Scheduling, s) + } return nil } diff --git a/pkg/apis/node/v1alpha1/conversion_test.go b/pkg/apis/node/v1alpha1/conversion_test.go index 6c794ef6c78..62dd0986e80 100644 --- a/pkg/apis/node/v1alpha1/conversion_test.go +++ b/pkg/apis/node/v1alpha1/conversion_test.go @@ -21,8 +21,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" v1alpha1 "k8s.io/api/node/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + core "k8s.io/kubernetes/pkg/apis/core" node "k8s.io/kubernetes/pkg/apis/node" ) @@ -31,24 +33,77 @@ func TestRuntimeClassConversion(t *testing.T) { name = "puppy" handler = "heidi" ) - internalRC := node.RuntimeClass{ - ObjectMeta: metav1.ObjectMeta{Name: name}, - Handler: handler, - } - v1alpha1RC := v1alpha1.RuntimeClass{ - ObjectMeta: metav1.ObjectMeta{Name: name}, - Spec: v1alpha1.RuntimeClassSpec{ - RuntimeHandler: handler, + tests := map[string]struct { + internal *node.RuntimeClass + external *v1alpha1.RuntimeClass + }{ + "fully-specified": { + internal: &node.RuntimeClass{ + ObjectMeta: metav1.ObjectMeta{Name: name}, + Handler: handler, + Scheduling: &node.Scheduling{ + NodeSelector: map[string]string{"extra-soft": "true"}, + Tolerations: []core.Toleration{{ + Key: "stinky", + Operator: core.TolerationOpExists, + Effect: core.TaintEffectNoSchedule, + }}, + }, + }, + external: &v1alpha1.RuntimeClass{ + ObjectMeta: metav1.ObjectMeta{Name: name}, + Spec: v1alpha1.RuntimeClassSpec{ + RuntimeHandler: handler, + Scheduling: &v1alpha1.Scheduling{ + NodeSelector: map[string]string{"extra-soft": "true"}, + Tolerations: []corev1.Toleration{{ + Key: "stinky", + Operator: corev1.TolerationOpExists, + Effect: corev1.TaintEffectNoSchedule, + }}, + }, + }, + }, + }, + "empty-scheduling": { + internal: &node.RuntimeClass{ + ObjectMeta: metav1.ObjectMeta{Name: name}, + Handler: handler, + Scheduling: &node.Scheduling{}, + }, + external: &v1alpha1.RuntimeClass{ + ObjectMeta: metav1.ObjectMeta{Name: name}, + Spec: v1alpha1.RuntimeClassSpec{ + RuntimeHandler: handler, + Scheduling: &v1alpha1.Scheduling{}, + }, + }, + }, + "empty": { + internal: &node.RuntimeClass{ + ObjectMeta: metav1.ObjectMeta{Name: name}, + Handler: handler, + }, + external: &v1alpha1.RuntimeClass{ + ObjectMeta: metav1.ObjectMeta{Name: name}, + Spec: v1alpha1.RuntimeClassSpec{ + RuntimeHandler: handler, + }, + }, }, } - convertedInternal := node.RuntimeClass{} - require.NoError(t, - Convert_v1alpha1_RuntimeClass_To_node_RuntimeClass(&v1alpha1RC, &convertedInternal, nil)) - assert.Equal(t, internalRC, convertedInternal) + for name, test := range tests { + t.Run(name, func(t *testing.T) { + convertedInternal := &node.RuntimeClass{} + require.NoError(t, + Convert_v1alpha1_RuntimeClass_To_node_RuntimeClass(test.external, convertedInternal, nil)) + assert.Equal(t, test.internal, convertedInternal, "external -> internal") - convertedV1alpha1 := v1alpha1.RuntimeClass{} - require.NoError(t, - Convert_node_RuntimeClass_To_v1alpha1_RuntimeClass(&internalRC, &convertedV1alpha1, nil)) - assert.Equal(t, v1alpha1RC, convertedV1alpha1) + convertedV1alpha1 := &v1alpha1.RuntimeClass{} + require.NoError(t, + Convert_node_RuntimeClass_To_v1alpha1_RuntimeClass(test.internal, convertedV1alpha1, nil)) + assert.Equal(t, test.external, convertedV1alpha1, "internal -> external") + }) + } } diff --git a/pkg/apis/node/v1alpha1/zz_generated.conversion.go b/pkg/apis/node/v1alpha1/zz_generated.conversion.go index dcb097f842e..f4c4804d54e 100644 --- a/pkg/apis/node/v1alpha1/zz_generated.conversion.go +++ b/pkg/apis/node/v1alpha1/zz_generated.conversion.go @@ -21,9 +21,13 @@ limitations under the License. package v1alpha1 import ( + unsafe "unsafe" + + v1 "k8s.io/api/core/v1" v1alpha1 "k8s.io/api/node/v1alpha1" conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" + core "k8s.io/kubernetes/pkg/apis/core" node "k8s.io/kubernetes/pkg/apis/node" ) @@ -54,6 +58,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*v1alpha1.Scheduling)(nil), (*node.Scheduling)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_Scheduling_To_node_Scheduling(a.(*v1alpha1.Scheduling), b.(*node.Scheduling), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*node.Scheduling)(nil), (*v1alpha1.Scheduling)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_node_Scheduling_To_v1alpha1_Scheduling(a.(*node.Scheduling), b.(*v1alpha1.Scheduling), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*node.RuntimeClass)(nil), (*v1alpha1.RuntimeClass)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_node_RuntimeClass_To_v1alpha1_RuntimeClass(a.(*node.RuntimeClass), b.(*v1alpha1.RuntimeClass), scope) }); err != nil { @@ -76,6 +90,7 @@ func autoConvert_v1alpha1_RuntimeClass_To_node_RuntimeClass(in *v1alpha1.Runtime func autoConvert_node_RuntimeClass_To_v1alpha1_RuntimeClass(in *node.RuntimeClass, out *v1alpha1.RuntimeClass, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta // WARNING: in.Handler requires manual conversion: does not exist in peer-type + // WARNING: in.Scheduling requires manual conversion: does not exist in peer-type return nil } @@ -120,3 +135,25 @@ func autoConvert_node_RuntimeClassList_To_v1alpha1_RuntimeClassList(in *node.Run func Convert_node_RuntimeClassList_To_v1alpha1_RuntimeClassList(in *node.RuntimeClassList, out *v1alpha1.RuntimeClassList, s conversion.Scope) error { return autoConvert_node_RuntimeClassList_To_v1alpha1_RuntimeClassList(in, out, s) } + +func autoConvert_v1alpha1_Scheduling_To_node_Scheduling(in *v1alpha1.Scheduling, out *node.Scheduling, s conversion.Scope) error { + out.NodeSelector = *(*map[string]string)(unsafe.Pointer(&in.NodeSelector)) + out.Tolerations = *(*[]core.Toleration)(unsafe.Pointer(&in.Tolerations)) + return nil +} + +// Convert_v1alpha1_Scheduling_To_node_Scheduling is an autogenerated conversion function. +func Convert_v1alpha1_Scheduling_To_node_Scheduling(in *v1alpha1.Scheduling, out *node.Scheduling, s conversion.Scope) error { + return autoConvert_v1alpha1_Scheduling_To_node_Scheduling(in, out, s) +} + +func autoConvert_node_Scheduling_To_v1alpha1_Scheduling(in *node.Scheduling, out *v1alpha1.Scheduling, s conversion.Scope) error { + out.NodeSelector = *(*map[string]string)(unsafe.Pointer(&in.NodeSelector)) + out.Tolerations = *(*[]v1.Toleration)(unsafe.Pointer(&in.Tolerations)) + return nil +} + +// Convert_node_Scheduling_To_v1alpha1_Scheduling is an autogenerated conversion function. +func Convert_node_Scheduling_To_v1alpha1_Scheduling(in *node.Scheduling, out *v1alpha1.Scheduling, s conversion.Scope) error { + return autoConvert_node_Scheduling_To_v1alpha1_Scheduling(in, out, s) +} diff --git a/pkg/apis/node/v1beta1/BUILD b/pkg/apis/node/v1beta1/BUILD index 692be926ae4..07ef4b482b2 100644 --- a/pkg/apis/node/v1beta1/BUILD +++ b/pkg/apis/node/v1beta1/BUILD @@ -10,7 +10,9 @@ go_library( importpath = "k8s.io/kubernetes/pkg/apis/node/v1beta1", visibility = ["//visibility:public"], deps = [ + "//pkg/apis/core:go_default_library", "//pkg/apis/node:go_default_library", + "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/node/v1beta1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", diff --git a/pkg/apis/node/v1beta1/zz_generated.conversion.go b/pkg/apis/node/v1beta1/zz_generated.conversion.go index ebe97f937c4..35f23db5762 100644 --- a/pkg/apis/node/v1beta1/zz_generated.conversion.go +++ b/pkg/apis/node/v1beta1/zz_generated.conversion.go @@ -23,9 +23,11 @@ package v1beta1 import ( unsafe "unsafe" + v1 "k8s.io/api/core/v1" v1beta1 "k8s.io/api/node/v1beta1" conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" + core "k8s.io/kubernetes/pkg/apis/core" node "k8s.io/kubernetes/pkg/apis/node" ) @@ -56,12 +58,23 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*v1beta1.Scheduling)(nil), (*node.Scheduling)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Scheduling_To_node_Scheduling(a.(*v1beta1.Scheduling), b.(*node.Scheduling), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*node.Scheduling)(nil), (*v1beta1.Scheduling)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_node_Scheduling_To_v1beta1_Scheduling(a.(*node.Scheduling), b.(*v1beta1.Scheduling), scope) + }); err != nil { + return err + } return nil } func autoConvert_v1beta1_RuntimeClass_To_node_RuntimeClass(in *v1beta1.RuntimeClass, out *node.RuntimeClass, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta out.Handler = in.Handler + out.Scheduling = (*node.Scheduling)(unsafe.Pointer(in.Scheduling)) return nil } @@ -73,6 +86,7 @@ func Convert_v1beta1_RuntimeClass_To_node_RuntimeClass(in *v1beta1.RuntimeClass, func autoConvert_node_RuntimeClass_To_v1beta1_RuntimeClass(in *node.RuntimeClass, out *v1beta1.RuntimeClass, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta out.Handler = in.Handler + out.Scheduling = (*v1beta1.Scheduling)(unsafe.Pointer(in.Scheduling)) return nil } @@ -102,3 +116,25 @@ func autoConvert_node_RuntimeClassList_To_v1beta1_RuntimeClassList(in *node.Runt func Convert_node_RuntimeClassList_To_v1beta1_RuntimeClassList(in *node.RuntimeClassList, out *v1beta1.RuntimeClassList, s conversion.Scope) error { return autoConvert_node_RuntimeClassList_To_v1beta1_RuntimeClassList(in, out, s) } + +func autoConvert_v1beta1_Scheduling_To_node_Scheduling(in *v1beta1.Scheduling, out *node.Scheduling, s conversion.Scope) error { + out.NodeSelector = *(*map[string]string)(unsafe.Pointer(&in.NodeSelector)) + out.Tolerations = *(*[]core.Toleration)(unsafe.Pointer(&in.Tolerations)) + return nil +} + +// Convert_v1beta1_Scheduling_To_node_Scheduling is an autogenerated conversion function. +func Convert_v1beta1_Scheduling_To_node_Scheduling(in *v1beta1.Scheduling, out *node.Scheduling, s conversion.Scope) error { + return autoConvert_v1beta1_Scheduling_To_node_Scheduling(in, out, s) +} + +func autoConvert_node_Scheduling_To_v1beta1_Scheduling(in *node.Scheduling, out *v1beta1.Scheduling, s conversion.Scope) error { + out.NodeSelector = *(*map[string]string)(unsafe.Pointer(&in.NodeSelector)) + out.Tolerations = *(*[]v1.Toleration)(unsafe.Pointer(&in.Tolerations)) + return nil +} + +// Convert_node_Scheduling_To_v1beta1_Scheduling is an autogenerated conversion function. +func Convert_node_Scheduling_To_v1beta1_Scheduling(in *node.Scheduling, out *v1beta1.Scheduling, s conversion.Scope) error { + return autoConvert_node_Scheduling_To_v1beta1_Scheduling(in, out, s) +} diff --git a/pkg/apis/node/validation/BUILD b/pkg/apis/node/validation/BUILD index 7d7345099df..6e28a9229ba 100644 --- a/pkg/apis/node/validation/BUILD +++ b/pkg/apis/node/validation/BUILD @@ -6,8 +6,10 @@ go_library( importpath = "k8s.io/kubernetes/pkg/apis/node/validation", visibility = ["//visibility:public"], deps = [ + "//pkg/apis/core/validation:go_default_library", "//pkg/apis/node:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/validation:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", ], ) @@ -17,6 +19,7 @@ go_test( srcs = ["validation_test.go"], embed = [":go_default_library"], deps = [ + "//pkg/apis/core:go_default_library", "//pkg/apis/node:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library", diff --git a/pkg/apis/node/validation/validation.go b/pkg/apis/node/validation/validation.go index b89a01ff58d..b5a22c9bd44 100644 --- a/pkg/apis/node/validation/validation.go +++ b/pkg/apis/node/validation/validation.go @@ -18,7 +18,9 @@ package validation import ( apivalidation "k8s.io/apimachinery/pkg/api/validation" + unversionedvalidation "k8s.io/apimachinery/pkg/apis/meta/v1/validation" "k8s.io/apimachinery/pkg/util/validation/field" + corevalidation "k8s.io/kubernetes/pkg/apis/core/validation" "k8s.io/kubernetes/pkg/apis/node" ) @@ -30,6 +32,10 @@ func ValidateRuntimeClass(rc *node.RuntimeClass) field.ErrorList { allErrs = append(allErrs, field.Invalid(field.NewPath("handler"), rc.Handler, msg)) } + if rc.Scheduling != nil { + allErrs = append(allErrs, validateScheduling(rc.Scheduling, field.NewPath("scheduling"))...) + } + return allErrs } @@ -41,3 +47,12 @@ func ValidateRuntimeClassUpdate(new, old *node.RuntimeClass) field.ErrorList { return allErrs } + +func validateScheduling(s *node.Scheduling, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + if s.NodeSelector != nil { + allErrs = append(allErrs, unversionedvalidation.ValidateLabels(s.NodeSelector, fldPath.Child("nodeSelector"))...) + } + allErrs = append(allErrs, corevalidation.ValidateTolerations(s.Tolerations, fldPath.Child("tolerations"))...) + return allErrs +} diff --git a/pkg/apis/node/validation/validation_test.go b/pkg/apis/node/validation/validation_test.go index fcbdc0e9a1d..1e27602ed41 100644 --- a/pkg/apis/node/validation/validation_test.go +++ b/pkg/apis/node/validation/validation_test.go @@ -20,6 +20,7 @@ import ( "testing" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/node" "github.com/stretchr/testify/assert" @@ -126,3 +127,70 @@ func TestValidateRuntimeUpdate(t *testing.T) { }) } } + +func TestValidateScheduling(t *testing.T) { + tests := []struct { + name string + scheduling *node.Scheduling + expectErrs int + }{{ + name: "valid scheduling", + scheduling: &node.Scheduling{ + NodeSelector: map[string]string{"valid": "yes"}, + Tolerations: []core.Toleration{{ + Key: "valid", + Operator: core.TolerationOpExists, + Effect: core.TaintEffectNoSchedule, + }}, + }, + }, { + name: "empty scheduling", + scheduling: &node.Scheduling{}, + }, { + name: "invalid nodeSelector", + scheduling: &node.Scheduling{ + NodeSelector: map[string]string{"not a valid key!!!": "nope"}, + }, + expectErrs: 1, + }, { + name: "invalid toleration", + scheduling: &node.Scheduling{ + Tolerations: []core.Toleration{{ + Key: "valid", + Operator: core.TolerationOpExists, + Effect: core.TaintEffectNoSchedule, + }, { + Key: "not a valid key!!!", + Operator: core.TolerationOpExists, + Effect: core.TaintEffectNoSchedule, + }}, + }, + expectErrs: 1, + }, { + name: "invalid scheduling", + scheduling: &node.Scheduling{ + NodeSelector: map[string]string{"not a valid key!!!": "nope"}, + Tolerations: []core.Toleration{{ + Key: "valid", + Operator: core.TolerationOpExists, + Effect: core.TaintEffectNoSchedule, + }, { + Key: "not a valid toleration key!!!", + Operator: core.TolerationOpExists, + Effect: core.TaintEffectNoSchedule, + }}, + }, + expectErrs: 2, + }} + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + rc := &node.RuntimeClass{ + ObjectMeta: metav1.ObjectMeta{Name: "foo"}, + Handler: "bar", + Scheduling: test.scheduling, + } + assert.Len(t, ValidateRuntimeClass(rc), test.expectErrs) + }) + } +} diff --git a/pkg/apis/node/zz_generated.deepcopy.go b/pkg/apis/node/zz_generated.deepcopy.go index 0f563289e1a..5765e025a56 100644 --- a/pkg/apis/node/zz_generated.deepcopy.go +++ b/pkg/apis/node/zz_generated.deepcopy.go @@ -22,6 +22,7 @@ package node import ( runtime "k8s.io/apimachinery/pkg/runtime" + core "k8s.io/kubernetes/pkg/apis/core" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -29,6 +30,11 @@ func (in *RuntimeClass) DeepCopyInto(out *RuntimeClass) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Scheduling != nil { + in, out := &in.Scheduling, &out.Scheduling + *out = new(Scheduling) + (*in).DeepCopyInto(*out) + } return } @@ -82,3 +88,33 @@ func (in *RuntimeClassList) DeepCopyObject() runtime.Object { } return nil } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Scheduling) DeepCopyInto(out *Scheduling) { + *out = *in + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]core.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Scheduling. +func (in *Scheduling) DeepCopy() *Scheduling { + if in == nil { + return nil + } + out := new(Scheduling) + in.DeepCopyInto(out) + return out +} diff --git a/staging/src/k8s.io/api/BUILD b/staging/src/k8s.io/api/BUILD index 364f85d0a51..e1d4fecb373 100644 --- a/staging/src/k8s.io/api/BUILD +++ b/staging/src/k8s.io/api/BUILD @@ -24,6 +24,8 @@ go_test( "//staging/src/k8s.io/api/extensions/v1beta1:go_default_library", "//staging/src/k8s.io/api/imagepolicy/v1alpha1:go_default_library", "//staging/src/k8s.io/api/networking/v1:go_default_library", + "//staging/src/k8s.io/api/node/v1alpha1:go_default_library", + "//staging/src/k8s.io/api/node/v1beta1:go_default_library", "//staging/src/k8s.io/api/policy/v1beta1:go_default_library", "//staging/src/k8s.io/api/rbac/v1:go_default_library", "//staging/src/k8s.io/api/rbac/v1alpha1:go_default_library", diff --git a/staging/src/k8s.io/api/node/v1alpha1/BUILD b/staging/src/k8s.io/api/node/v1alpha1/BUILD index 4f8f496f616..6a176d0a913 100644 --- a/staging/src/k8s.io/api/node/v1alpha1/BUILD +++ b/staging/src/k8s.io/api/node/v1alpha1/BUILD @@ -14,10 +14,12 @@ go_library( importpath = "k8s.io/api/node/v1alpha1", visibility = ["//visibility:public"], 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/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/github.com/gogo/protobuf/proto:go_default_library", + "//vendor/github.com/gogo/protobuf/sortkeys:go_default_library", ], ) diff --git a/staging/src/k8s.io/api/node/v1alpha1/generated.pb.go b/staging/src/k8s.io/api/node/v1alpha1/generated.pb.go index 16f5af92992..28c5e6a4371 100644 --- a/staging/src/k8s.io/api/node/v1alpha1/generated.pb.go +++ b/staging/src/k8s.io/api/node/v1alpha1/generated.pb.go @@ -27,6 +27,7 @@ limitations under the License. RuntimeClass RuntimeClassList RuntimeClassSpec + Scheduling */ package v1alpha1 @@ -34,6 +35,10 @@ import proto "github.com/gogo/protobuf/proto" import fmt "fmt" import math "math" +import k8s_io_api_core_v1 "k8s.io/api/core/v1" + +import github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + import strings "strings" import reflect "reflect" @@ -62,10 +67,15 @@ func (m *RuntimeClassSpec) Reset() { *m = RuntimeClassSpec{} func (*RuntimeClassSpec) ProtoMessage() {} func (*RuntimeClassSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{2} } +func (m *Scheduling) Reset() { *m = Scheduling{} } +func (*Scheduling) ProtoMessage() {} +func (*Scheduling) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{3} } + func init() { proto.RegisterType((*RuntimeClass)(nil), "k8s.io.api.node.v1alpha1.RuntimeClass") proto.RegisterType((*RuntimeClassList)(nil), "k8s.io.api.node.v1alpha1.RuntimeClassList") proto.RegisterType((*RuntimeClassSpec)(nil), "k8s.io.api.node.v1alpha1.RuntimeClassSpec") + proto.RegisterType((*Scheduling)(nil), "k8s.io.api.node.v1alpha1.Scheduling") } func (m *RuntimeClass) Marshal() (dAtA []byte, err error) { size := m.Size() @@ -158,6 +168,68 @@ func (m *RuntimeClassSpec) MarshalTo(dAtA []byte) (int, error) { i++ i = encodeVarintGenerated(dAtA, i, uint64(len(m.RuntimeHandler))) i += copy(dAtA[i:], m.RuntimeHandler) + if m.Scheduling != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Scheduling.Size())) + n4, err := m.Scheduling.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n4 + } + return i, nil +} + +func (m *Scheduling) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Scheduling) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.NodeSelector) > 0 { + keysForNodeSelector := make([]string, 0, len(m.NodeSelector)) + for k := range m.NodeSelector { + keysForNodeSelector = append(keysForNodeSelector, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForNodeSelector) + for _, k := range keysForNodeSelector { + dAtA[i] = 0xa + i++ + v := m.NodeSelector[string(k)] + mapSize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) + i = encodeVarintGenerated(dAtA, i, uint64(mapSize)) + dAtA[i] = 0xa + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(k))) + i += copy(dAtA[i:], k) + dAtA[i] = 0x12 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(v))) + i += copy(dAtA[i:], v) + } + } + if len(m.Tolerations) > 0 { + for _, msg := range m.Tolerations { + dAtA[i] = 0x12 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } return i, nil } @@ -199,6 +271,30 @@ func (m *RuntimeClassSpec) Size() (n int) { _ = l l = len(m.RuntimeHandler) n += 1 + l + sovGenerated(uint64(l)) + if m.Scheduling != nil { + l = m.Scheduling.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *Scheduling) Size() (n int) { + var l int + _ = l + if len(m.NodeSelector) > 0 { + for k, v := range m.NodeSelector { + _ = k + _ = v + mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) + n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) + } + } + if len(m.Tolerations) > 0 { + for _, e := range m.Tolerations { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -243,6 +339,28 @@ func (this *RuntimeClassSpec) String() string { } s := strings.Join([]string{`&RuntimeClassSpec{`, `RuntimeHandler:` + fmt.Sprintf("%v", this.RuntimeHandler) + `,`, + `Scheduling:` + strings.Replace(fmt.Sprintf("%v", this.Scheduling), "Scheduling", "Scheduling", 1) + `,`, + `}`, + }, "") + return s +} +func (this *Scheduling) String() string { + if this == nil { + return "nil" + } + keysForNodeSelector := make([]string, 0, len(this.NodeSelector)) + for k := range this.NodeSelector { + keysForNodeSelector = append(keysForNodeSelector, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForNodeSelector) + mapStringForNodeSelector := "map[string]string{" + for _, k := range keysForNodeSelector { + mapStringForNodeSelector += fmt.Sprintf("%v: %v,", k, this.NodeSelector[k]) + } + mapStringForNodeSelector += "}" + s := strings.Join([]string{`&Scheduling{`, + `NodeSelector:` + mapStringForNodeSelector + `,`, + `Tolerations:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Tolerations), "Toleration", "k8s_io_api_core_v1.Toleration", 1), `&`, ``, 1) + `,`, `}`, }, "") return s @@ -534,6 +652,238 @@ func (m *RuntimeClassSpec) Unmarshal(dAtA []byte) error { } m.RuntimeHandler = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Scheduling", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Scheduling == nil { + m.Scheduling = &Scheduling{} + } + if err := m.Scheduling.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Scheduling) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Scheduling: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Scheduling: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeSelector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NodeSelector == nil { + m.NodeSelector = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.NodeSelector[mapkey] = mapvalue + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Tolerations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Tolerations = append(m.Tolerations, k8s_io_api_core_v1.Toleration{}) + if err := m.Tolerations[len(m.Tolerations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -665,32 +1015,41 @@ func init() { } var fileDescriptorGenerated = []byte{ - // 421 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0x41, 0x6b, 0xd4, 0x40, - 0x14, 0xc7, 0x33, 0xb5, 0x85, 0x75, 0x5a, 0x4b, 0xc9, 0x41, 0xc2, 0x1e, 0xa6, 0x65, 0x0f, 0x52, - 0x04, 0x67, 0xdc, 0x22, 0xe2, 0x49, 0x30, 0x5e, 0x14, 0x2b, 0x42, 0xbc, 0x89, 0x07, 0x27, 0xc9, - 0x33, 0x19, 0xb3, 0xc9, 0x0c, 0x99, 0x49, 0xc0, 0x9b, 0x1f, 0xc1, 0x2f, 0xa4, 0xe7, 0x3d, 0xf6, - 0xd8, 0x53, 0x71, 0xe3, 0x17, 0x91, 0x99, 0x64, 0xbb, 0xdb, 0x2e, 0xc5, 0xbd, 0xe5, 0xbd, 0xf9, - 0xff, 0x7f, 0xef, 0xfd, 0x5f, 0xf0, 0xab, 0xe2, 0x85, 0xa6, 0x42, 0xb2, 0xa2, 0x89, 0xa1, 0xae, - 0xc0, 0x80, 0x66, 0x2d, 0x54, 0xa9, 0xac, 0xd9, 0xf0, 0xc0, 0x95, 0x60, 0x95, 0x4c, 0x81, 0xb5, - 0x53, 0x3e, 0x53, 0x39, 0x9f, 0xb2, 0x0c, 0x2a, 0xa8, 0xb9, 0x81, 0x94, 0xaa, 0x5a, 0x1a, 0xe9, - 0x07, 0xbd, 0x92, 0x72, 0x25, 0xa8, 0x55, 0xd2, 0xa5, 0x72, 0xfc, 0x24, 0x13, 0x26, 0x6f, 0x62, - 0x9a, 0xc8, 0x92, 0x65, 0x32, 0x93, 0xcc, 0x19, 0xe2, 0xe6, 0xab, 0xab, 0x5c, 0xe1, 0xbe, 0x7a, - 0xd0, 0xf8, 0xd9, 0x6a, 0x64, 0xc9, 0x93, 0x5c, 0x54, 0x50, 0x7f, 0x67, 0xaa, 0xc8, 0x6c, 0x43, - 0xb3, 0x12, 0x0c, 0x67, 0xed, 0xc6, 0xf8, 0x31, 0xbb, 0xcb, 0x55, 0x37, 0x95, 0x11, 0x25, 0x6c, - 0x18, 0x9e, 0xff, 0xcf, 0xa0, 0x93, 0x1c, 0x4a, 0x7e, 0xdb, 0x37, 0xf9, 0x8d, 0xf0, 0x41, 0xd4, - 0x4b, 0x5e, 0xcf, 0xb8, 0xd6, 0xfe, 0x17, 0x3c, 0xb2, 0x4b, 0xa5, 0xdc, 0xf0, 0x00, 0x9d, 0xa0, - 0xd3, 0xfd, 0xb3, 0xa7, 0x74, 0x75, 0x8b, 0x6b, 0x36, 0x55, 0x45, 0x66, 0x1b, 0x9a, 0x5a, 0x35, - 0x6d, 0xa7, 0xf4, 0x43, 0xfc, 0x0d, 0x12, 0xf3, 0x1e, 0x0c, 0x0f, 0xfd, 0xf9, 0xd5, 0xb1, 0xd7, - 0x5d, 0x1d, 0xe3, 0x55, 0x2f, 0xba, 0xa6, 0xfa, 0xe7, 0x78, 0x57, 0x2b, 0x48, 0x82, 0x1d, 0x47, - 0x7f, 0x4c, 0xef, 0xba, 0x34, 0x5d, 0xdf, 0xeb, 0xa3, 0x82, 0x24, 0x3c, 0x18, 0xb8, 0xbb, 0xb6, - 0x8a, 0x1c, 0x65, 0xf2, 0x0b, 0xe1, 0xa3, 0x75, 0xe1, 0xb9, 0xd0, 0xc6, 0xff, 0xbc, 0x11, 0x82, - 0x6e, 0x17, 0xc2, 0xba, 0x5d, 0x84, 0xa3, 0x61, 0xd4, 0x68, 0xd9, 0x59, 0x0b, 0xf0, 0x0e, 0xef, - 0x09, 0x03, 0xa5, 0x0e, 0x76, 0x4e, 0xee, 0x9d, 0xee, 0x9f, 0x3d, 0xda, 0x2e, 0x41, 0xf8, 0x60, - 0x40, 0xee, 0xbd, 0xb5, 0xe6, 0xa8, 0x67, 0x4c, 0xa2, 0x9b, 0xeb, 0xdb, 0x64, 0xfe, 0x4b, 0x7c, - 0x38, 0xfc, 0xb6, 0x37, 0xbc, 0x4a, 0x67, 0x50, 0xbb, 0x10, 0xf7, 0xc3, 0x87, 0x03, 0xe1, 0x30, - 0xba, 0xf1, 0x1a, 0xdd, 0x52, 0x87, 0x74, 0xbe, 0x20, 0xde, 0xc5, 0x82, 0x78, 0x97, 0x0b, 0xe2, - 0xfd, 0xe8, 0x08, 0x9a, 0x77, 0x04, 0x5d, 0x74, 0x04, 0x5d, 0x76, 0x04, 0xfd, 0xe9, 0x08, 0xfa, - 0xf9, 0x97, 0x78, 0x9f, 0x46, 0xcb, 0x35, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x94, 0x34, 0x0e, - 0xef, 0x30, 0x03, 0x00, 0x00, + // 568 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xc1, 0x6e, 0xd3, 0x4c, + 0x10, 0x8e, 0xd3, 0x56, 0x4a, 0x37, 0xf9, 0xa3, 0xfc, 0x4b, 0x85, 0xa2, 0x1c, 0xdc, 0x2a, 0x42, + 0xa8, 0x42, 0x62, 0x97, 0x54, 0xa8, 0xaa, 0x38, 0x80, 0x30, 0x42, 0x02, 0x51, 0x40, 0xda, 0x94, + 0x0b, 0xe2, 0xc0, 0xc6, 0x1e, 0x1c, 0x13, 0xdb, 0x6b, 0x79, 0xd7, 0x91, 0x72, 0xe3, 0x11, 0x38, + 0xf1, 0x0c, 0xbc, 0x04, 0x9c, 0x73, 0xec, 0xb1, 0xa7, 0x8a, 0x98, 0x17, 0x41, 0x6b, 0x3b, 0x89, + 0x9b, 0x10, 0x91, 0x9b, 0x67, 0xe6, 0xfb, 0xbe, 0x99, 0x6f, 0x66, 0x8d, 0x9e, 0x8e, 0xce, 0x24, + 0xf1, 0x04, 0x1d, 0x25, 0x03, 0x88, 0x43, 0x50, 0x20, 0xe9, 0x18, 0x42, 0x47, 0xc4, 0xb4, 0x28, + 0xf0, 0xc8, 0xa3, 0xa1, 0x70, 0x80, 0x8e, 0x7b, 0xdc, 0x8f, 0x86, 0xbc, 0x47, 0x5d, 0x08, 0x21, + 0xe6, 0x0a, 0x1c, 0x12, 0xc5, 0x42, 0x09, 0xdc, 0xce, 0x91, 0x84, 0x47, 0x1e, 0xd1, 0x48, 0x32, + 0x47, 0x76, 0xee, 0xbb, 0x9e, 0x1a, 0x26, 0x03, 0x62, 0x8b, 0x80, 0xba, 0xc2, 0x15, 0x34, 0x23, + 0x0c, 0x92, 0x4f, 0x59, 0x94, 0x05, 0xd9, 0x57, 0x2e, 0xd4, 0xe9, 0x96, 0x5a, 0xda, 0x22, 0xd6, + 0x2d, 0x57, 0x9b, 0x75, 0x1e, 0x2e, 0x31, 0x01, 0xb7, 0x87, 0x5e, 0x08, 0xf1, 0x84, 0x46, 0x23, + 0x57, 0x27, 0x24, 0x0d, 0x40, 0xf1, 0xbf, 0xb1, 0xe8, 0x26, 0x56, 0x9c, 0x84, 0xca, 0x0b, 0x60, + 0x8d, 0x70, 0xfa, 0x2f, 0x82, 0xb4, 0x87, 0x10, 0xf0, 0x55, 0x5e, 0xf7, 0xa7, 0x81, 0x1a, 0x2c, + 0x87, 0x3c, 0xf3, 0xb9, 0x94, 0xf8, 0x23, 0xaa, 0xe9, 0xa1, 0x1c, 0xae, 0x78, 0xdb, 0x38, 0x32, + 0x8e, 0xeb, 0x27, 0x0f, 0xc8, 0x72, 0x5f, 0x0b, 0x6d, 0x12, 0x8d, 0x5c, 0x9d, 0x90, 0x44, 0xa3, + 0xc9, 0xb8, 0x47, 0xde, 0x0e, 0x3e, 0x83, 0xad, 0x5e, 0x83, 0xe2, 0x16, 0x9e, 0x5e, 0x1f, 0x56, + 0xd2, 0xeb, 0x43, 0xb4, 0xcc, 0xb1, 0x85, 0x2a, 0x3e, 0x47, 0xbb, 0x32, 0x02, 0xbb, 0x5d, 0xcd, + 0xd4, 0xef, 0x91, 0x4d, 0xd7, 0x20, 0xe5, 0xb9, 0xfa, 0x11, 0xd8, 0x56, 0xa3, 0xd0, 0xdd, 0xd5, + 0x11, 0xcb, 0x54, 0xba, 0x3f, 0x0c, 0xd4, 0x2a, 0x03, 0xcf, 0x3d, 0xa9, 0xf0, 0x87, 0x35, 0x13, + 0x64, 0x3b, 0x13, 0x9a, 0x9d, 0x59, 0x68, 0x15, 0xad, 0x6a, 0xf3, 0x4c, 0xc9, 0xc0, 0x2b, 0xb4, + 0xe7, 0x29, 0x08, 0x64, 0xbb, 0x7a, 0xb4, 0x73, 0x5c, 0x3f, 0xb9, 0xbb, 0x9d, 0x03, 0xeb, 0xbf, + 0x42, 0x72, 0xef, 0xa5, 0x26, 0xb3, 0x5c, 0xa3, 0xfb, 0x7d, 0x65, 0x7e, 0x6d, 0x0d, 0x3f, 0x46, + 0xcd, 0xe2, 0x6e, 0x2f, 0x78, 0xe8, 0xf8, 0x10, 0x67, 0x2e, 0xf6, 0xad, 0xdb, 0x85, 0x44, 0x93, + 0xdd, 0xa8, 0xb2, 0x15, 0x34, 0xbe, 0x40, 0x48, 0xdf, 0xdb, 0x49, 0x7c, 0x2f, 0x74, 0xdb, 0x3b, + 0xd9, 0x06, 0xee, 0x6c, 0x1e, 0xb3, 0xbf, 0xc0, 0x5a, 0x4d, 0x7d, 0xb6, 0x65, 0xcc, 0x4a, 0x3a, + 0xdd, 0x6f, 0x55, 0x54, 0x2a, 0xe1, 0x08, 0x35, 0xb4, 0x4c, 0x1f, 0x7c, 0xb0, 0x95, 0xd0, 0x23, + 0xea, 0x6d, 0x9c, 0x6e, 0xd3, 0x86, 0xbc, 0x29, 0x11, 0x9f, 0x87, 0x2a, 0x9e, 0x58, 0x07, 0x85, + 0xb5, 0x46, 0xb9, 0xc4, 0x6e, 0x74, 0xc0, 0xef, 0x50, 0x5d, 0x09, 0x5f, 0xbf, 0x5f, 0x4f, 0x84, + 0xf3, 0xf5, 0x9b, 0xe5, 0x86, 0xfa, 0x2f, 0xd4, 0x77, 0xbc, 0x58, 0xc0, 0xac, 0x5b, 0x85, 0x70, + 0x7d, 0x99, 0x93, 0xac, 0xac, 0xd3, 0x79, 0x82, 0xfe, 0x5f, 0x9b, 0x07, 0xb7, 0xd0, 0xce, 0x08, + 0x26, 0xf9, 0xde, 0x99, 0xfe, 0xc4, 0x07, 0x68, 0x6f, 0xcc, 0xfd, 0x04, 0xb2, 0x87, 0xbb, 0xcf, + 0xf2, 0xe0, 0x51, 0xf5, 0xcc, 0xb0, 0xc8, 0x74, 0x66, 0x56, 0x2e, 0x67, 0x66, 0xe5, 0x6a, 0x66, + 0x56, 0xbe, 0xa4, 0xa6, 0x31, 0x4d, 0x4d, 0xe3, 0x32, 0x35, 0x8d, 0xab, 0xd4, 0x34, 0x7e, 0xa5, + 0xa6, 0xf1, 0xf5, 0xb7, 0x59, 0x79, 0x5f, 0x9b, 0x2f, 0xe2, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xa4, 0x0d, 0x70, 0xa4, 0xc4, 0x04, 0x00, 0x00, } diff --git a/staging/src/k8s.io/api/node/v1alpha1/generated.proto b/staging/src/k8s.io/api/node/v1alpha1/generated.proto index ca4e5e53506..39d5a96b44a 100644 --- a/staging/src/k8s.io/api/node/v1alpha1/generated.proto +++ b/staging/src/k8s.io/api/node/v1alpha1/generated.proto @@ -21,6 +21,7 @@ syntax = 'proto2'; package k8s.io.api.node.v1alpha1; +import "k8s.io/api/core/v1/generated.proto"; import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; @@ -72,5 +73,30 @@ message RuntimeClassSpec { // The RuntimeHandler must conform to the DNS Label (RFC 1123) requirements // and is immutable. optional string runtimeHandler = 1; + + // Scheduling holds the scheduling constraints to ensure that pods running + // with this RuntimeClass are scheduled to nodes that support it. + // If scheduling is nil, this RuntimeClass is assumed to be supported by all + // nodes. + // +optional + optional Scheduling scheduling = 3; +} + +// Scheduling specifies the scheduling constraints for nodes supporting a +// RuntimeClass. +message Scheduling { + // nodeSelector lists labels that must be present on nodes that support this + // RuntimeClass. Pods using this RuntimeClass can only be scheduled to a + // node matched by this selector. The RuntimeClass nodeSelector is merged + // with a pod's existing nodeSelector. Any conflicts will cause the pod to + // be rejected in admission. + // +optional + map nodeSelector = 1; + + // tolerations are appended (excluding duplicates) to pods running with this + // RuntimeClass during admission, effectively unioning the set of nodes + // tolerated by the pod and the RuntimeClass. + // +optional + repeated k8s.io.api.core.v1.Toleration tolerations = 2; } diff --git a/staging/src/k8s.io/api/node/v1alpha1/types.go b/staging/src/k8s.io/api/node/v1alpha1/types.go index 2ce67c116fc..9807acb3236 100644 --- a/staging/src/k8s.io/api/node/v1alpha1/types.go +++ b/staging/src/k8s.io/api/node/v1alpha1/types.go @@ -17,6 +17,7 @@ limitations under the License. package v1alpha1 import ( + "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -58,6 +59,31 @@ type RuntimeClassSpec struct { // The RuntimeHandler must conform to the DNS Label (RFC 1123) requirements // and is immutable. RuntimeHandler string `json:"runtimeHandler" protobuf:"bytes,1,opt,name=runtimeHandler"` + + // Scheduling holds the scheduling constraints to ensure that pods running + // with this RuntimeClass are scheduled to nodes that support it. + // If scheduling is nil, this RuntimeClass is assumed to be supported by all + // nodes. + // +optional + Scheduling *Scheduling `json:"scheduling,omitempty" protobuf:"bytes,3,opt,name=scheduling"` +} + +// Scheduling specifies the scheduling constraints for nodes supporting a +// RuntimeClass. +type Scheduling struct { + // nodeSelector lists labels that must be present on nodes that support this + // RuntimeClass. Pods using this RuntimeClass can only be scheduled to a + // node matched by this selector. The RuntimeClass nodeSelector is merged + // with a pod's existing nodeSelector. Any conflicts will cause the pod to + // be rejected in admission. + // +optional + NodeSelector map[string]string `json:"nodeSelector,omitempty" protobuf:"bytes,1,opt,name=nodeSelector"` + + // tolerations are appended (excluding duplicates) to pods running with this + // RuntimeClass during admission, effectively unioning the set of nodes + // tolerated by the pod and the RuntimeClass. + // +optional + Tolerations []v1.Toleration `json:"tolerations,omitempty" protobuf:"bytes,2,rep,name=tolerations"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/staging/src/k8s.io/api/node/v1alpha1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/node/v1alpha1/types_swagger_doc_generated.go index a51fa525df3..0bcf32e16ad 100644 --- a/staging/src/k8s.io/api/node/v1alpha1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/node/v1alpha1/types_swagger_doc_generated.go @@ -50,10 +50,21 @@ func (RuntimeClassList) SwaggerDoc() map[string]string { var map_RuntimeClassSpec = map[string]string{ "": "RuntimeClassSpec is a specification of a RuntimeClass. It contains parameters that are required to describe the RuntimeClass to the Container Runtime Interface (CRI) implementation, as well as any other components that need to understand how the pod will be run. The RuntimeClassSpec is immutable.", "runtimeHandler": "RuntimeHandler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called \"runc\" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The RuntimeHandler must conform to the DNS Label (RFC 1123) requirements and is immutable.", + "scheduling": "Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.", } func (RuntimeClassSpec) SwaggerDoc() map[string]string { return map_RuntimeClassSpec } +var map_Scheduling = map[string]string{ + "": "Scheduling specifies the scheduling constraints for nodes supporting a RuntimeClass.", + "nodeSelector": "nodeSelector lists labels that must be present on nodes that support this RuntimeClass. Pods using this RuntimeClass can only be scheduled to a node matched by this selector. The RuntimeClass nodeSelector is merged with a pod's existing nodeSelector. Any conflicts will cause the pod to be rejected in admission.", + "tolerations": "tolerations are appended (excluding duplicates) to pods running with this RuntimeClass during admission, effectively unioning the set of nodes tolerated by the pod and the RuntimeClass.", +} + +func (Scheduling) SwaggerDoc() map[string]string { + return map_Scheduling +} + // AUTO-GENERATED FUNCTIONS END HERE diff --git a/staging/src/k8s.io/api/node/v1alpha1/zz_generated.deepcopy.go b/staging/src/k8s.io/api/node/v1alpha1/zz_generated.deepcopy.go index 91b8d80168d..79f9ff1a84e 100644 --- a/staging/src/k8s.io/api/node/v1alpha1/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/api/node/v1alpha1/zz_generated.deepcopy.go @@ -21,6 +21,7 @@ limitations under the License. package v1alpha1 import ( + v1 "k8s.io/api/core/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -29,7 +30,7 @@ func (in *RuntimeClass) DeepCopyInto(out *RuntimeClass) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec + in.Spec.DeepCopyInto(&out.Spec) return } @@ -87,6 +88,11 @@ func (in *RuntimeClassList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RuntimeClassSpec) DeepCopyInto(out *RuntimeClassSpec) { *out = *in + if in.Scheduling != nil { + in, out := &in.Scheduling, &out.Scheduling + *out = new(Scheduling) + (*in).DeepCopyInto(*out) + } return } @@ -99,3 +105,33 @@ func (in *RuntimeClassSpec) DeepCopy() *RuntimeClassSpec { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Scheduling) DeepCopyInto(out *Scheduling) { + *out = *in + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]v1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Scheduling. +func (in *Scheduling) DeepCopy() *Scheduling { + if in == nil { + return nil + } + out := new(Scheduling) + in.DeepCopyInto(out) + return out +} diff --git a/staging/src/k8s.io/api/node/v1beta1/BUILD b/staging/src/k8s.io/api/node/v1beta1/BUILD index 5ae9e598dac..db2cdbe037f 100644 --- a/staging/src/k8s.io/api/node/v1beta1/BUILD +++ b/staging/src/k8s.io/api/node/v1beta1/BUILD @@ -14,10 +14,12 @@ go_library( importpath = "k8s.io/api/node/v1beta1", visibility = ["//visibility:public"], 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/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/github.com/gogo/protobuf/proto:go_default_library", + "//vendor/github.com/gogo/protobuf/sortkeys:go_default_library", ], ) diff --git a/staging/src/k8s.io/api/node/v1beta1/generated.pb.go b/staging/src/k8s.io/api/node/v1beta1/generated.pb.go index 27251a8a892..a2cf593923f 100644 --- a/staging/src/k8s.io/api/node/v1beta1/generated.pb.go +++ b/staging/src/k8s.io/api/node/v1beta1/generated.pb.go @@ -26,6 +26,7 @@ limitations under the License. It has these top-level messages: RuntimeClass RuntimeClassList + Scheduling */ package v1beta1 @@ -33,6 +34,10 @@ import proto "github.com/gogo/protobuf/proto" import fmt "fmt" import math "math" +import k8s_io_api_core_v1 "k8s.io/api/core/v1" + +import github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + import strings "strings" import reflect "reflect" @@ -57,9 +62,14 @@ func (m *RuntimeClassList) Reset() { *m = RuntimeClassList{} func (*RuntimeClassList) ProtoMessage() {} func (*RuntimeClassList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{1} } +func (m *Scheduling) Reset() { *m = Scheduling{} } +func (*Scheduling) ProtoMessage() {} +func (*Scheduling) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{2} } + func init() { proto.RegisterType((*RuntimeClass)(nil), "k8s.io.api.node.v1beta1.RuntimeClass") proto.RegisterType((*RuntimeClassList)(nil), "k8s.io.api.node.v1beta1.RuntimeClassList") + proto.RegisterType((*Scheduling)(nil), "k8s.io.api.node.v1beta1.Scheduling") } func (m *RuntimeClass) Marshal() (dAtA []byte, err error) { size := m.Size() @@ -88,6 +98,16 @@ func (m *RuntimeClass) MarshalTo(dAtA []byte) (int, error) { i++ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Handler))) i += copy(dAtA[i:], m.Handler) + if m.Scheduling != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Scheduling.Size())) + n2, err := m.Scheduling.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } return i, nil } @@ -109,11 +129,11 @@ func (m *RuntimeClassList) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ListMeta.Size())) - n2, err := m.ListMeta.MarshalTo(dAtA[i:]) + n3, err := m.ListMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n2 + i += n3 if len(m.Items) > 0 { for _, msg := range m.Items { dAtA[i] = 0x12 @@ -129,6 +149,58 @@ func (m *RuntimeClassList) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *Scheduling) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Scheduling) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.NodeSelector) > 0 { + keysForNodeSelector := make([]string, 0, len(m.NodeSelector)) + for k := range m.NodeSelector { + keysForNodeSelector = append(keysForNodeSelector, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForNodeSelector) + for _, k := range keysForNodeSelector { + dAtA[i] = 0xa + i++ + v := m.NodeSelector[string(k)] + mapSize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) + i = encodeVarintGenerated(dAtA, i, uint64(mapSize)) + dAtA[i] = 0xa + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(k))) + i += copy(dAtA[i:], k) + dAtA[i] = 0x12 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(v))) + i += copy(dAtA[i:], v) + } + } + if len(m.Tolerations) > 0 { + for _, msg := range m.Tolerations { + dAtA[i] = 0x12 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { dAtA[offset] = uint8(v&0x7f | 0x80) @@ -145,6 +217,10 @@ func (m *RuntimeClass) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.Handler) n += 1 + l + sovGenerated(uint64(l)) + if m.Scheduling != nil { + l = m.Scheduling.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -162,6 +238,26 @@ func (m *RuntimeClassList) Size() (n int) { return n } +func (m *Scheduling) Size() (n int) { + var l int + _ = l + if len(m.NodeSelector) > 0 { + for k, v := range m.NodeSelector { + _ = k + _ = v + mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) + n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) + } + } + if len(m.Tolerations) > 0 { + for _, e := range m.Tolerations { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + func sovGenerated(x uint64) (n int) { for { n++ @@ -182,6 +278,7 @@ func (this *RuntimeClass) String() string { s := strings.Join([]string{`&RuntimeClass{`, `ObjectMeta:` + strings.Replace(strings.Replace(this.ObjectMeta.String(), "ObjectMeta", "k8s_io_apimachinery_pkg_apis_meta_v1.ObjectMeta", 1), `&`, ``, 1) + `,`, `Handler:` + fmt.Sprintf("%v", this.Handler) + `,`, + `Scheduling:` + strings.Replace(fmt.Sprintf("%v", this.Scheduling), "Scheduling", "Scheduling", 1) + `,`, `}`, }, "") return s @@ -197,6 +294,27 @@ func (this *RuntimeClassList) String() string { }, "") return s } +func (this *Scheduling) String() string { + if this == nil { + return "nil" + } + keysForNodeSelector := make([]string, 0, len(this.NodeSelector)) + for k := range this.NodeSelector { + keysForNodeSelector = append(keysForNodeSelector, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForNodeSelector) + mapStringForNodeSelector := "map[string]string{" + for _, k := range keysForNodeSelector { + mapStringForNodeSelector += fmt.Sprintf("%v: %v,", k, this.NodeSelector[k]) + } + mapStringForNodeSelector += "}" + s := strings.Join([]string{`&Scheduling{`, + `NodeSelector:` + mapStringForNodeSelector + `,`, + `Tolerations:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Tolerations), "Toleration", "k8s_io_api_core_v1.Toleration", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} func valueToStringGenerated(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -293,6 +411,39 @@ func (m *RuntimeClass) Unmarshal(dAtA []byte) error { } m.Handler = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Scheduling", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Scheduling == nil { + m.Scheduling = &Scheduling{} + } + if err := m.Scheduling.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -425,6 +576,205 @@ func (m *RuntimeClassList) Unmarshal(dAtA []byte) error { } return nil } +func (m *Scheduling) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Scheduling: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Scheduling: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeSelector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NodeSelector == nil { + m.NodeSelector = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.NodeSelector[mapkey] = mapvalue + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Tolerations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Tolerations = append(m.Tolerations, k8s_io_api_core_v1.Toleration{}) + if err := m.Tolerations[len(m.Tolerations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipGenerated(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 @@ -535,30 +885,39 @@ func init() { } var fileDescriptorGenerated = []byte{ - // 389 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xcd, 0x6a, 0xdb, 0x40, - 0x14, 0x85, 0x35, 0x2e, 0xc6, 0xae, 0xdc, 0x52, 0xa3, 0x4d, 0x8d, 0x17, 0x63, 0x63, 0x28, 0xb8, - 0x0b, 0xcf, 0xd4, 0xa6, 0x94, 0x2e, 0x8b, 0xba, 0x69, 0x4b, 0x4b, 0x41, 0xcb, 0x90, 0x45, 0x46, - 0xd2, 0x8d, 0x34, 0x91, 0xa5, 0x11, 0x9a, 0x91, 0x20, 0xbb, 0x3c, 0x42, 0xf6, 0x79, 0x95, 0x3c, - 0x80, 0x97, 0x5e, 0x7a, 0x65, 0x62, 0xe5, 0x45, 0x82, 0x7e, 0xfc, 0x43, 0x8c, 0x49, 0x76, 0xba, - 0xe7, 0x9e, 0x73, 0xee, 0x87, 0x18, 0xfd, 0x47, 0xf0, 0x5d, 0x12, 0x2e, 0x68, 0x90, 0xda, 0x90, - 0x44, 0xa0, 0x40, 0xd2, 0x0c, 0x22, 0x57, 0x24, 0xb4, 0x5e, 0xb0, 0x98, 0xd3, 0x48, 0xb8, 0x40, - 0xb3, 0xa9, 0x0d, 0x8a, 0x4d, 0xa9, 0x07, 0x11, 0x24, 0x4c, 0x81, 0x4b, 0xe2, 0x44, 0x28, 0x61, - 0x7c, 0xac, 0x8c, 0x84, 0xc5, 0x9c, 0x14, 0x46, 0x52, 0x1b, 0xfb, 0x13, 0x8f, 0x2b, 0x3f, 0xb5, - 0x89, 0x23, 0x42, 0xea, 0x09, 0x4f, 0xd0, 0xd2, 0x6f, 0xa7, 0x97, 0xe5, 0x54, 0x0e, 0xe5, 0x57, - 0xd5, 0xd3, 0xff, 0xba, 0x3f, 0x18, 0x32, 0xc7, 0xe7, 0x11, 0x24, 0xd7, 0x34, 0x0e, 0xbc, 0x42, - 0x90, 0x34, 0x04, 0xc5, 0x68, 0x76, 0x74, 0xbd, 0x4f, 0x4f, 0xa5, 0x92, 0x34, 0x52, 0x3c, 0x84, - 0xa3, 0xc0, 0xb7, 0x97, 0x02, 0xd2, 0xf1, 0x21, 0x64, 0xcf, 0x73, 0xa3, 0x3b, 0xa4, 0xbf, 0xb3, - 0x2a, 0xcb, 0xcf, 0x39, 0x93, 0xd2, 0xb8, 0xd0, 0xdb, 0x05, 0x94, 0xcb, 0x14, 0xeb, 0xa1, 0x21, - 0x1a, 0x77, 0x66, 0x5f, 0xc8, 0xfe, 0x57, 0xec, 0xba, 0x49, 0x1c, 0x78, 0x85, 0x20, 0x49, 0xe1, - 0x26, 0xd9, 0x94, 0xfc, 0xb7, 0xaf, 0xc0, 0x51, 0xff, 0x40, 0x31, 0xd3, 0x58, 0xac, 0x07, 0x5a, - 0xbe, 0x1e, 0xe8, 0x7b, 0xcd, 0xda, 0xb5, 0x1a, 0x9f, 0xf5, 0x96, 0xcf, 0x22, 0x77, 0x0e, 0x49, - 0xaf, 0x31, 0x44, 0xe3, 0xb7, 0xe6, 0x87, 0xda, 0xde, 0xfa, 0x55, 0xc9, 0xd6, 0x76, 0x3f, 0xba, - 0x47, 0x7a, 0xf7, 0x90, 0xee, 0x2f, 0x97, 0xca, 0x38, 0x3f, 0x22, 0x24, 0xaf, 0x23, 0x2c, 0xd2, - 0x25, 0x5f, 0xb7, 0x3e, 0xd8, 0xde, 0x2a, 0x07, 0x74, 0x7f, 0xf4, 0x26, 0x57, 0x10, 0xca, 0x5e, - 0x63, 0xf8, 0x66, 0xdc, 0x99, 0x7d, 0x22, 0x27, 0xde, 0x01, 0x39, 0xe4, 0x32, 0xdf, 0xd7, 0x8d, - 0xcd, 0xdf, 0x45, 0xd6, 0xaa, 0x2a, 0xcc, 0xc9, 0x62, 0x83, 0xb5, 0xe5, 0x06, 0x6b, 0xab, 0x0d, - 0xd6, 0x6e, 0x72, 0x8c, 0x16, 0x39, 0x46, 0xcb, 0x1c, 0xa3, 0x55, 0x8e, 0xd1, 0x43, 0x8e, 0xd1, - 0xed, 0x23, 0xd6, 0xce, 0x5a, 0x75, 0xe3, 0x53, 0x00, 0x00, 0x00, 0xff, 0xff, 0x93, 0x68, 0xe5, - 0x0d, 0xb5, 0x02, 0x00, 0x00, + // 534 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xcf, 0x8e, 0xd2, 0x40, + 0x18, 0x67, 0x20, 0x84, 0xdd, 0x01, 0x15, 0xeb, 0x26, 0x12, 0x0e, 0x5d, 0x82, 0x31, 0xc1, 0xc3, + 0xce, 0xc8, 0x46, 0xcd, 0xc6, 0x8b, 0xa6, 0xc6, 0x44, 0x8d, 0x7f, 0x92, 0xa2, 0x17, 0xe3, 0xc1, + 0xa1, 0xfd, 0x2c, 0x95, 0xb6, 0x43, 0x3a, 0x53, 0x12, 0x6e, 0x3e, 0x82, 0x17, 0xdf, 0xc6, 0x07, + 0xe0, 0xb8, 0xc7, 0x3d, 0x6d, 0xa4, 0xbe, 0x80, 0x8f, 0x60, 0xa6, 0x2d, 0x74, 0x5c, 0x24, 0xbb, + 0xb7, 0x7e, 0xdf, 0xfc, 0xfe, 0x7c, 0xbf, 0x6f, 0xa6, 0xf8, 0xe9, 0xf4, 0x44, 0x10, 0x9f, 0xd3, + 0x69, 0x32, 0x86, 0x38, 0x02, 0x09, 0x82, 0xce, 0x21, 0x72, 0x79, 0x4c, 0x8b, 0x03, 0x36, 0xf3, + 0x69, 0xc4, 0x5d, 0xa0, 0xf3, 0xe1, 0x18, 0x24, 0x1b, 0x52, 0x0f, 0x22, 0x88, 0x99, 0x04, 0x97, + 0xcc, 0x62, 0x2e, 0xb9, 0x71, 0x3b, 0x07, 0x12, 0x36, 0xf3, 0x89, 0x02, 0x92, 0x02, 0xd8, 0x3d, + 0xf2, 0x7c, 0x39, 0x49, 0xc6, 0xc4, 0xe1, 0x21, 0xf5, 0xb8, 0xc7, 0x69, 0x86, 0x1f, 0x27, 0x5f, + 0xb2, 0x2a, 0x2b, 0xb2, 0xaf, 0x5c, 0xa7, 0xdb, 0xd7, 0x0c, 0x1d, 0x1e, 0x2b, 0xc3, 0x8b, 0x5e, + 0xdd, 0x07, 0x25, 0x26, 0x64, 0xce, 0xc4, 0x8f, 0x20, 0x5e, 0xd0, 0xd9, 0xd4, 0x53, 0x0d, 0x41, + 0x43, 0x90, 0xec, 0x7f, 0x2c, 0xba, 0x8b, 0x15, 0x27, 0x91, 0xf4, 0x43, 0xd8, 0x22, 0x3c, 0xba, + 0x8c, 0x20, 0x9c, 0x09, 0x84, 0xec, 0x22, 0xaf, 0xff, 0x07, 0xe1, 0x96, 0x9d, 0x43, 0x9e, 0x05, + 0x4c, 0x08, 0xe3, 0x33, 0xde, 0x53, 0x43, 0xb9, 0x4c, 0xb2, 0x0e, 0xea, 0xa1, 0x41, 0xf3, 0xf8, + 0x3e, 0x29, 0xd7, 0xb5, 0xd1, 0x26, 0xb3, 0xa9, 0xa7, 0x1a, 0x82, 0x28, 0x34, 0x99, 0x0f, 0xc9, + 0xbb, 0xf1, 0x57, 0x70, 0xe4, 0x1b, 0x90, 0xcc, 0x32, 0x96, 0xe7, 0x87, 0x95, 0xf4, 0xfc, 0x10, + 0x97, 0x3d, 0x7b, 0xa3, 0x6a, 0xdc, 0xc3, 0x8d, 0x09, 0x8b, 0xdc, 0x00, 0xe2, 0x4e, 0xb5, 0x87, + 0x06, 0xfb, 0xd6, 0x8d, 0x02, 0xde, 0x78, 0x91, 0xb7, 0xed, 0xf5, 0xb9, 0x31, 0xc2, 0x58, 0xcd, + 0xed, 0x26, 0x81, 0x1f, 0x79, 0x9d, 0x5a, 0x36, 0xce, 0x1d, 0xb2, 0xe3, 0xf6, 0xc8, 0x68, 0x03, + 0xb5, 0xae, 0x2b, 0xf7, 0xb2, 0xb6, 0x35, 0x99, 0xfe, 0x4f, 0x84, 0xdb, 0x7a, 0xe4, 0xd7, 0xbe, + 0x90, 0xc6, 0xa7, 0xad, 0xd8, 0xe4, 0x6a, 0xb1, 0x15, 0x3b, 0x0b, 0xdd, 0x2e, 0x52, 0xec, 0xad, + 0x3b, 0x5a, 0xe4, 0x57, 0xb8, 0xee, 0x4b, 0x08, 0x45, 0xa7, 0xda, 0xab, 0x0d, 0x9a, 0xc7, 0x77, + 0x77, 0x46, 0xd0, 0xe7, 0xb2, 0xae, 0x15, 0x8a, 0xf5, 0x97, 0x8a, 0x6b, 0xe7, 0x12, 0xfd, 0x1f, + 0x55, 0xac, 0x25, 0x33, 0x38, 0x6e, 0x29, 0x85, 0x11, 0x04, 0xe0, 0x48, 0x1e, 0x77, 0x50, 0xe6, + 0xf0, 0xf0, 0x0a, 0x4b, 0x22, 0x6f, 0x35, 0xde, 0xf3, 0x48, 0xc6, 0x0b, 0xeb, 0xa0, 0x70, 0x6c, + 0xe9, 0x47, 0xf6, 0x3f, 0x06, 0xc6, 0x07, 0xdc, 0x94, 0x3c, 0x50, 0x8f, 0xc8, 0xe7, 0xd1, 0x3a, + 0x91, 0xa9, 0xfb, 0xa9, 0x5f, 0x41, 0xad, 0xe6, 0xfd, 0x06, 0x66, 0xdd, 0x2a, 0x84, 0x9b, 0x65, + 0x4f, 0xd8, 0xba, 0x4e, 0xf7, 0x09, 0xbe, 0xb9, 0x35, 0x8f, 0xd1, 0xc6, 0xb5, 0x29, 0x2c, 0xb2, + 0x0b, 0xd9, 0xb7, 0xd5, 0xa7, 0x71, 0x80, 0xeb, 0x73, 0x16, 0x24, 0x90, 0x3f, 0x1d, 0x3b, 0x2f, + 0x1e, 0x57, 0x4f, 0x90, 0x75, 0xb4, 0x5c, 0x99, 0x95, 0xd3, 0x95, 0x59, 0x39, 0x5b, 0x99, 0x95, + 0x6f, 0xa9, 0x89, 0x96, 0xa9, 0x89, 0x4e, 0x53, 0x13, 0x9d, 0xa5, 0x26, 0xfa, 0x95, 0x9a, 0xe8, + 0xfb, 0x6f, 0xb3, 0xf2, 0xb1, 0x51, 0xec, 0xe1, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x36, 0x6a, + 0x5d, 0x42, 0x46, 0x04, 0x00, 0x00, } diff --git a/staging/src/k8s.io/api/node/v1beta1/generated.proto b/staging/src/k8s.io/api/node/v1beta1/generated.proto index 9082fbd3344..d1124c93be9 100644 --- a/staging/src/k8s.io/api/node/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/node/v1beta1/generated.proto @@ -21,6 +21,7 @@ syntax = 'proto2'; package k8s.io.api.node.v1beta1; +import "k8s.io/api/core/v1/generated.proto"; import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; @@ -51,6 +52,13 @@ message RuntimeClass { // The Handler must conform to the DNS Label (RFC 1123) requirements, and is // immutable. optional string handler = 2; + + // Scheduling holds the scheduling constraints to ensure that pods running + // with this RuntimeClass are scheduled to nodes that support it. + // If scheduling is nil, this RuntimeClass is assumed to be supported by all + // nodes. + // +optional + optional Scheduling scheduling = 3; } // RuntimeClassList is a list of RuntimeClass objects. @@ -64,3 +72,21 @@ message RuntimeClassList { repeated RuntimeClass items = 2; } +// Scheduling specifies the scheduling constraints for nodes supporting a +// RuntimeClass. +message Scheduling { + // nodeSelector lists labels that must be present on nodes that support this + // RuntimeClass. Pods using this RuntimeClass can only be scheduled to a + // node matched by this selector. The RuntimeClass nodeSelector is merged + // with a pod's existing nodeSelector. Any conflicts will cause the pod to + // be rejected in admission. + // +optional + map nodeSelector = 1; + + // tolerations are appended (excluding duplicates) to pods running with this + // RuntimeClass during admission, effectively unioning the set of nodes + // tolerated by the pod and the RuntimeClass. + // +optional + repeated k8s.io.api.core.v1.Toleration tolerations = 2; +} + diff --git a/staging/src/k8s.io/api/node/v1beta1/types.go b/staging/src/k8s.io/api/node/v1beta1/types.go index 993c6e50660..e437580d35a 100644 --- a/staging/src/k8s.io/api/node/v1beta1/types.go +++ b/staging/src/k8s.io/api/node/v1beta1/types.go @@ -17,6 +17,7 @@ limitations under the License. package v1beta1 import ( + "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -48,6 +49,31 @@ type RuntimeClass struct { // The Handler must conform to the DNS Label (RFC 1123) requirements, and is // immutable. Handler string `json:"handler" protobuf:"bytes,2,opt,name=handler"` + + // Scheduling holds the scheduling constraints to ensure that pods running + // with this RuntimeClass are scheduled to nodes that support it. + // If scheduling is nil, this RuntimeClass is assumed to be supported by all + // nodes. + // +optional + Scheduling *Scheduling `json:"scheduling,omitempty" protobuf:"bytes,3,opt,name=scheduling"` +} + +// Scheduling specifies the scheduling constraints for nodes supporting a +// RuntimeClass. +type Scheduling struct { + // nodeSelector lists labels that must be present on nodes that support this + // RuntimeClass. Pods using this RuntimeClass can only be scheduled to a + // node matched by this selector. The RuntimeClass nodeSelector is merged + // with a pod's existing nodeSelector. Any conflicts will cause the pod to + // be rejected in admission. + // +optional + NodeSelector map[string]string `json:"nodeSelector,omitempty" protobuf:"bytes,1,opt,name=nodeSelector"` + + // tolerations are appended (excluding duplicates) to pods running with this + // RuntimeClass during admission, effectively unioning the set of nodes + // tolerated by the pod and the RuntimeClass. + // +optional + Tolerations []v1.Toleration `json:"tolerations,omitempty" protobuf:"bytes,2,rep,name=tolerations"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/staging/src/k8s.io/api/node/v1beta1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/node/v1beta1/types_swagger_doc_generated.go index 8bfa304e78d..ac6e95528db 100644 --- a/staging/src/k8s.io/api/node/v1beta1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/node/v1beta1/types_swagger_doc_generated.go @@ -28,9 +28,10 @@ package v1beta1 // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_RuntimeClass = map[string]string{ - "": "RuntimeClass defines a class of container runtime supported in the cluster. The RuntimeClass is used to determine which container runtime is used to run all containers in a pod. RuntimeClasses are (currently) manually defined by a user or cluster provisioner, and referenced in the PodSpec. The Kubelet is responsible for resolving the RuntimeClassName reference before running the pod. For more details, see https://git.k8s.io/enhancements/keps/sig-node/runtime-class.md", - "metadata": "More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata", - "handler": "Handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called \"runc\" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The Handler must conform to the DNS Label (RFC 1123) requirements, and is immutable.", + "": "RuntimeClass defines a class of container runtime supported in the cluster. The RuntimeClass is used to determine which container runtime is used to run all containers in a pod. RuntimeClasses are (currently) manually defined by a user or cluster provisioner, and referenced in the PodSpec. The Kubelet is responsible for resolving the RuntimeClassName reference before running the pod. For more details, see https://git.k8s.io/enhancements/keps/sig-node/runtime-class.md", + "metadata": "More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata", + "handler": "Handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called \"runc\" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The Handler must conform to the DNS Label (RFC 1123) requirements, and is immutable.", + "scheduling": "Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.", } func (RuntimeClass) SwaggerDoc() map[string]string { @@ -47,4 +48,14 @@ func (RuntimeClassList) SwaggerDoc() map[string]string { return map_RuntimeClassList } +var map_Scheduling = map[string]string{ + "": "Scheduling specifies the scheduling constraints for nodes supporting a RuntimeClass.", + "nodeSelector": "nodeSelector lists labels that must be present on nodes that support this RuntimeClass. Pods using this RuntimeClass can only be scheduled to a node matched by this selector. The RuntimeClass nodeSelector is merged with a pod's existing nodeSelector. Any conflicts will cause the pod to be rejected in admission.", + "tolerations": "tolerations are appended (excluding duplicates) to pods running with this RuntimeClass during admission, effectively unioning the set of nodes tolerated by the pod and the RuntimeClass.", +} + +func (Scheduling) SwaggerDoc() map[string]string { + return map_Scheduling +} + // AUTO-GENERATED FUNCTIONS END HERE diff --git a/staging/src/k8s.io/api/node/v1beta1/zz_generated.deepcopy.go b/staging/src/k8s.io/api/node/v1beta1/zz_generated.deepcopy.go index f211e849940..289110ed0b8 100644 --- a/staging/src/k8s.io/api/node/v1beta1/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/api/node/v1beta1/zz_generated.deepcopy.go @@ -21,6 +21,7 @@ limitations under the License. package v1beta1 import ( + v1 "k8s.io/api/core/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -29,6 +30,11 @@ func (in *RuntimeClass) DeepCopyInto(out *RuntimeClass) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Scheduling != nil { + in, out := &in.Scheduling, &out.Scheduling + *out = new(Scheduling) + (*in).DeepCopyInto(*out) + } return } @@ -82,3 +88,33 @@ func (in *RuntimeClassList) DeepCopyObject() runtime.Object { } return nil } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Scheduling) DeepCopyInto(out *Scheduling) { + *out = *in + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]v1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Scheduling. +func (in *Scheduling) DeepCopy() *Scheduling { + if in == nil { + return nil + } + out := new(Scheduling) + in.DeepCopyInto(out) + return out +} diff --git a/staging/src/k8s.io/api/roundtrip_test.go b/staging/src/k8s.io/api/roundtrip_test.go index a36721f10a8..910732174f0 100644 --- a/staging/src/k8s.io/api/roundtrip_test.go +++ b/staging/src/k8s.io/api/roundtrip_test.go @@ -40,6 +40,8 @@ import ( extensionsv1beta1 "k8s.io/api/extensions/v1beta1" imagepolicyv1alpha1 "k8s.io/api/imagepolicy/v1alpha1" networkingv1 "k8s.io/api/networking/v1" + nodev1alpha1 "k8s.io/api/node/v1alpha1" + nodev1beta1 "k8s.io/api/node/v1beta1" policyv1beta1 "k8s.io/api/policy/v1beta1" rbacv1 "k8s.io/api/rbac/v1" rbacv1alpha1 "k8s.io/api/rbac/v1alpha1" @@ -83,6 +85,8 @@ var groups = []runtime.SchemeBuilder{ extensionsv1beta1.SchemeBuilder, imagepolicyv1alpha1.SchemeBuilder, networkingv1.SchemeBuilder, + nodev1alpha1.SchemeBuilder, + nodev1beta1.SchemeBuilder, policyv1beta1.SchemeBuilder, rbacv1alpha1.SchemeBuilder, rbacv1beta1.SchemeBuilder,