Add task UUID label to Kubernetes pods (#5544)

This commit is contained in:
Henrik Huitti
2025-09-23 21:30:20 +03:00
committed by GitHub
parent 7707e843f2
commit 0bd69e876f
4 changed files with 58 additions and 38 deletions

View File

@@ -19,6 +19,8 @@ The following metadata labels are supported:
- `woodpecker-ci.org/repo-full-name`
- `woodpecker-ci.org/branch`
- `woodpecker-ci.org/org-id`
- `woodpecker-ci.org/task-uuid`
- `woodpecker-ci.org/step`
## Private registries

View File

@@ -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)
_, err = startPod(ctx, e, step, options)
_, err = startPod(ctx, e, step, options, taskUUID)
return err
}

View File

@@ -36,11 +36,12 @@ const (
// This will be removed in the future.
StepLabelLegacy = "step"
StepLabel = "woodpecker-ci.org/step"
TaskUUIDLabel = "woodpecker-ci.org/task-uuid"
podPrefix = "wp-"
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
nsp := newNativeSecretsProcessor(config, options.Secrets)
@@ -49,7 +50,7 @@ func mkPod(step *types.Step, config *config, podName, goos string, options Backe
return nil, err
}
meta, err := podMeta(step, config, options, podName)
meta, err := podMeta(step, config, options, podName, taskUUID)
if err != nil {
return nil, err
}
@@ -84,7 +85,7 @@ func podName(step *types.Step) (string, error) {
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
meta := meta_v1.ObjectMeta{
Name: podName,
@@ -92,7 +93,7 @@ func podMeta(step *types.Step, config *config, options BackendOptions, podName s
Annotations: podAnnotations(config, options),
}
meta.Labels, err = podLabels(step, config, options)
meta.Labels, err = podLabels(step, config, options, taskUUID)
if err != nil {
return meta, err
}
@@ -100,7 +101,7 @@ func podMeta(step *types.Step, config *config, options BackendOptions, podName s
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
labels := make(map[string]string)
@@ -141,6 +142,10 @@ func podLabels(step *types.Step, config *config, options BackendOptions) (map[st
return labels, err
}
if len(taskUUID) > 0 {
labels[TaskUUIDLabel] = taskUUID
}
return labels, nil
}
@@ -598,13 +603,13 @@ func mapToEnvVars(m map[string]string) []v1.EnvVar {
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)
if err != nil {
return nil, err
}
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 {
return nil, err
}

View File

@@ -25,6 +25,8 @@ import (
"go.woodpecker-ci.org/woodpecker/v3/pipeline/backend/types"
)
const taskUUID = "11301"
func TestPodName(t *testing.T) {
name, err := podName(&types.Step{UUID: "01he8bebctabr3kgk0qj36d2me-0"})
assert.NoError(t, err)
@@ -73,9 +75,10 @@ func TestPodMeta(t *testing.T) {
Environment: map[string]string{"CI": "woodpecker"},
}, &config{
Namespace: "woodpecker",
}, BackendOptions{}, "wp-01he8bebctabr3kg-0")
}, BackendOptions{}, "wp-01he8bebctabr3kg-0", taskUUID)
assert.NoError(t, err)
assert.EqualValues(t, "wp-svc-01he8bebctabr3kg-postgres", meta.Labels[ServiceLabel])
assert.EqualValues(t, taskUUID, meta.Labels[TaskUUIDLabel])
// Detached service
meta, err = podMeta(&types.Step{
@@ -87,7 +90,7 @@ func TestPodMeta(t *testing.T) {
Environment: map[string]string{"CI": "woodpecker"},
}, &config{
Namespace: "woodpecker",
}, BackendOptions{}, "wp-01he8bebctabr3kg-0")
}, BackendOptions{}, "wp-01he8bebctabr3kg-0", taskUUID)
assert.NoError(t, err)
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"},
}, &config{
Namespace: "woodpecker",
}, BackendOptions{}, "wp-01he8bebctabr3kg-0")
}, BackendOptions{}, "wp-01he8bebctabr3kg-0", taskUUID)
assert.NoError(t, err)
assert.EqualValues(t, "", meta.Labels[ServiceLabel])
}
@@ -123,7 +126,8 @@ func TestTinyPod(t *testing.T) {
"namespace": "woodpecker",
"labels": {
"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": {
@@ -185,7 +189,7 @@ func TestTinyPod(t *testing.T) {
Environment: map[string]string{"CI": "woodpecker"},
}, &config{
Namespace: "woodpecker",
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{})
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{}, taskUUID)
assert.NoError(t, err)
podJSON, err := json.Marshal(pod)
@@ -205,7 +209,8 @@ func TestFullPod(t *testing.T) {
"app": "test",
"part-of": "woodpecker-ci",
"step": "go-test",
"woodpecker-ci.org/step": "go-test"
"woodpecker-ci.org/step": "go-test",
"woodpecker-ci.org/task-uuid": "11301"
},
"annotations": {
"apps.kubernetes.io/pod-index": "0",
@@ -391,19 +396,22 @@ func TestFullPod(t *testing.T) {
PodTolerationsAllowFromStep: true,
PodNodeSelector: map[string]string{"topology.kubernetes.io/region": "eu-central-1"},
SecurityContext: SecurityContextConfig{RunAsNonRoot: false},
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{
Labels: map[string]string{"part-of": "woodpecker-ci"},
Annotations: map[string]string{"kubernetes.io/limit-ranger": "LimitRanger plugin set: cpu, memory request and limit for container"},
NodeSelector: map[string]string{"storage": "ssd"},
RuntimeClassName: &runtimeClass,
ServiceAccountName: "wp-svc-acc",
Tolerations: []Toleration{{Key: "net-port", Value: "100Mbit", Effect: TaintEffectNoSchedule}},
Resources: Resources{
Requests: map[string]string{"memory": "128Mi", "cpu": "1000m"},
Limits: map[string]string{"memory": "256Mi", "cpu": "2"},
},
SecurityContext: &secCtx,
})
},
"wp-01he8bebctabr3kgk0qj36d2me-0",
"linux/amd64",
BackendOptions{
Labels: map[string]string{"part-of": "woodpecker-ci"},
Annotations: map[string]string{"kubernetes.io/limit-ranger": "LimitRanger plugin set: cpu, memory request and limit for container"},
NodeSelector: map[string]string{"storage": "ssd"},
RuntimeClassName: &runtimeClass,
ServiceAccountName: "wp-svc-acc",
Tolerations: []Toleration{{Key: "net-port", Value: "100Mbit", Effect: TaintEffectNoSchedule}},
Resources: Resources{
Requests: map[string]string{"memory": "128Mi", "cpu": "1000m"},
Limits: map[string]string{"memory": "256Mi", "cpu": "2"},
},
SecurityContext: &secCtx,
}, taskUUID)
assert.NoError(t, err)
podJSON, err := json.Marshal(pod)
@@ -425,7 +433,7 @@ func TestPodPrivilege(t *testing.T) {
SecurityContext: SecurityContextConfig{RunAsNonRoot: globalRunAsRoot},
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{
SecurityContext: &secCtx,
})
}, "")
}
// securty context is requesting user and group 101 (non-root)
@@ -504,7 +512,8 @@ func TestScratchPod(t *testing.T) {
"namespace": "woodpecker",
"labels": {
"step": "curl-google",
"woodpecker-ci.org/step": "curl-google"
"woodpecker-ci.org/step": "curl-google",
"woodpecker-ci.org/task-uuid": "11301"
}
},
"spec": {
@@ -532,7 +541,7 @@ func TestScratchPod(t *testing.T) {
Entrypoint: []string{"/usr/bin/curl", "-v", "google.com"},
}, &config{
Namespace: "woodpecker",
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{})
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{}, taskUUID)
assert.NoError(t, err)
podJSON, err := json.Marshal(pod)
@@ -550,7 +559,8 @@ func TestSecrets(t *testing.T) {
"namespace": "woodpecker",
"labels": {
"step": "test-secrets",
"woodpecker-ci.org/step": "test-secrets"
"woodpecker-ci.org/step": "test-secrets",
"woodpecker-ci.org/task-uuid": "11301"
}
},
"spec": {
@@ -652,7 +662,7 @@ func TestSecrets(t *testing.T) {
Target: SecretTarget{File: "~/.docker/config.json"},
},
},
})
}, taskUUID)
assert.NoError(t, err)
podJSON, err := json.Marshal(pod)
@@ -670,7 +680,8 @@ func TestPodTolerations(t *testing.T) {
"namespace": "woodpecker",
"labels": {
"step": "toleration-test",
"woodpecker-ci.org/step": "toleration-test"
"woodpecker-ci.org/step": "toleration-test",
"woodpecker-ci.org/task-uuid": "11301"
}
},
"spec": {
@@ -711,7 +722,7 @@ func TestPodTolerations(t *testing.T) {
Namespace: "woodpecker",
PodTolerations: globalTolerations,
PodTolerationsAllowFromStep: false,
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{})
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{}, taskUUID)
assert.NoError(t, err)
podJSON, err := json.Marshal(pod)
@@ -729,7 +740,8 @@ func TestPodTolerationsAllowFromStep(t *testing.T) {
"namespace": "woodpecker",
"labels": {
"step": "toleration-test",
"woodpecker-ci.org/step": "toleration-test"
"woodpecker-ci.org/step": "toleration-test",
"woodpecker-ci.org/task-uuid": "11301"
}
},
"spec": {
@@ -751,7 +763,8 @@ func TestPodTolerationsAllowFromStep(t *testing.T) {
"namespace": "woodpecker",
"labels": {
"step": "toleration-test",
"woodpecker-ci.org/step": "toleration-test"
"woodpecker-ci.org/step": "toleration-test",
"woodpecker-ci.org/task-uuid": "11301"
}
},
"spec": {
@@ -789,7 +802,7 @@ func TestPodTolerationsAllowFromStep(t *testing.T) {
PodTolerationsAllowFromStep: false,
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{
Tolerations: stepTolerations,
})
}, taskUUID)
assert.NoError(t, err)
podJSON, err := json.Marshal(pod)
@@ -803,7 +816,7 @@ func TestPodTolerationsAllowFromStep(t *testing.T) {
PodTolerationsAllowFromStep: true,
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{
Tolerations: stepTolerations,
})
}, taskUUID)
assert.NoError(t, err)
podJSON, err = json.Marshal(pod)