Compare commits

...
Author SHA1 Message Date
claude-bot 1f3afcd7e3 feat(woodpecker): liveness probe on the agent healthcheck
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
ci/woodpecker/pr/ci-manifests-test Pipeline was successful
ci/woodpecker/pr/pr-review Pipeline was successful
The agent was the last workload in this repo running a real service with no
probe of any kind. WOODPECKER_HEALTHCHECK defaults to true and already serves
:3000, so nothing had to be enabled — the port was simply never declared and
never probed. Confirmed against the running pod: /healthz answers 200, / and
/metrics do not.

What it actually asserts is narrower than the name suggests, and narrower than
I assumed when proposing this. State.Healthy in agent/state.go returns false
only when a running workflow has passed its own timeout plus a one-hour buffer;
an agent with nothing to do always answers 200.

So this catches one specific failure — a wedged build holding a slot, which
today nobody would notice — and explicitly does not catch an agent that has
lost its connection to the server. That agent reports healthy while quietly
taking no work, which was the failure I originally wanted to cover. The comment
says so, because a green probe here is easy to misread as "CI is fine".

Liveness only. The agent fronts no Service, so a readiness probe would gate
nothing. Thresholds are short because the upstream condition already carries an
hour of debounce.

Everything else still unprobed is either operator- or chart-owned (Rook, the
authentik outposts, the kube-prometheus-stack sidecars, Multus, cert-manager,
mariadb-operator, velero node-agent) or a sidecar loop with no listening socket
where an exec probe would assert little beyond what container exit already
does.
2026-08-28 14:31:45 +02:00
+25
View File
@@ -94,6 +94,31 @@ spec:
envFrom:
- secretRef:
name: woodpecker-secret
ports:
# WOODPECKER_HEALTHCHECK defaults to true and serves :3000, so this
# port already existed; declaring it just lets the probe name it.
- name: health
containerPort: 3000
protocol: TCP
# /healthz answers 500 ONLY when a running workflow has passed its own
# timeout plus a one-hour buffer (agent/state.go, State.Healthy). An
# idle agent always answers 200.
#
# So this catches a wedged build holding a slot, which is otherwise
# invisible — and it does NOT catch an agent that has lost its server
# connection, which reports healthy while quietly taking no work. Do
# not read a green probe here as "CI is fine".
#
# Liveness only: the agent fronts no Service, so readiness would gate
# nothing. The upstream condition is already debounced by that hour,
# which is why the thresholds here are short.
livenessProbe:
httpGet:
path: /healthz
port: health
initialDelaySeconds: 20
periodSeconds: 30
timeoutSeconds: 5
resources:
requests:
cpu: 25m