mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-18 04:54:54 +00:00
KEP-5491: change ResourceSliceMaxDevicesWithTaintsOrConsumesCounters to ResourceSliceMaxDevicesWithAdvancedFeatures and add testcases with max devices with list attributes
This commit is contained in:
@@ -254,7 +254,14 @@ type ResourcePool struct {
|
||||
|
||||
const ResourceSliceMaxSharedCapacity = 128
|
||||
const ResourceSliceMaxDevices = 128
|
||||
const ResourceSliceMaxDevicesWithTaintsOrConsumesCounters = 64
|
||||
|
||||
// ResourceSliceMaxDevicesWithAdvancedFeatures defines the maximum number of devices in a ResourceSlice
|
||||
// if any of those devices uses advanced features:
|
||||
// - device taints (DRADeviceTaints feature gate)
|
||||
// - consuming counters (DRAPartitionableDevices feature gate)
|
||||
// - list attributes (DRAListTypeAttributes feature gate)
|
||||
const ResourceSliceMaxDevicesWithAdvancedFeatures = 64
|
||||
|
||||
const PoolNameMaxLength = validation.DNS1123SubdomainMaxLength // Same as for a single node name.
|
||||
const BindingConditionsMaxSize = 4
|
||||
const BindingFailureConditionsMaxSize = 4
|
||||
|
||||
@@ -711,8 +711,8 @@ func validateResourceSliceSpec(spec, oldSpec *resource.ResourceSliceSpec, fldPat
|
||||
}
|
||||
|
||||
maxDevices := resource.ResourceSliceMaxDevices
|
||||
if haveDeviceTaints(spec) || haveConsumesCounters(spec) {
|
||||
maxDevices = resource.ResourceSliceMaxDevicesWithTaintsOrConsumesCounters
|
||||
if haveDeviceTaints(spec) || haveConsumesCounters(spec) || haveListAttributes(spec) {
|
||||
maxDevices = resource.ResourceSliceMaxDevicesWithAdvancedFeatures
|
||||
}
|
||||
allErrs = append(allErrs, validateSet(spec.Devices, maxDevices,
|
||||
func(device resource.Device, fldPath *field.Path) field.ErrorList {
|
||||
@@ -732,6 +732,24 @@ func validateResourceSliceSpec(spec, oldSpec *resource.ResourceSliceSpec, fldPat
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func haveListAttributes(spec *resource.ResourceSliceSpec) bool {
|
||||
if spec == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, device := range spec.Devices {
|
||||
for _, attribute := range device.Attributes {
|
||||
if attribute.BoolValues != nil ||
|
||||
attribute.IntValues != nil ||
|
||||
attribute.StringValues != nil ||
|
||||
attribute.VersionValues != nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func haveDeviceTaints(spec *resource.ResourceSliceSpec) bool {
|
||||
if spec == nil {
|
||||
return false
|
||||
|
||||
@@ -197,7 +197,7 @@ func TestValidateResourceSlice(t *testing.T) {
|
||||
},
|
||||
"good-taints": {
|
||||
slice: func() *resourceapi.ResourceSlice {
|
||||
slice := testResourceSlice(goodName, goodName, goodName, resourceapi.ResourceSliceMaxDevicesWithTaintsOrConsumesCounters)
|
||||
slice := testResourceSlice(goodName, goodName, goodName, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures)
|
||||
for i := range slice.Spec.Devices {
|
||||
slice.Spec.Devices[i].Taints = []resourceapi.DeviceTaint{{Key: "example.com/taint", Effect: resourceapi.DeviceTaintEffectNoExecute}}
|
||||
}
|
||||
@@ -205,9 +205,9 @@ func TestValidateResourceSlice(t *testing.T) {
|
||||
}(),
|
||||
},
|
||||
"too-large-taints": {
|
||||
wantFailures: field.ErrorList{field.TooMany(field.NewPath("spec", "devices"), resourceapi.ResourceSliceMaxDevicesWithTaintsOrConsumesCounters+1, resourceapi.ResourceSliceMaxDevicesWithTaintsOrConsumesCounters)},
|
||||
wantFailures: field.ErrorList{field.TooMany(field.NewPath("spec", "devices"), resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures+1, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures)},
|
||||
slice: func() *resourceapi.ResourceSlice {
|
||||
slice := testResourceSlice(goodName, goodName, goodName, resourceapi.ResourceSliceMaxDevicesWithTaintsOrConsumesCounters+1)
|
||||
slice := testResourceSlice(goodName, goodName, goodName, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures+1)
|
||||
for i := range slice.Spec.Devices {
|
||||
slice.Spec.Devices[i].Taints = []resourceapi.DeviceTaint{{Key: "example.com/taint", Effect: resourceapi.DeviceTaintEffectNoExecute}}
|
||||
}
|
||||
@@ -544,6 +544,74 @@ func TestValidateResourceSlice(t *testing.T) {
|
||||
return slice
|
||||
}(),
|
||||
},
|
||||
"max-devices-with-list-of-int-attributes": {
|
||||
slice: func() *resourceapi.ResourceSlice {
|
||||
slice := testResourceSlice(goodName, goodName, goodName, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures)
|
||||
for i := range slice.Spec.Devices {
|
||||
slice.Spec.Devices[i].Attributes["ints"] = resourceapi.DeviceAttribute{IntValues: []int64{1, 2, 3}}
|
||||
}
|
||||
return slice
|
||||
}(),
|
||||
},
|
||||
"too-many-devices-with-list-of-int-attributes": {
|
||||
wantFailures: field.ErrorList{field.TooMany(field.NewPath("spec", "devices"), resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures+1, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures)},
|
||||
slice: func() *resourceapi.ResourceSlice {
|
||||
slice := testResourceSlice(goodName, goodName, goodName, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures+1)
|
||||
slice.Spec.Devices[0].Attributes["ints"] = resourceapi.DeviceAttribute{IntValues: []int64{1, 2, 3}}
|
||||
return slice
|
||||
}(),
|
||||
},
|
||||
"max-devices-with-list-of-bool-attributes": {
|
||||
slice: func() *resourceapi.ResourceSlice {
|
||||
slice := testResourceSlice(goodName, goodName, goodName, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures)
|
||||
for i := range slice.Spec.Devices {
|
||||
slice.Spec.Devices[i].Attributes["bools"] = resourceapi.DeviceAttribute{BoolValues: []bool{true, false, true}}
|
||||
}
|
||||
return slice
|
||||
}(),
|
||||
},
|
||||
"too-many-devices-with-list-of-bool-attributes": {
|
||||
wantFailures: field.ErrorList{field.TooMany(field.NewPath("spec", "devices"), resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures+1, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures)},
|
||||
slice: func() *resourceapi.ResourceSlice {
|
||||
slice := testResourceSlice(goodName, goodName, goodName, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures+1)
|
||||
slice.Spec.Devices[0].Attributes["bools"] = resourceapi.DeviceAttribute{BoolValues: []bool{true, false, true}}
|
||||
return slice
|
||||
}(),
|
||||
},
|
||||
"max-devices-with-list-of-string-attributes": {
|
||||
slice: func() *resourceapi.ResourceSlice {
|
||||
slice := testResourceSlice(goodName, goodName, goodName, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures)
|
||||
for i := range slice.Spec.Devices {
|
||||
slice.Spec.Devices[i].Attributes["strings"] = resourceapi.DeviceAttribute{StringValues: []string{"a", "b", "c"}}
|
||||
}
|
||||
return slice
|
||||
}(),
|
||||
},
|
||||
"too-many-devices-with-list-of-string-attributes": {
|
||||
wantFailures: field.ErrorList{field.TooMany(field.NewPath("spec", "devices"), resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures+1, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures)},
|
||||
slice: func() *resourceapi.ResourceSlice {
|
||||
slice := testResourceSlice(goodName, goodName, goodName, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures+1)
|
||||
slice.Spec.Devices[0].Attributes["strings"] = resourceapi.DeviceAttribute{StringValues: []string{"a", "b", "c"}}
|
||||
return slice
|
||||
}(),
|
||||
},
|
||||
"max-devices-with-list-of-version-attributes": {
|
||||
slice: func() *resourceapi.ResourceSlice {
|
||||
slice := testResourceSlice(goodName, goodName, goodName, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures)
|
||||
for i := range slice.Spec.Devices {
|
||||
slice.Spec.Devices[i].Attributes["versions"] = resourceapi.DeviceAttribute{VersionValues: []string{"1.0.0", "2.0.0", "3.0.0"}}
|
||||
}
|
||||
return slice
|
||||
}(),
|
||||
},
|
||||
"too-many-devices-with-list-of-version-attributes": {
|
||||
wantFailures: field.ErrorList{field.TooMany(field.NewPath("spec", "devices"), resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures+1, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures)},
|
||||
slice: func() *resourceapi.ResourceSlice {
|
||||
slice := testResourceSlice(goodName, goodName, goodName, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures+1)
|
||||
slice.Spec.Devices[0].Attributes["versions"] = resourceapi.DeviceAttribute{VersionValues: []string{"1.0.0", "2.0.0", "3.0.0"}}
|
||||
return slice
|
||||
}(),
|
||||
},
|
||||
"good-attribute-names": {
|
||||
slice: func() *resourceapi.ResourceSlice {
|
||||
slice := testResourceSlice(goodName, goodName, goodName, 2)
|
||||
@@ -1170,7 +1238,7 @@ func TestValidateResourceSlice(t *testing.T) {
|
||||
},
|
||||
"max-number-of-devices-with-consumes-counters": {
|
||||
slice: func() *resourceapi.ResourceSlice {
|
||||
slice := testResourceSlice(goodName, goodName, goodName, resourceapi.ResourceSliceMaxDevicesWithTaintsOrConsumesCounters)
|
||||
slice := testResourceSlice(goodName, goodName, goodName, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures)
|
||||
for i := range slice.Spec.Devices {
|
||||
slice.Spec.Devices[i].ConsumesCounters = []resourceapi.DeviceCounterConsumption{
|
||||
{
|
||||
@@ -1183,9 +1251,9 @@ func TestValidateResourceSlice(t *testing.T) {
|
||||
}(),
|
||||
},
|
||||
"too-many-devices-with-consumes-counters": {
|
||||
wantFailures: field.ErrorList{field.TooMany(field.NewPath("spec", "devices"), resourceapi.ResourceSliceMaxDevicesWithTaintsOrConsumesCounters+1, resourceapi.ResourceSliceMaxDevicesWithTaintsOrConsumesCounters)},
|
||||
wantFailures: field.ErrorList{field.TooMany(field.NewPath("spec", "devices"), resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures+1, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures)},
|
||||
slice: func() *resourceapi.ResourceSlice {
|
||||
slice := testResourceSlice(goodName, goodName, goodName, resourceapi.ResourceSliceMaxDevicesWithTaintsOrConsumesCounters+1)
|
||||
slice := testResourceSlice(goodName, goodName, goodName, resourceapi.ResourceSliceMaxDevicesWithAdvancedFeatures+1)
|
||||
slice.Spec.Devices[0].ConsumesCounters = []resourceapi.DeviceCounterConsumption{
|
||||
{
|
||||
CounterSet: "counterset-0",
|
||||
|
||||
Reference in New Issue
Block a user