Repository navigation
CLO-188 orchestratord: report Materialize lifecycle transitions as events - #38537
Alphadelta14 wants to merge 4 commits into
Conversation
5d3c90e to
c977770
Compare
|
All contributors have signed the CLA. |
There was a problem hiding this comment.
Pull request overview
Adds Kubernetes events for Materialize rollout lifecycle transitions.
Changes:
- Publishes Normal or Warning events after status transitions persist.
- Shares the reconciliation event publisher with the Materialize controller.
- Adds orchestratord lifecycle-event coverage.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/orchestratord/src/controller/materialize.rs |
Publishes lifecycle transition events. |
src/orchestratord/src/bin/orchestratord.rs |
Injects the shared event publisher. |
src/orchestratord/src/reconcile.rs |
Documents lifecycle event reporting. |
test/orchestratord/mzcompose.py |
Verifies successful rollout events. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
|
||
| # Two manual promotions have now driven the full lifecycle, so every phase | ||
| # of one should have been reported as an event. | ||
| check_lifecycle_events(definition) |
78ae0b9 to
20c7d0e
Compare
QA LLM Review1. MEDIUM --
|
jubrad
left a comment
There was a problem hiding this comment.
Reads correct to me: the one-event-per-transition property genuinely follows from the needs_update guard, and publishing after replace_status means no event claims a transition that failed to persist.
Summary
1 consideration
1 nit
written by claude on behalf of @jubrad
|
|
||
| # Two manual promotions have now driven the full lifecycle, so every phase | ||
| # of one should have been reported as an event. | ||
| check_lifecycle_events(definition) |
There was a problem hiding this comment.
consider — Noted by claude:
wait_for_rollout_complete() polls the status, but the Applied event is published after replace_status returns, so the test can observe the final status before the event it asserts on exists. The window is one API round trip and will usually be closed by the 1s poll granularity, but it is a real race.
The sibling check just above uses retry(check, 300) for exactly this reason. Wrapping the body of check_lifecycle_events the same way would cost nothing and remove the flake:
retry(lambda: _check_lifecycle_events(name), 60)written by claude on behalf of @jubrad
| .set(u64::cast_from(needs_update_set.len())); | ||
| } | ||
|
|
||
| /// Reports a lifecycle transition as a Kubernetes event on the resource. |
There was a problem hiding this comment.
nit — This is ~30 lines of doc and inline prose for ~20 lines of code, and a good part of it re-argues things that already have an owner. The third paragraph ("These do not aggregate the way repeated failures do...") restates Publisher's aggregation contract, which the Publisher doc explains at length; the inline comment at the let condition = ... line restates the guard three lines above it; and the second paragraph explains the relationship to Observed::publish_failure from the wrong end.
Per CLAUDE.md the doc comment should be the caller's contract, with reasoning at the decision point and each fact owned once. Something like a one-line summary plus "published only once the status is durable" would carry everything a caller needs, with the severity policy staying on transition_event_type where it already lives.
written by claude on behalf of @jubrad
The status conditions record only the phase an environment is in now, so a rollout that has moved on leaves no account of the phases it passed through. Report each transition as a Kubernetes event, which the monitoring stack persists as a structured log. `update_status` is the single place a condition is written, and it already returns early unless the status substantively moved, comparing everything but the timestamp. That makes it an exact edge detector, so a reconciler that re-runs on every watch event still files one event per transition without tracking any state of its own. The event carries the condition's own reason and message, so `Applying`, `ReadyToPromote`, `Promoting`, `Applied`, `WaitingForApproval`, `RolloutTimeout` and `FailedDeploy` are one vocabulary across the status, `kubectl describe`, and a dashboard. Publishing happens after the status write lands, so no event claims a transition that failed to persist. Failures now report twice, once here with the phase and once from the reconciliation wrapper with the cause; the reasons tell them apart. `workflow_manually_promote` drives a promotion through every phase, so it asserts the vocabulary rather than that any event at all was published. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The severity of a lifecycle event was taken from the condition's status, so every reason carrying `UpToDate=False` reported as a warning. Three reasons carry it: `FailedDeploy` and `RolloutTimeout`, which are failures, and `WaitingForApproval`, which is not. That last one is the operator doing exactly what it was configured to do, holding a detected change until someone requests the rollout. Flagging it teaches people to ignore warnings on Materialize resources, which costs them the two that mean something. The rule moves into `transition_event_type`, which special-cases that reason and otherwise falls back to the status, so a failure reason added later still reports as a warning without having to be named there. A unit test pins the severity of every condition the controller writes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
a0503df to
8698e04
Compare
QA LLM Review1. MEDIUM -- Failure events now bypass
|
This reverts commit 8698e04, which does not build: it points `Observed::publish_failure` back at a `recorder` field that no longer exists, since the aggregation fix replaced it with `publisher`. The commit reapplies the free `publish` function verbatim, stale doc comment included, and leaves it beside the `Publisher` that superseded it with no callers. That is the rebase conflict resolved toward the wrong side rather than an intended change, so reverting it restores the file to its parent exactly. Reinstating that path would also undo the fix for the aggregation bug QA reported on the parent branch: publishing every failure through one shared recorder pins a failing resource's event note to whichever error came first, for as long as the failure lasts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Closed in favor of #39030 |
Motivation
While #35829 addresses failure cases, this adds some additional information
about rollouts themselves upon success.
Description
Add Normal events upon rollout stages
Verification
Soon~
Stack created with GitHub Stacks CLI • Give Feedback 💬