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
Progress is currently derived from three independent conditions (Approved / DriftDetected / Applied assembled in build_status, k8s/controller/redfish_node_profile_controller.py) — there is no single authoritative phase, which is what makes windows like #255 possible and outcomes ambiguous after a crash.
Design
Use an explicit state machine persisted in status as one field:
pending
→ planning
→ awaiting_approval
→ quiescing
→ applying
→ waiting_for_bmc_task
→ rebooting
→ verifying
→ ready_for_workload
→ workload_running
→ rolling_back
→ succeeded
Any active phase may transition to:
failed
blocked
unknown_outcome
unknown_outcome is the honest state for a crash between a side effect and its confirmation; a reconcile that finds itself there verifies actual BMC state instead of re-applying.
Existing conditions remain, but as projections derived from the single phase (Kubernetes conventions preserved; no more three-way inference).
Invalid transitions are rejected and logged; every transition carries a reason and timestamp.
Tests: full transition-table coverage plus crash-injection at every persisted boundary (fake-kopf harness in tests/test_k8s_controller_concurrency.py is reusable).
Relates to #255 (crash replay) and the tracing contract (each phase is a natural span/attribute boundary for the per-reconcile root span in #256).
Summary
Progress is currently derived from three independent conditions (Approved / DriftDetected / Applied assembled in build_status, k8s/controller/redfish_node_profile_controller.py) — there is no single authoritative phase, which is what makes windows like #255 possible and outcomes ambiguous after a crash.
Design
Use an explicit state machine persisted in status as one field:
Requirements
applyinglands in etcd before the BMC write, which closes the NodeProfile controller can replay a consumed plan after a crash #255 replay window by construction.unknown_outcomeis the honest state for a crash between a side effect and its confirmation; a reconcile that finds itself there verifies actual BMC state instead of re-applying.Relates to #255 (crash replay) and the tracing contract (each phase is a natural span/attribute boundary for the per-reconcile root span in #256).