DRA: remove immediate allocation
As agreed in https://github.com/kubernetes/enhancements/pull/4709, immediate allocation is one of those features which can be removed because it makes no sense for structured parameters and the justification for classic DRA is weak.
This commit is contained in:
@@ -17,24 +17,10 @@ limitations under the License.
|
||||
package fuzzer
|
||||
|
||||
import (
|
||||
fuzz "github.com/google/gofuzz"
|
||||
|
||||
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/kubernetes/pkg/apis/resource"
|
||||
)
|
||||
|
||||
// Funcs contains the fuzzer functions for the resource group.
|
||||
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
|
||||
return []interface{}{
|
||||
func(obj *resource.ResourceClaimSpec, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(obj) // fuzz self without calling this function again
|
||||
|
||||
// Custom fuzzing for allocation mode: pick one valid mode randomly.
|
||||
modes := []resource.AllocationMode{
|
||||
resource.AllocationModeImmediate,
|
||||
resource.AllocationModeWaitForFirstConsumer,
|
||||
}
|
||||
obj.AllocationMode = modes[c.Rand.Intn(len(modes))]
|
||||
},
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -62,34 +62,8 @@ type ResourceClaimSpec struct {
|
||||
// The object must be in the same namespace as the ResourceClaim.
|
||||
// +optional
|
||||
ParametersRef *ResourceClaimParametersReference
|
||||
|
||||
// Allocation can start immediately or when a Pod wants to use the
|
||||
// resource. "WaitForFirstConsumer" is the default.
|
||||
// +optional
|
||||
AllocationMode AllocationMode
|
||||
}
|
||||
|
||||
// AllocationMode describes whether a ResourceClaim gets allocated immediately
|
||||
// when it gets created (AllocationModeImmediate) or whether allocation is
|
||||
// delayed until it is needed for a Pod
|
||||
// (AllocationModeWaitForFirstConsumer). Other modes might get added in the
|
||||
// future.
|
||||
type AllocationMode string
|
||||
|
||||
const (
|
||||
// When a ResourceClaim has AllocationModeWaitForFirstConsumer, allocation is
|
||||
// delayed until a Pod gets scheduled that needs the ResourceClaim. The
|
||||
// scheduler will consider all resource requirements of that Pod and
|
||||
// trigger allocation for a node that fits the Pod.
|
||||
AllocationModeWaitForFirstConsumer AllocationMode = "WaitForFirstConsumer"
|
||||
|
||||
// When a ResourceClaim has AllocationModeImmediate, allocation starts
|
||||
// as soon as the ResourceClaim gets created. This is done without
|
||||
// considering the needs of Pods that will use the ResourceClaim
|
||||
// because those Pods are not known yet.
|
||||
AllocationModeImmediate AllocationMode = "Immediate"
|
||||
)
|
||||
|
||||
// ResourceClaimStatus tracks whether the resource has been allocated and what
|
||||
// the resulting attributes are.
|
||||
type ResourceClaimStatus struct {
|
||||
|
||||
@@ -17,16 +17,9 @@ limitations under the License.
|
||||
package v1alpha3
|
||||
|
||||
import (
|
||||
"k8s.io/api/resource/v1alpha3"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
||||
return RegisterDefaults(scheme)
|
||||
}
|
||||
|
||||
func SetDefaults_ResourceClaimSpec(obj *v1alpha3.ResourceClaimSpec) {
|
||||
if obj.AllocationMode == "" {
|
||||
obj.AllocationMode = v1alpha3.AllocationModeWaitForFirstConsumer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha3_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
v1alpha3 "k8s.io/api/resource/v1alpha3"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
// ensure types are installed
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
_ "k8s.io/kubernetes/pkg/apis/resource/install"
|
||||
)
|
||||
|
||||
func TestSetDefaultAllocationMode(t *testing.T) {
|
||||
claim := &v1alpha3.ResourceClaim{}
|
||||
|
||||
// field should be defaulted
|
||||
defaultMode := v1alpha3.AllocationModeWaitForFirstConsumer
|
||||
output := roundTrip(t, runtime.Object(claim)).(*v1alpha3.ResourceClaim)
|
||||
outMode := output.Spec.AllocationMode
|
||||
if outMode != defaultMode {
|
||||
t.Errorf("Expected AllocationMode to be defaulted to: %+v, got: %+v", defaultMode, outMode)
|
||||
}
|
||||
|
||||
// field should not change
|
||||
nonDefaultMode := v1alpha3.AllocationModeImmediate
|
||||
claim = &v1alpha3.ResourceClaim{
|
||||
Spec: v1alpha3.ResourceClaimSpec{
|
||||
AllocationMode: nonDefaultMode,
|
||||
},
|
||||
}
|
||||
output = roundTrip(t, runtime.Object(claim)).(*v1alpha3.ResourceClaim)
|
||||
outMode = output.Spec.AllocationMode
|
||||
if outMode != v1alpha3.AllocationModeImmediate {
|
||||
t.Errorf("Expected AllocationMode to remain %+v, got: %+v", nonDefaultMode, outMode)
|
||||
}
|
||||
}
|
||||
|
||||
func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
|
||||
codec := legacyscheme.Codecs.LegacyCodec(v1alpha3.SchemeGroupVersion)
|
||||
data, err := runtime.Encode(codec, obj)
|
||||
if err != nil {
|
||||
t.Errorf("%v\n %#v", err, obj)
|
||||
return nil
|
||||
}
|
||||
obj2, err := runtime.Decode(codec, data)
|
||||
if err != nil {
|
||||
t.Errorf("%v\nData: %s\nSource: %#v", err, string(data), obj)
|
||||
return nil
|
||||
}
|
||||
obj3 := reflect.New(reflect.TypeOf(obj).Elem()).Interface().(runtime.Object)
|
||||
err = legacyscheme.Scheme.Convert(obj2, obj3, nil)
|
||||
if err != nil {
|
||||
t.Errorf("%v\nSource: %#v", err, obj2)
|
||||
return nil
|
||||
}
|
||||
return obj3
|
||||
}
|
||||
@@ -1159,7 +1159,6 @@ func Convert_resource_ResourceClaimSchedulingStatus_To_v1alpha3_ResourceClaimSch
|
||||
func autoConvert_v1alpha3_ResourceClaimSpec_To_resource_ResourceClaimSpec(in *v1alpha3.ResourceClaimSpec, out *resource.ResourceClaimSpec, s conversion.Scope) error {
|
||||
out.ResourceClassName = in.ResourceClassName
|
||||
out.ParametersRef = (*resource.ResourceClaimParametersReference)(unsafe.Pointer(in.ParametersRef))
|
||||
out.AllocationMode = resource.AllocationMode(in.AllocationMode)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1171,7 +1170,6 @@ func Convert_v1alpha3_ResourceClaimSpec_To_resource_ResourceClaimSpec(in *v1alph
|
||||
func autoConvert_resource_ResourceClaimSpec_To_v1alpha3_ResourceClaimSpec(in *resource.ResourceClaimSpec, out *v1alpha3.ResourceClaimSpec, s conversion.Scope) error {
|
||||
out.ResourceClassName = in.ResourceClassName
|
||||
out.ParametersRef = (*v1alpha3.ResourceClaimParametersReference)(unsafe.Pointer(in.ParametersRef))
|
||||
out.AllocationMode = v1alpha3.AllocationMode(in.AllocationMode)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
29
pkg/apis/resource/v1alpha3/zz_generated.defaults.go
generated
29
pkg/apis/resource/v1alpha3/zz_generated.defaults.go
generated
@@ -22,7 +22,6 @@ limitations under the License.
|
||||
package v1alpha3
|
||||
|
||||
import (
|
||||
v1alpha3 "k8s.io/api/resource/v1alpha3"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
@@ -30,33 +29,5 @@ import (
|
||||
// Public to allow building arbitrary schemes.
|
||||
// All generated defaulters are covering - they call all nested defaulters.
|
||||
func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
scheme.AddTypeDefaultingFunc(&v1alpha3.ResourceClaim{}, func(obj interface{}) { SetObjectDefaults_ResourceClaim(obj.(*v1alpha3.ResourceClaim)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1alpha3.ResourceClaimList{}, func(obj interface{}) { SetObjectDefaults_ResourceClaimList(obj.(*v1alpha3.ResourceClaimList)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1alpha3.ResourceClaimTemplate{}, func(obj interface{}) { SetObjectDefaults_ResourceClaimTemplate(obj.(*v1alpha3.ResourceClaimTemplate)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1alpha3.ResourceClaimTemplateList{}, func(obj interface{}) {
|
||||
SetObjectDefaults_ResourceClaimTemplateList(obj.(*v1alpha3.ResourceClaimTemplateList))
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetObjectDefaults_ResourceClaim(in *v1alpha3.ResourceClaim) {
|
||||
SetDefaults_ResourceClaimSpec(&in.Spec)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_ResourceClaimList(in *v1alpha3.ResourceClaimList) {
|
||||
for i := range in.Items {
|
||||
a := &in.Items[i]
|
||||
SetObjectDefaults_ResourceClaim(a)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_ResourceClaimTemplate(in *v1alpha3.ResourceClaimTemplate) {
|
||||
SetDefaults_ResourceClaimSpec(&in.Spec.Spec)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_ResourceClaimTemplateList(in *v1alpha3.ResourceClaimTemplateList) {
|
||||
for i := range in.Items {
|
||||
a := &in.Items[i]
|
||||
SetObjectDefaults_ResourceClaimTemplate(a)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,14 +46,9 @@ func validateResourceClaimSpec(spec *resource.ResourceClaimSpec, fldPath *field.
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceClassName"), spec.ResourceClassName, msg))
|
||||
}
|
||||
allErrs = append(allErrs, validateResourceClaimParametersRef(spec.ParametersRef, fldPath.Child("parametersRef"))...)
|
||||
if !supportedAllocationModes.Has(string(spec.AllocationMode)) {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("allocationMode"), spec.AllocationMode, supportedAllocationModes.List()))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
var supportedAllocationModes = sets.NewString(string(resource.AllocationModeImmediate), string(resource.AllocationModeWaitForFirstConsumer))
|
||||
|
||||
// It would have been nice to use Go generics to reuse the same validation
|
||||
// function for Kind and Name in both types, but generics cannot be used to
|
||||
// access common fields in structs.
|
||||
|
||||
@@ -42,14 +42,11 @@ func testClaim(name, namespace string, spec resource.ResourceClaimSpec) *resourc
|
||||
}
|
||||
|
||||
func TestValidateClaim(t *testing.T) {
|
||||
validMode := resource.AllocationModeImmediate
|
||||
invalidMode := resource.AllocationMode("invalid")
|
||||
goodName := "foo"
|
||||
badName := "!@#$%^"
|
||||
goodNS := "ns"
|
||||
goodClaimSpec := resource.ResourceClaimSpec{
|
||||
ResourceClassName: goodName,
|
||||
AllocationMode: validMode,
|
||||
}
|
||||
now := metav1.Now()
|
||||
badValue := "spaces not allowed"
|
||||
@@ -200,14 +197,6 @@ func TestValidateClaim(t *testing.T) {
|
||||
return claim
|
||||
}(),
|
||||
},
|
||||
"bad-mode": {
|
||||
wantFailures: field.ErrorList{field.NotSupported(field.NewPath("spec", "allocationMode"), invalidMode, supportedAllocationModes.List())},
|
||||
claim: func() *resource.ResourceClaim {
|
||||
claim := testClaim(goodName, goodNS, goodClaimSpec)
|
||||
claim.Spec.AllocationMode = invalidMode
|
||||
return claim
|
||||
}(),
|
||||
},
|
||||
"good-parameters": {
|
||||
claim: func() *resource.ResourceClaim {
|
||||
claim := testClaim(goodName, goodNS, goodClaimSpec)
|
||||
@@ -279,7 +268,6 @@ func TestValidateClaimUpdate(t *testing.T) {
|
||||
}
|
||||
validClaim := testClaim("foo", "ns", resource.ResourceClaimSpec{
|
||||
ResourceClassName: name,
|
||||
AllocationMode: resource.AllocationModeImmediate,
|
||||
ParametersRef: parameters,
|
||||
})
|
||||
|
||||
@@ -316,18 +304,6 @@ func TestValidateClaimUpdate(t *testing.T) {
|
||||
return claim
|
||||
},
|
||||
},
|
||||
"invalid-update-mode": {
|
||||
wantFailures: field.ErrorList{field.Invalid(field.NewPath("spec"), func() resource.ResourceClaimSpec {
|
||||
spec := validClaim.Spec.DeepCopy()
|
||||
spec.AllocationMode = resource.AllocationModeWaitForFirstConsumer
|
||||
return *spec
|
||||
}(), "field is immutable")},
|
||||
oldClaim: validClaim,
|
||||
update: func(claim *resource.ResourceClaim) *resource.ResourceClaim {
|
||||
claim.Spec.AllocationMode = resource.AllocationModeWaitForFirstConsumer
|
||||
return claim
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, scenario := range scenarios {
|
||||
@@ -343,7 +319,6 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
|
||||
invalidName := "!@#$%^"
|
||||
validClaim := testClaim("foo", "ns", resource.ResourceClaimSpec{
|
||||
ResourceClassName: "valid",
|
||||
AllocationMode: resource.AllocationModeImmediate,
|
||||
})
|
||||
|
||||
validAllocatedClaim := validClaim.DeepCopy()
|
||||
|
||||
@@ -40,14 +40,11 @@ func testClaimTemplate(name, namespace string, spec resource.ResourceClaimSpec)
|
||||
}
|
||||
|
||||
func TestValidateClaimTemplate(t *testing.T) {
|
||||
validMode := resource.AllocationModeImmediate
|
||||
invalidMode := resource.AllocationMode("invalid")
|
||||
goodName := "foo"
|
||||
badName := "!@#$%^"
|
||||
goodNS := "ns"
|
||||
goodClaimSpec := resource.ResourceClaimSpec{
|
||||
ResourceClassName: goodName,
|
||||
AllocationMode: validMode,
|
||||
}
|
||||
now := metav1.Now()
|
||||
badValue := "spaces not allowed"
|
||||
@@ -198,14 +195,6 @@ func TestValidateClaimTemplate(t *testing.T) {
|
||||
return template
|
||||
}(),
|
||||
},
|
||||
"bad-mode": {
|
||||
wantFailures: field.ErrorList{field.NotSupported(field.NewPath("spec", "spec", "allocationMode"), invalidMode, supportedAllocationModes.List())},
|
||||
template: func() *resource.ResourceClaimTemplate {
|
||||
template := testClaimTemplate(goodName, goodNS, goodClaimSpec)
|
||||
template.Spec.Spec.AllocationMode = invalidMode
|
||||
return template
|
||||
}(),
|
||||
},
|
||||
"good-parameters": {
|
||||
template: func() *resource.ResourceClaimTemplate {
|
||||
template := testClaimTemplate(goodName, goodNS, goodClaimSpec)
|
||||
@@ -277,7 +266,6 @@ func TestValidateClaimTemplateUpdate(t *testing.T) {
|
||||
}
|
||||
validClaimTemplate := testClaimTemplate("foo", "ns", resource.ResourceClaimSpec{
|
||||
ResourceClassName: name,
|
||||
AllocationMode: resource.AllocationModeImmediate,
|
||||
ParametersRef: parameters,
|
||||
})
|
||||
|
||||
@@ -314,18 +302,6 @@ func TestValidateClaimTemplateUpdate(t *testing.T) {
|
||||
return template
|
||||
},
|
||||
},
|
||||
"invalid-update-mode": {
|
||||
wantFailures: field.ErrorList{field.Invalid(field.NewPath("spec"), func() resource.ResourceClaimTemplateSpec {
|
||||
spec := validClaimTemplate.Spec.DeepCopy()
|
||||
spec.Spec.AllocationMode = resource.AllocationModeWaitForFirstConsumer
|
||||
return *spec
|
||||
}(), "field is immutable")},
|
||||
oldClaimTemplate: validClaimTemplate,
|
||||
update: func(template *resource.ResourceClaimTemplate) *resource.ResourceClaimTemplate {
|
||||
template.Spec.Spec.AllocationMode = resource.AllocationModeWaitForFirstConsumer
|
||||
return template
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, scenario := range scenarios {
|
||||
|
||||
Reference in New Issue
Block a user