Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 61 additions & 2 deletions pkg/device/hygon/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,67 @@ func ParseConfig(fs *flag.FlagSet) {
}

func (dev *DCUDevices) MutateAdmission(ctr *corev1.Container, p *corev1.Pod) (bool, error) {
_, ok := ctr.Resources.Limits[corev1.ResourceName(HygonResourceCount)]
return ok, nil
count, countRequested := ctr.Resources.Limits[corev1.ResourceName(HygonResourceCount)]
reqCount, reqRequested := ctr.Resources.Requests[corev1.ResourceName(HygonResourceCount)]

if countRequested || reqRequested {
if countRequested {
n, isInt := count.AsInt64()
if !isInt || n <= 0 || n > math.MaxInt32 {
return false, fmt.Errorf("%s must be a positive integer between 1 and %d", HygonResourceCount, math.MaxInt32)
}
}
if reqRequested {
n, isInt := reqCount.AsInt64()
if !isInt || n <= 0 || n > math.MaxInt32 {
return false, fmt.Errorf("%s must be a positive integer between 1 and %d", HygonResourceCount, math.MaxInt32)
}
}
if countRequested && reqRequested {
limitN, _ := count.AsInt64()
reqN, _ := reqCount.AsInt64()
if limitN != reqN {
return false, fmt.Errorf("conflicting %s request (%d) and limit (%d)", HygonResourceCount, reqN, limitN)
}
}
if !countRequested && reqRequested {
if ctr.Resources.Limits == nil {
ctr.Resources.Limits = corev1.ResourceList{}
}
ctr.Resources.Limits[corev1.ResourceName(HygonResourceCount)] = reqCount
} else if countRequested && !reqRequested {
if ctr.Resources.Requests == nil {
ctr.Resources.Requests = corev1.ResourceList{}
}
ctr.Resources.Requests[corev1.ResourceName(HygonResourceCount)] = count
}
return true, nil
}

_, memRequested := ctr.Resources.Limits[corev1.ResourceName(HygonResourceMemory)]
if !memRequested {
_, memRequested = ctr.Resources.Requests[corev1.ResourceName(HygonResourceMemory)]
}
_, coreRequested := ctr.Resources.Limits[corev1.ResourceName(HygonResourceCores)]
if !coreRequested {
_, coreRequested = ctr.Resources.Requests[corev1.ResourceName(HygonResourceCores)]
}

if memRequested || coreRequested {
gpuQty := *resource.NewQuantity(1, resource.DecimalSI)
if ctr.Resources.Limits == nil {
ctr.Resources.Limits = corev1.ResourceList{}
}
ctr.Resources.Limits[corev1.ResourceName(HygonResourceCount)] = gpuQty

if ctr.Resources.Requests == nil {
ctr.Resources.Requests = corev1.ResourceList{}
}
ctr.Resources.Requests[corev1.ResourceName(HygonResourceCount)] = gpuQty
return true, nil
}

return false, nil
}

func checkDCUtype(annos map[string]string, cardtype string) bool {
Expand Down
162 changes: 160 additions & 2 deletions pkg/device/hygon/device_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,173 @@ func Test_MutateAdmission(t *testing.T) {
want: true,
err: nil,
},
{
name: "dcu memory in limits -> synthesizes count in limits and requests",
args: struct {
ctr *corev1.Container
p *corev1.Pod
}{
ctr: &corev1.Container{
Resources: corev1.ResourceRequirements{
Limits: corev1.ResourceList{
"hygon.com/dcumem": resource.MustParse("1024"),
},
},
},
p: &corev1.Pod{},
},
want: true,
err: nil,
},
{
name: "requests only (limits empty) -> true and syncs limits",
args: struct {
ctr *corev1.Container
p *corev1.Pod
}{
ctr: &corev1.Container{
Resources: corev1.ResourceRequirements{
Requests: corev1.ResourceList{
"hygon.com/dcunum": resource.MustParse("1"),
},
},
},
p: &corev1.Pod{},
},
want: true,
err: nil,
},
{
name: "rejects zero dcu count",
args: struct {
ctr *corev1.Container
p *corev1.Pod
}{
ctr: &corev1.Container{
Resources: corev1.ResourceRequirements{
Limits: corev1.ResourceList{
"hygon.com/dcunum": resource.MustParse("0"),
},
},
},
p: &corev1.Pod{},
},
want: false,
err: fmt.Errorf("hygon.com/dcunum must be a positive integer between 1 and 2147483647"),
},
{
name: "rejects negative dcu count",
args: struct {
ctr *corev1.Container
p *corev1.Pod
}{
ctr: &corev1.Container{
Resources: corev1.ResourceRequirements{
Limits: corev1.ResourceList{
"hygon.com/dcunum": resource.MustParse("-1"),
},
},
},
p: &corev1.Pod{},
},
want: false,
err: fmt.Errorf("hygon.com/dcunum must be a positive integer between 1 and 2147483647"),
},
{
name: "rejects fractional dcu count",
args: struct {
ctr *corev1.Container
p *corev1.Pod
}{
ctr: &corev1.Container{
Resources: corev1.ResourceRequirements{
Limits: corev1.ResourceList{
"hygon.com/dcunum": resource.MustParse("1.5"),
},
},
},
p: &corev1.Pod{},
},
want: false,
err: fmt.Errorf("hygon.com/dcunum must be a positive integer between 1 and 2147483647"),
},
{
name: "rejects overflow dcu count",
args: struct {
ctr *corev1.Container
p *corev1.Pod
}{
ctr: &corev1.Container{
Resources: corev1.ResourceRequirements{
Limits: corev1.ResourceList{
"hygon.com/dcunum": *resource.NewQuantity(math.MaxInt32+1, resource.DecimalSI),
},
},
},
p: &corev1.Pod{},
},
want: false,
err: fmt.Errorf("hygon.com/dcunum must be a positive integer between 1 and 2147483647"),
},
{
name: "accepts max int32 dcu count",
args: struct {
ctr *corev1.Container
p *corev1.Pod
}{
ctr: &corev1.Container{
Resources: corev1.ResourceRequirements{
Limits: corev1.ResourceList{
"hygon.com/dcunum": *resource.NewQuantity(math.MaxInt32, resource.DecimalSI),
},
},
},
p: &corev1.Pod{},
},
want: true,
err: nil,
},
{
name: "conflicting count in limits and requests",
args: struct {
ctr *corev1.Container
p *corev1.Pod
}{
ctr: &corev1.Container{
Resources: corev1.ResourceRequirements{
Limits: corev1.ResourceList{
"hygon.com/dcunum": resource.MustParse("1"),
},
Requests: corev1.ResourceList{
"hygon.com/dcunum": resource.MustParse("5"),
},
},
},
p: &corev1.Pod{},
},
want: false,
err: fmt.Errorf("conflicting hygon.com/dcunum request"),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
dev := DCUDevices{}
result, err := dev.MutateAdmission(test.args.ctr, test.args.p)
if err != test.err {
klog.InfoS("set to resource limits failed")
if test.err != nil {
assert.ErrorContains(t, err, test.err.Error())
return
}
assert.NilError(t, err)
assert.Equal(t, result, test.want)
if result && test.name == "dcu memory in limits -> synthesizes count in limits and requests" {
limitQty, ok := test.args.ctr.Resources.Limits["hygon.com/dcunum"]
assert.Equal(t, ok, true)
assert.Equal(t, limitQty.Value(), int64(1))

reqQty, ok := test.args.ctr.Resources.Requests["hygon.com/dcunum"]
assert.Equal(t, ok, true)
assert.Equal(t, reqQty.Value(), int64(1))
}
})
}
}
Expand Down
Loading