You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -118,12 +126,14 @@ This is the wedge's headline use case in Argo: silent step failure inside a mult
118
126
119
127
| Label | Source |
120
128
|---|---|
121
-
| `run_id` | `ARGO_WORKFLOW_UID` (Workflow CR's K8s UID); falls back to `ARGO_WORKFLOW_NAME` |
129
+
| `run_id` | `ARGO_WORKFLOW_NAME` via downward API on the `workflows.argoproj.io/workflow` pod label. Argo injects `ARGO_WORKFLOW_UID` only on the `wait` sidecar, so runctx's UID-then-NAME fallback chain lands on the workflow name. |
| `node` | `ARGO_NODE_ID` (per-step DAG node identifier) |
125
-
| `pod` | `ARGO_POD_NAME` (step's pod name) |
126
-
| `namespace` | `POD_NAMESPACE` (downward API `metadata.namespace` — must be declared in env block; not in Argo's auto-injected set) |
131
+
| `workflow` | `ARGO_WORKFLOW_NAME` via downward API (same as `run_id` source) |
132
+
| `node` | `ARGO_NODE_ID` — auto-injected by Argo on the main container, no downward API needed |
133
+
| `pod` | `ARGO_POD_NAME` via downward API on `metadata.name` |
134
+
| `namespace` | `POD_NAMESPACE` via downward API on `metadata.namespace` |
135
+
136
+
> **Why so much downward API?** Argo's controller injects only `ARGO_TEMPLATE`, `ARGO_NODE_ID`, and `ARGO_CONTAINER_NAME` on the step's main container. The richer set (`ARGO_WORKFLOW_UID`, `ARGO_WORKFLOW_NAME`, `ARGO_POD_NAME`) is hardcoded by the controller onto the auxiliary `wait` sidecar only. The recipe's `env:` block uses the K8s downward API to surface workflow name, pod name, and namespace to the main container so runctx can populate the labels above. `ARGO_WORKFLOW_UID` cannot be recovered on the main container — the controller writes it as a literal env value on the `wait` sidecar with no corresponding pod label or annotation; runctx's UID-then-NAME fallback handles this gracefully.
127
137
128
138
A self-hosted CI runner (GitHub Actions, GitLab CI, etc.) deployed on Argo-managed Kubernetes will set both its CI env vars *and* `ARGO_TEMPLATE`. In that case `runctx` reports the CI platform — its labels are richer for alerting purposes — and the Argo labels are skipped. See [Configuration](../configuration.md) for the full notifier reference.
129
139
@@ -179,8 +189,15 @@ spec:
179
189
- "{{inputs.parameters.cmd}}"
180
190
envFrom: [{ secretRef: { name: ding-secrets } }]
181
191
env:
192
+
# See Minimal example for why ARGO_POD_NAME and ARGO_WORKFLOW_NAME
193
+
# need explicit downward API entries (Argo only injects them on
@@ -191,7 +208,7 @@ When `train` exits 1, DING in the `train` step's pod fires the alert; `eval` is
191
208
- `workflow=<wf-name>`(shared across all three steps)
192
209
- `node=<wf>-train-<random>`(distinct per step)
193
210
- `pod=<wf>-train-<random>-<random>`(distinct per step; contains the step name as substring)
194
-
- `run_id=<wf-uid>`(shared across all three steps — identifies the Workflow run, not the step)
211
+
- `run_id=<wf-name>`(shared across all three steps — identifies the Workflow run; runctx falls back to the workflow name because `ARGO_WORKFLOW_UID` isn't available on main containers)
195
212
196
213
**Per-step matching is constrained.** DING's `match.labels` does exact-match comparison, and Argo's `node`/`pod` values are dynamic per Workflow run. You can't write a `match.labels: { node: my-train-step }` rule that matches "the train step." Pragmatic patterns:
197
214
@@ -245,6 +262,7 @@ If the alert doesn't fire, common issues: the Secret wasn't readable (RBAC on th
245
262
246
263
## Tradeoffs / known limitations
247
264
265
+
- **Argo injects `ARGO_WORKFLOW_UID`, `ARGO_WORKFLOW_NAME`, and `ARGO_POD_NAME` only on the `wait` sidecar.** The main container (where DING runs) only gets `ARGO_TEMPLATE`, `ARGO_NODE_ID`, and `ARGO_CONTAINER_NAME` from the controller. The recipe's downward-API env block restores workflow name and pod name; `ARGO_WORKFLOW_UID` isn't available on the main container at all (no corresponding pod label/annotation), so runctx falls back to `ARGO_WORKFLOW_NAME` for `run_id`. Workflow name is stable across retried pods of the same step — good for dedup, but not globally unique like the UID would be.
248
266
- **Template name not auto-labeled.** `runctx` doesn't parse `ARGO_TEMPLATE` JSON. Surface template name manually via downward API on the `workflows.argoproj.io/template` pod label if needed (see [Surfacing the template name](#surfacing-the-template-name-manual)).
249
267
- **Per-step matching is constrained.** Parallel/fan-out steps share `run_id`; `node` and `pod` are dynamic per run, so DING's exact-match `match.labels` can't pre-target a specific DAG step's `run.exit`. Disambiguate in the message template, or emit step labels yourself for during-run rules.
250
268
- **`onExit` template alerts get a different `node`.** If you put DING in an `onExit` template instead of (or in addition to) the main step, its alerts have a different `node` label than the failed step they're reporting on, breaking per-step matching for users who copy-paste rules from the K8s recipe.
@@ -257,7 +275,7 @@ This recipe is **a Tier-2 candidate** by the program's standard rubric:
257
275
258
276
- **Setup commands required:** 1 (`kubectl apply`) — under threshold of 5
259
277
- **Boilerplate lines:** ~95 minimal + ~50 DAG subsection ≈ ~145 YAML — over threshold of 50 → **Tier-2 candidate**
260
-
- **"Gotcha" callouts:** 5 — over threshold of 2 → **Tier-2 candidate**
278
+
- **"Gotcha" callouts:** 6 — over threshold of 2 → **Tier-2 candidate**
**Tier-2 candidate.** The boilerplate count is the structural problem — both the minimal manifest and the DAG subsection are mostly mechanical plumbing (volumes, initContainers, downward API env block) that every Argo user will copy verbatim. An `argo-workflow-template` repo (separate, mirroring [`ding-k8s-job`](https://github.com/ding-labs/ding-k8s-job)) that publishes a parameterized `WorkflowTemplate` to GHCR — invoked via `argo submit --from workflowtemplate/ding-step --parameter image=my-app --parameter command='python train.py' --parameter slack-url=$SLACK_WEBHOOK_URL` — would collapse the recipe to a one-line invocation. Defer the chart until 2+ users ask.
0 commit comments