mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-09-28 05:04:39 +00:00
Add task UUID label to Kubernetes pods (#5544)
This commit is contained in:
@@ -19,6 +19,8 @@ The following metadata labels are supported:
|
|||||||
- `woodpecker-ci.org/repo-full-name`
|
- `woodpecker-ci.org/repo-full-name`
|
||||||
- `woodpecker-ci.org/branch`
|
- `woodpecker-ci.org/branch`
|
||||||
- `woodpecker-ci.org/org-id`
|
- `woodpecker-ci.org/org-id`
|
||||||
|
- `woodpecker-ci.org/task-uuid`
|
||||||
|
- `woodpecker-ci.org/step`
|
||||||
|
|
||||||
## Private registries
|
## Private registries
|
||||||
|
|
||||||
|
@@ -274,7 +274,7 @@ func (e *kube) StartStep(ctx context.Context, step *types.Step, taskUUID string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Trace().Str("taskUUID", taskUUID).Msgf("starting step: %s", step.Name)
|
log.Trace().Str("taskUUID", taskUUID).Msgf("starting step: %s", step.Name)
|
||||||
_, err = startPod(ctx, e, step, options)
|
_, err = startPod(ctx, e, step, options, taskUUID)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -36,11 +36,12 @@ const (
|
|||||||
// This will be removed in the future.
|
// This will be removed in the future.
|
||||||
StepLabelLegacy = "step"
|
StepLabelLegacy = "step"
|
||||||
StepLabel = "woodpecker-ci.org/step"
|
StepLabel = "woodpecker-ci.org/step"
|
||||||
|
TaskUUIDLabel = "woodpecker-ci.org/task-uuid"
|
||||||
podPrefix = "wp-"
|
podPrefix = "wp-"
|
||||||
defaultFSGroup int64 = 1000
|
defaultFSGroup int64 = 1000
|
||||||
)
|
)
|
||||||
|
|
||||||
func mkPod(step *types.Step, config *config, podName, goos string, options BackendOptions) (*v1.Pod, error) {
|
func mkPod(step *types.Step, config *config, podName, goos string, options BackendOptions, taskUUID string) (*v1.Pod, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
nsp := newNativeSecretsProcessor(config, options.Secrets)
|
nsp := newNativeSecretsProcessor(config, options.Secrets)
|
||||||
@@ -49,7 +50,7 @@ func mkPod(step *types.Step, config *config, podName, goos string, options Backe
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
meta, err := podMeta(step, config, options, podName)
|
meta, err := podMeta(step, config, options, podName, taskUUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -84,7 +85,7 @@ func podName(step *types.Step) (string, error) {
|
|||||||
return dnsName(podPrefix + step.UUID)
|
return dnsName(podPrefix + step.UUID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func podMeta(step *types.Step, config *config, options BackendOptions, podName string) (meta_v1.ObjectMeta, error) {
|
func podMeta(step *types.Step, config *config, options BackendOptions, podName, taskUUID string) (meta_v1.ObjectMeta, error) {
|
||||||
var err error
|
var err error
|
||||||
meta := meta_v1.ObjectMeta{
|
meta := meta_v1.ObjectMeta{
|
||||||
Name: podName,
|
Name: podName,
|
||||||
@@ -92,7 +93,7 @@ func podMeta(step *types.Step, config *config, options BackendOptions, podName s
|
|||||||
Annotations: podAnnotations(config, options),
|
Annotations: podAnnotations(config, options),
|
||||||
}
|
}
|
||||||
|
|
||||||
meta.Labels, err = podLabels(step, config, options)
|
meta.Labels, err = podLabels(step, config, options, taskUUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return meta, err
|
return meta, err
|
||||||
}
|
}
|
||||||
@@ -100,7 +101,7 @@ func podMeta(step *types.Step, config *config, options BackendOptions, podName s
|
|||||||
return meta, nil
|
return meta, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func podLabels(step *types.Step, config *config, options BackendOptions) (map[string]string, error) {
|
func podLabels(step *types.Step, config *config, options BackendOptions, taskUUID string) (map[string]string, error) {
|
||||||
var err error
|
var err error
|
||||||
labels := make(map[string]string)
|
labels := make(map[string]string)
|
||||||
|
|
||||||
@@ -141,6 +142,10 @@ func podLabels(step *types.Step, config *config, options BackendOptions) (map[st
|
|||||||
return labels, err
|
return labels, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(taskUUID) > 0 {
|
||||||
|
labels[TaskUUIDLabel] = taskUUID
|
||||||
|
}
|
||||||
|
|
||||||
return labels, nil
|
return labels, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,13 +603,13 @@ func mapToEnvVars(m map[string]string) []v1.EnvVar {
|
|||||||
return ev
|
return ev
|
||||||
}
|
}
|
||||||
|
|
||||||
func startPod(ctx context.Context, engine *kube, step *types.Step, options BackendOptions) (*v1.Pod, error) {
|
func startPod(ctx context.Context, engine *kube, step *types.Step, options BackendOptions, taskUUID string) (*v1.Pod, error) {
|
||||||
podName, err := stepToPodName(step)
|
podName, err := stepToPodName(step)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
engineConfig := engine.getConfig()
|
engineConfig := engine.getConfig()
|
||||||
pod, err := mkPod(step, engineConfig, podName, engine.goos, options)
|
pod, err := mkPod(step, engineConfig, podName, engine.goos, options, taskUUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,8 @@ import (
|
|||||||
"go.woodpecker-ci.org/woodpecker/v3/pipeline/backend/types"
|
"go.woodpecker-ci.org/woodpecker/v3/pipeline/backend/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const taskUUID = "11301"
|
||||||
|
|
||||||
func TestPodName(t *testing.T) {
|
func TestPodName(t *testing.T) {
|
||||||
name, err := podName(&types.Step{UUID: "01he8bebctabr3kgk0qj36d2me-0"})
|
name, err := podName(&types.Step{UUID: "01he8bebctabr3kgk0qj36d2me-0"})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -73,9 +75,10 @@ func TestPodMeta(t *testing.T) {
|
|||||||
Environment: map[string]string{"CI": "woodpecker"},
|
Environment: map[string]string{"CI": "woodpecker"},
|
||||||
}, &config{
|
}, &config{
|
||||||
Namespace: "woodpecker",
|
Namespace: "woodpecker",
|
||||||
}, BackendOptions{}, "wp-01he8bebctabr3kg-0")
|
}, BackendOptions{}, "wp-01he8bebctabr3kg-0", taskUUID)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, "wp-svc-01he8bebctabr3kg-postgres", meta.Labels[ServiceLabel])
|
assert.EqualValues(t, "wp-svc-01he8bebctabr3kg-postgres", meta.Labels[ServiceLabel])
|
||||||
|
assert.EqualValues(t, taskUUID, meta.Labels[TaskUUIDLabel])
|
||||||
|
|
||||||
// Detached service
|
// Detached service
|
||||||
meta, err = podMeta(&types.Step{
|
meta, err = podMeta(&types.Step{
|
||||||
@@ -87,7 +90,7 @@ func TestPodMeta(t *testing.T) {
|
|||||||
Environment: map[string]string{"CI": "woodpecker"},
|
Environment: map[string]string{"CI": "woodpecker"},
|
||||||
}, &config{
|
}, &config{
|
||||||
Namespace: "woodpecker",
|
Namespace: "woodpecker",
|
||||||
}, BackendOptions{}, "wp-01he8bebctabr3kg-0")
|
}, BackendOptions{}, "wp-01he8bebctabr3kg-0", taskUUID)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, "wp-svc-01he8bebctabr3kg-postgres", meta.Labels[ServiceLabel])
|
assert.EqualValues(t, "wp-svc-01he8bebctabr3kg-postgres", meta.Labels[ServiceLabel])
|
||||||
|
|
||||||
@@ -101,7 +104,7 @@ func TestPodMeta(t *testing.T) {
|
|||||||
Environment: map[string]string{"CI": "woodpecker"},
|
Environment: map[string]string{"CI": "woodpecker"},
|
||||||
}, &config{
|
}, &config{
|
||||||
Namespace: "woodpecker",
|
Namespace: "woodpecker",
|
||||||
}, BackendOptions{}, "wp-01he8bebctabr3kg-0")
|
}, BackendOptions{}, "wp-01he8bebctabr3kg-0", taskUUID)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, "", meta.Labels[ServiceLabel])
|
assert.EqualValues(t, "", meta.Labels[ServiceLabel])
|
||||||
}
|
}
|
||||||
@@ -123,7 +126,8 @@ func TestTinyPod(t *testing.T) {
|
|||||||
"namespace": "woodpecker",
|
"namespace": "woodpecker",
|
||||||
"labels": {
|
"labels": {
|
||||||
"step": "build-via-gradle",
|
"step": "build-via-gradle",
|
||||||
"woodpecker-ci.org/step": "build-via-gradle"
|
"woodpecker-ci.org/step": "build-via-gradle",
|
||||||
|
"woodpecker-ci.org/task-uuid": "11301"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"spec": {
|
"spec": {
|
||||||
@@ -185,7 +189,7 @@ func TestTinyPod(t *testing.T) {
|
|||||||
Environment: map[string]string{"CI": "woodpecker"},
|
Environment: map[string]string{"CI": "woodpecker"},
|
||||||
}, &config{
|
}, &config{
|
||||||
Namespace: "woodpecker",
|
Namespace: "woodpecker",
|
||||||
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{})
|
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{}, taskUUID)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
podJSON, err := json.Marshal(pod)
|
podJSON, err := json.Marshal(pod)
|
||||||
@@ -205,7 +209,8 @@ func TestFullPod(t *testing.T) {
|
|||||||
"app": "test",
|
"app": "test",
|
||||||
"part-of": "woodpecker-ci",
|
"part-of": "woodpecker-ci",
|
||||||
"step": "go-test",
|
"step": "go-test",
|
||||||
"woodpecker-ci.org/step": "go-test"
|
"woodpecker-ci.org/step": "go-test",
|
||||||
|
"woodpecker-ci.org/task-uuid": "11301"
|
||||||
},
|
},
|
||||||
"annotations": {
|
"annotations": {
|
||||||
"apps.kubernetes.io/pod-index": "0",
|
"apps.kubernetes.io/pod-index": "0",
|
||||||
@@ -391,19 +396,22 @@ func TestFullPod(t *testing.T) {
|
|||||||
PodTolerationsAllowFromStep: true,
|
PodTolerationsAllowFromStep: true,
|
||||||
PodNodeSelector: map[string]string{"topology.kubernetes.io/region": "eu-central-1"},
|
PodNodeSelector: map[string]string{"topology.kubernetes.io/region": "eu-central-1"},
|
||||||
SecurityContext: SecurityContextConfig{RunAsNonRoot: false},
|
SecurityContext: SecurityContextConfig{RunAsNonRoot: false},
|
||||||
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{
|
},
|
||||||
Labels: map[string]string{"part-of": "woodpecker-ci"},
|
"wp-01he8bebctabr3kgk0qj36d2me-0",
|
||||||
Annotations: map[string]string{"kubernetes.io/limit-ranger": "LimitRanger plugin set: cpu, memory request and limit for container"},
|
"linux/amd64",
|
||||||
NodeSelector: map[string]string{"storage": "ssd"},
|
BackendOptions{
|
||||||
RuntimeClassName: &runtimeClass,
|
Labels: map[string]string{"part-of": "woodpecker-ci"},
|
||||||
ServiceAccountName: "wp-svc-acc",
|
Annotations: map[string]string{"kubernetes.io/limit-ranger": "LimitRanger plugin set: cpu, memory request and limit for container"},
|
||||||
Tolerations: []Toleration{{Key: "net-port", Value: "100Mbit", Effect: TaintEffectNoSchedule}},
|
NodeSelector: map[string]string{"storage": "ssd"},
|
||||||
Resources: Resources{
|
RuntimeClassName: &runtimeClass,
|
||||||
Requests: map[string]string{"memory": "128Mi", "cpu": "1000m"},
|
ServiceAccountName: "wp-svc-acc",
|
||||||
Limits: map[string]string{"memory": "256Mi", "cpu": "2"},
|
Tolerations: []Toleration{{Key: "net-port", Value: "100Mbit", Effect: TaintEffectNoSchedule}},
|
||||||
},
|
Resources: Resources{
|
||||||
SecurityContext: &secCtx,
|
Requests: map[string]string{"memory": "128Mi", "cpu": "1000m"},
|
||||||
})
|
Limits: map[string]string{"memory": "256Mi", "cpu": "2"},
|
||||||
|
},
|
||||||
|
SecurityContext: &secCtx,
|
||||||
|
}, taskUUID)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
podJSON, err := json.Marshal(pod)
|
podJSON, err := json.Marshal(pod)
|
||||||
@@ -425,7 +433,7 @@ func TestPodPrivilege(t *testing.T) {
|
|||||||
SecurityContext: SecurityContextConfig{RunAsNonRoot: globalRunAsRoot},
|
SecurityContext: SecurityContextConfig{RunAsNonRoot: globalRunAsRoot},
|
||||||
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{
|
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{
|
||||||
SecurityContext: &secCtx,
|
SecurityContext: &secCtx,
|
||||||
})
|
}, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// securty context is requesting user and group 101 (non-root)
|
// securty context is requesting user and group 101 (non-root)
|
||||||
@@ -504,7 +512,8 @@ func TestScratchPod(t *testing.T) {
|
|||||||
"namespace": "woodpecker",
|
"namespace": "woodpecker",
|
||||||
"labels": {
|
"labels": {
|
||||||
"step": "curl-google",
|
"step": "curl-google",
|
||||||
"woodpecker-ci.org/step": "curl-google"
|
"woodpecker-ci.org/step": "curl-google",
|
||||||
|
"woodpecker-ci.org/task-uuid": "11301"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"spec": {
|
"spec": {
|
||||||
@@ -532,7 +541,7 @@ func TestScratchPod(t *testing.T) {
|
|||||||
Entrypoint: []string{"/usr/bin/curl", "-v", "google.com"},
|
Entrypoint: []string{"/usr/bin/curl", "-v", "google.com"},
|
||||||
}, &config{
|
}, &config{
|
||||||
Namespace: "woodpecker",
|
Namespace: "woodpecker",
|
||||||
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{})
|
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{}, taskUUID)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
podJSON, err := json.Marshal(pod)
|
podJSON, err := json.Marshal(pod)
|
||||||
@@ -550,7 +559,8 @@ func TestSecrets(t *testing.T) {
|
|||||||
"namespace": "woodpecker",
|
"namespace": "woodpecker",
|
||||||
"labels": {
|
"labels": {
|
||||||
"step": "test-secrets",
|
"step": "test-secrets",
|
||||||
"woodpecker-ci.org/step": "test-secrets"
|
"woodpecker-ci.org/step": "test-secrets",
|
||||||
|
"woodpecker-ci.org/task-uuid": "11301"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"spec": {
|
"spec": {
|
||||||
@@ -652,7 +662,7 @@ func TestSecrets(t *testing.T) {
|
|||||||
Target: SecretTarget{File: "~/.docker/config.json"},
|
Target: SecretTarget{File: "~/.docker/config.json"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
}, taskUUID)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
podJSON, err := json.Marshal(pod)
|
podJSON, err := json.Marshal(pod)
|
||||||
@@ -670,7 +680,8 @@ func TestPodTolerations(t *testing.T) {
|
|||||||
"namespace": "woodpecker",
|
"namespace": "woodpecker",
|
||||||
"labels": {
|
"labels": {
|
||||||
"step": "toleration-test",
|
"step": "toleration-test",
|
||||||
"woodpecker-ci.org/step": "toleration-test"
|
"woodpecker-ci.org/step": "toleration-test",
|
||||||
|
"woodpecker-ci.org/task-uuid": "11301"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"spec": {
|
"spec": {
|
||||||
@@ -711,7 +722,7 @@ func TestPodTolerations(t *testing.T) {
|
|||||||
Namespace: "woodpecker",
|
Namespace: "woodpecker",
|
||||||
PodTolerations: globalTolerations,
|
PodTolerations: globalTolerations,
|
||||||
PodTolerationsAllowFromStep: false,
|
PodTolerationsAllowFromStep: false,
|
||||||
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{})
|
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{}, taskUUID)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
podJSON, err := json.Marshal(pod)
|
podJSON, err := json.Marshal(pod)
|
||||||
@@ -729,7 +740,8 @@ func TestPodTolerationsAllowFromStep(t *testing.T) {
|
|||||||
"namespace": "woodpecker",
|
"namespace": "woodpecker",
|
||||||
"labels": {
|
"labels": {
|
||||||
"step": "toleration-test",
|
"step": "toleration-test",
|
||||||
"woodpecker-ci.org/step": "toleration-test"
|
"woodpecker-ci.org/step": "toleration-test",
|
||||||
|
"woodpecker-ci.org/task-uuid": "11301"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"spec": {
|
"spec": {
|
||||||
@@ -751,7 +763,8 @@ func TestPodTolerationsAllowFromStep(t *testing.T) {
|
|||||||
"namespace": "woodpecker",
|
"namespace": "woodpecker",
|
||||||
"labels": {
|
"labels": {
|
||||||
"step": "toleration-test",
|
"step": "toleration-test",
|
||||||
"woodpecker-ci.org/step": "toleration-test"
|
"woodpecker-ci.org/step": "toleration-test",
|
||||||
|
"woodpecker-ci.org/task-uuid": "11301"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"spec": {
|
"spec": {
|
||||||
@@ -789,7 +802,7 @@ func TestPodTolerationsAllowFromStep(t *testing.T) {
|
|||||||
PodTolerationsAllowFromStep: false,
|
PodTolerationsAllowFromStep: false,
|
||||||
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{
|
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{
|
||||||
Tolerations: stepTolerations,
|
Tolerations: stepTolerations,
|
||||||
})
|
}, taskUUID)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
podJSON, err := json.Marshal(pod)
|
podJSON, err := json.Marshal(pod)
|
||||||
@@ -803,7 +816,7 @@ func TestPodTolerationsAllowFromStep(t *testing.T) {
|
|||||||
PodTolerationsAllowFromStep: true,
|
PodTolerationsAllowFromStep: true,
|
||||||
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{
|
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{
|
||||||
Tolerations: stepTolerations,
|
Tolerations: stepTolerations,
|
||||||
})
|
}, taskUUID)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
podJSON, err = json.Marshal(pod)
|
podJSON, err = json.Marshal(pod)
|
||||||
|
Reference in New Issue
Block a user