mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-09-05 07:24:31 +00:00
Adding initial version of Kubernetes backend (#552)
Co-authored-by: laszlocph <laszlo@laszlo.cloud> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Rynoxx <rynoxx@grid-servers.net>
This commit is contained in:
137
pipeline/backend/kubernetes/pod.go
Normal file
137
pipeline/backend/kubernetes/pod.go
Normal file
@@ -0,0 +1,137 @@
|
||||
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]
|
||||
}
|
Reference in New Issue
Block a user