Allow setting resources for kubernetes on a per-step basis (#1767)

This add a simple implementation of requests/limits for individual
steps. There is no validation of what the resource actually is beyond
checking that it can successfully be converted to a Quantity, so it can
be used for things other than just memory/CPU.

close #1809
This commit is contained in:
Stephen Muth
2023-06-03 18:50:08 -04:00
committed by GitHub
parent 14177635b6
commit 2941e508b3
10 changed files with 273 additions and 131 deletions

View File

@@ -1,6 +1,7 @@
package kubernetes
import (
"fmt"
"strings"
"github.com/woodpecker-ci/woodpecker/pipeline/backend/common"
@@ -62,35 +63,21 @@ func Pod(namespace string, step *types.Step, labels, annotations map[string]stri
hostAliases = append(hostAliases, v1.HostAlias{IP: host[1], Hostnames: []string{host[0]}})
}
// TODO: add support for resource limits
// if step.Resources.CPULimit == "" {
// step.Resources.CPULimit = "2"
// }
// if step.Resources.MemoryLimit == "" {
// step.Resources.MemoryLimit = "2G"
// }
// memoryLimit := resource.MustParse(step.Resources.MemoryLimit)
// CPULimit := resource.MustParse(step.Resources.CPULimit)
memoryLimit := resource.MustParse("2G")
CPULimit := resource.MustParse("2")
memoryLimitValue, _ := memoryLimit.AsInt64()
CPULimitValue, _ := CPULimit.AsInt64()
loadfactor := 0.5
memoryRequest := resource.NewQuantity(int64(float64(memoryLimitValue)*loadfactor), resource.DecimalSI)
CPURequest := resource.NewQuantity(int64(float64(CPULimitValue)*loadfactor), resource.DecimalSI)
resources := v1.ResourceRequirements{
Requests: v1.ResourceList{
v1.ResourceMemory: *memoryRequest,
v1.ResourceCPU: *CPURequest,
},
Limits: v1.ResourceList{
v1.ResourceMemory: memoryLimit,
v1.ResourceCPU: CPULimit,
},
resourceRequirements := v1.ResourceRequirements{Requests: v1.ResourceList{}, Limits: v1.ResourceList{}}
var err error
for key, val := range step.BackendOptions.Kubernetes.Resources.Requests {
resourceKey := v1.ResourceName(key)
resourceRequirements.Requests[resourceKey], err = resource.ParseQuantity(val)
if err != nil {
return nil, fmt.Errorf("resource request '%v' quantity '%v': %w", key, val, err)
}
}
for key, val := range step.BackendOptions.Kubernetes.Resources.Limits {
resourceKey := v1.ResourceName(key)
resourceRequirements.Limits[resourceKey], err = resource.ParseQuantity(val)
if err != nil {
return nil, fmt.Errorf("resource limit '%v' quantity '%v': %w", key, val, err)
}
}
podName, err := dnsName(step.Name)
@@ -130,7 +117,7 @@ func Pod(namespace string, step *types.Step, labels, annotations map[string]stri
WorkingDir: step.WorkingDir,
Env: mapToEnvVars(step.Environment),
VolumeMounts: volMounts,
Resources: resources,
Resources: resourceRequirements,
SecurityContext: &v1.SecurityContext{
Privileged: &step.Privileged,
},