mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-02 06:41:18 +00:00
3b0263442a
Co-authored-by: laszlocph <laszlo@laszlo.cloud> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Rynoxx <rynoxx@grid-servers.net>
137 lines
3.4 KiB
Go
137 lines
3.4 KiB
Go
package kubernetes
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"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
|
|
var volMounts []v1.VolumeMount
|
|
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
|
|
}
|
|
|
|
command := step.Entrypoint
|
|
args := step.Command
|
|
envs := mapToEnvVars(step.Environment)
|
|
|
|
if _, hasScript := step.Environment["CI_SCRIPT"]; !strings.HasSuffix(step.Name, "_clone") && hasScript {
|
|
command = []string{"/bin/sh", "-c"}
|
|
args = []string{"echo $CI_SCRIPT | base64 -d | /bin/sh -e"}
|
|
}
|
|
|
|
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: command,
|
|
Args: args,
|
|
WorkingDir: step.WorkingDir,
|
|
Env: envs,
|
|
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]
|
|
}
|