woodpecker/pipeline/backend/kubernetes/pod.go
6543 b15ca52a63
Move constrain to only have a single command in backend to run to dedicated backends (#1032)
at the moment we compile a script that we can pipe in as single command
this is because of the constrains the docker backend gives us.

so we move it into the docker backend and eventually get rid of it altogether
2022-10-31 00:26:49 +01:00

144 lines
3.4 KiB
Go

package kubernetes
import (
"strings"
"github.com/woodpecker-ci/woodpecker/pipeline/backend/common"
"github.com/woodpecker-ci/woodpecker/pipeline/backend/types"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func Pod(namespace string, step *types.Step) *v1.Pod {
var (
vols []v1.Volume
volMounts []v1.VolumeMount
entrypoint []string
args []string
)
if step.WorkingDir != "" {
for _, vol := range step.Volumes {
vols = append(vols, v1.Volume{
Name: volumeName(vol),
VolumeSource: v1.VolumeSource{
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
ClaimName: volumeName(vol),
ReadOnly: false,
},
},
})
volMounts = append(volMounts, v1.VolumeMount{
Name: volumeName(vol),
MountPath: volumeMountPath(vol),
})
}
}
pullPolicy := v1.PullIfNotPresent
if step.Pull {
pullPolicy = v1.PullAlways
}
if len(step.Commands) != 0 {
scriptEnv, entry, cmds := common.GenerateContainerConf(step.Commands)
for k, v := range scriptEnv {
step.Environment[k] = v
}
entrypoint = entry
args = cmds
}
hostAliases := []v1.HostAlias{}
for _, extraHost := range step.ExtraHosts {
host := strings.Split(extraHost, ":")
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,
},
}
return &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: podName(step),
Namespace: namespace,
Labels: map[string]string{
"step": podName(step),
},
},
Spec: v1.PodSpec{
RestartPolicy: v1.RestartPolicyNever,
HostAliases: hostAliases,
Containers: []v1.Container{{
Name: podName(step),
Image: step.Image,
ImagePullPolicy: pullPolicy,
Command: entrypoint,
Args: args,
WorkingDir: step.WorkingDir,
Env: mapToEnvVars(step.Environment),
VolumeMounts: volMounts,
Resources: resources,
SecurityContext: &v1.SecurityContext{
Privileged: &step.Privileged,
},
}},
ImagePullSecrets: []v1.LocalObjectReference{{Name: "regcred"}},
Volumes: vols,
},
}
}
func podName(s *types.Step) string {
return dnsName(s.Name)
}
func mapToEnvVars(m map[string]string) []v1.EnvVar {
var ev []v1.EnvVar
for k, v := range m {
ev = append(ev, v1.EnvVar{
Name: k,
Value: v,
})
}
return ev
}
func volumeMountPath(i string) string {
s := strings.Split(i, ":")
if len(s) > 1 {
return s[1]
}
return s[0]
}