-
Notifications
You must be signed in to change notification settings - Fork 5
Add comprehensive controller development rules, reconciliation flow library, and refactor API/controllers #495
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Signed-off-by: David Magton <david.magton@flant.com>
…ation Signed-off-by: David Magton <david.magton@flant.com>
…ng rules - Renamed condition Type/Reason constants for all API types that have status.conditions (RV/RVR/RVA/RSC/RSP) to: - <ObjPrefix>Cond<...>Type - <ObjPrefix>Cond<...>Reason<...> - string values unchanged. - Updated all usages across controllers/agent/CSI/megatest and tests; split shared reasons per condition type while keeping the same string values. - Added Cursor rules in .cursor/api_conditions_rules.mdc. Signed-off-by: David Magton <david.magton@flant.com>
- Add .cursor/go_rules.mdc, .cursor/go_test_rules.mdc, .cursor/api_codegen_rules.mdc - Update .cursor/rules.mdc with commit message requirements Signed-off-by: David Magton <david.magton@flant.com>
- Split API into *_types.go and *_conditions.go; add shared helpers - Rename condition constants to object-scoped Replicated*Cond* identifiers - Update controllers/tests to use the new condition/type names - Regenerate CRDs and move Cursor rules under .cursor/rules/* Signed-off-by: David Magton <david.magton@flant.com>
127f13a to
0e31413
Compare
- Rename Cursor rules from RULE.md to *.mdc - Add tooling.mdc with canonical commands and "must ask" boundaries - Add .envrc to keep Go/golangci-lint caches under .cache/ - Ignore .cache/ and .direnv/ in .gitignore Signed-off-by: David Magton <david.magton@flant.com>
- API: represent ReplicatedVolume status.deviceMinor as v1alpha1.DeviceMinor and add range validation. - API: add DeviceMinorOutOfRangeError and exclude it from controller-gen object/deepcopy generation. - Controller: genericize rv_controller/idpool and use IDPool[v1alpha1.DeviceMinor] for allocation. - Codegen: regenerate deepcopy outputs.\n- Tooling: document non-API type generation hygiene in Cursor api-types rules. Signed-off-by: David Magton <david.magton@flant.com>
Introduce api/objutilv1 (conditions, labels, finalizers, ownerrefs, interfaces) with tests, and update API types to implement StatusConditionObject adapters (GetStatusConditions/SetStatusConditions). Refactor controller/agent code to use objutilv1 (imported as obju): - condition comparisons use semantic equality with ObservedGeneration (SpecAware) - label updates use objutilv1.SetLabel - finalizer checks use objutilv1.HasFinalizer/HasFinalizersOtherThan Update API rules docs to require StatusConditionObject adapters on root objects. Signed-off-by: David Magton <david.magton@flant.com>
- Add internal/reconciliation/flow with Outcome helpers, phase logging, and tests - Refactor rv_controller reconciler to use flow.Begin/BeginPhase, split main vs status, and improve error aggregation - Switch ReplicatedVolume label sync helpers to objutilv1 label operations - Add go.work wiring for nested modules and make hack/run-tests.sh workspace-aware Signed-off-by: David Magton <david.magton@flant.com>
- flow: make Outcome fields private (result/err) and update docs/tests accordingly - objutilv1: add condition comparison helpers (by semantic meaning / by Type+Status) with tests - objutilv1: add missing godoc for labels/finalizers/ownerrefs helpers - cursor: add controller wiring/file-structure rules for IDE guidance Signed-off-by: David Magton <david.magton@flant.com>
- Add TL;DR + explicit ALLOW/DENY boundaries for controller.go (wiring vs business logic) - Clarify predicate best practices: generation vs metadata-only changes; prefer client.Object getters; use obju for conditions - Update repo-wide commit-message rules to require sign-off and remind about it when generating commit messages Signed-off-by: David Magton <david.magton@flant.com>
Signed-off-by: David Magton <david.magton@flant.com>
…n Outcome - Add change tracking API on flow.Outcome (ReportChanged*, DidChange, RequireOptimisticLock, OptimisticLockRequired, Error) - Aggregate change tracking state in flow.Merge - Refactor and extend tests (external flow_test + internal guard test for unsupported Requeue=true) Signed-off-by: David Magton <david.magton@flant.com>
Signed-off-by: David Magton <david.magton@flant.com>
a2d6b45 to
78141bb
Compare
…e.Errorf - Add Cursor rules for ReconcileHelper categories (compute/apply/ensure/is-up-to-date/create/delete/patch) - Extend controller file-structure rules to formalize Reconcile vs ReconcileHelper vs other code in reconciler.go - Move controller reconciliation rules document to repo root (disable alwaysApply in frontmatter) - Add flow.Outcome.Errorf() helper + unit tests Signed-off-by: David Magton <david.magton@flant.com>
78141bb to
2137cbd
Compare
Update and extend ReconcileHelper category docs (compute/apply/ensure/create/delete/patch/isUpToDate) and the shared helper conventions. Signed-off-by: David Magton <david.magton@flant.com>
- Make controller reconciliation rules always-applied and scope them via globs - Restructure and tighten the document (patterns, DeepCopy/base rules, phases, checklist) Signed-off-by: David Magton <david.magton@flant.com>
- Clarify error context layering: Reconcile methods add action/phase context, helpers must not include primary reconcile identity - Tighten error-handling guidance across apply/compute/ensure/create/delete/patch/isUpToDate helper categories - Add guidance on when to extract helpers and document deterministic reconciler-owned state exceptions (e.g., idpool/cache) Signed-off-by: David Magton <david.magton@flant.com>
- Record phase metadata in ctx; log phase start/end at V(1) - Add Outcome.OnErrorf for local wrapping + logging + phase-aware wrapping - Rename Outcome.Errorf -> Wrapf; add Outcome.Merge - Update flow tests Signed-off-by: David Magton <david.magton@flant.com>
- Document compute helper restrictions for change/optimistic-lock reporting - Add recommended ensure helper reporting patterns - Minor wording fix in patch helper doc Signed-off-by: David Magton <david.magton@flant.com>
- Add `controller-terminology.mdc` and `controller-reconciliation-flow.mdc` - Refine reconciliation, compute and ensure helper guidelines Signed-off-by: David Magton <david.magton@flant.com>
- Make TL;DR sections non-normative (“Summary only”) and move requirements into explicit sections - Align helper category docs (apply/compute/create/delete/ensure/is-up-to-date/patch) with consistent terminology, naming and keywords - Expand `controller-terminology.mdc` and apply consistent bolding for defined terms Signed-off-by: David Magton <david.magton@flant.com>
ce4191e to
c4f2967
Compare
- Change BeginPhase kv to string key/value pairs and panic on odd-length input - Render phase kv in errors as "phase <name> [k=v ...]" consistently - Add tests for kv validation and error formatting Signed-off-by: David Magton <david.magton@flant.com>
- Move error logging to EndPhase and track it via Outcome.ErrorLogged to avoid duplicates - Rename Outcome.Wrapf -> Enrichf and adjust docs/examples accordingly - Make Merge treat any error as Fail and drop ContinueErr/ContinueErrf - Update rv_controller reconciler and controller .mdc rules to match the new flow contract Signed-off-by: David Magton <david.magton@flant.com>
- Bold standardized controller terminology across rule documents - Clarify wording around wiring-only vs reconciliation logic and predicate scope - Keep content consistent across helper category docs (compute/apply/ensure/create/delete/patch) Signed-off-by: David Magton <david.magton@flant.com>
- Run main/status reconciliation sequentially with explicit flow phases and documented patterns - Extract RV patch helpers (main vs status) and deviceMinor desired-state helpers - Tighten tests to assert returned Signed-off-by: David Magton <david.magton@flant.com>
- Move replicated-storage-class label sync logic into rv_controller reconcileMain - Remove ReplicatedVolume label helper methods from api/v1alpha1 Signed-off-by: David Magton <david.magton@flant.com>
- rv_controller: switch root Reconcile to orchestration style; rework status deviceMinor reconciliation via allocateDM phase - idpool: replace GetOrCreate/GetOrCreateWithID/BulkAdd with EnsureAllocated/Fill; return OutOfRangeError instead of panicking; add Is/AsOutOfRange helpers and update tests - api: drop DeviceMinor validation/error and ReplicatedVolumeStatus deviceMinor helpers from v1alpha1; adjust objutilv1 condition semantic equality to default ObservedGeneration from object - docs: update controller rule docs and add ConstructionReconcileHelper guidelines Signed-off-by: David Magton <david.magton@flant.com>
- Update controller helper naming/contracts docs: IsUpToDate -> IsInSync - Adjust rv_controller status drift check helper to isDMInSync Signed-off-by: David Magton <david.magton@flant.com>
…aming - On ReplicatedVolume NotFound, set rv=nil to allow cleanup paths (e.g. device-minor release) - Align reconciliation pattern comments (Pure orchestration / Target-state driven) - Normalize device-minor phase name and helper/variable naming (targetDM, newDeviceMinorAssignedCondition) Signed-off-by: David Magton <david.magton@flant.com>
Signed-off-by: David Magton <david.magton@flant.com>
889ac1c to
05946b9
Compare
Signed-off-by: David Magton <david.magton@flant.com>
…elper docs - Make controller wiring docs require predicates to live in predicate.go (wired via builder.WithPredicates). - Add GetReconcileHelper contract and align helper-category listings/terminology. - Tighten flow and controller terminology docs (phase naming, root/non-root phase rules, controller name kebab-case). Signed-off-by: David Magton <david.magton@flant.com>
- Convert rule scoping to single-string `globs` and stop `alwaysApply` for scoped docs - Link controller rule docs to `rfc-like-mdc.mdc` and remove duplicated keyword sections - Align predicate file naming in rules (`predicate.go` -> `predicates.go`) Signed-off-by: David Magton <david.magton@flant.com>
- Remove emphasis from BCP 14 keywords (MUST/SHOULD/MAY, etc.) across controller rules - Adjust section headings and bullets to match `rfc-like-mdc.mdc` conventions Signed-off-by: David Magton <david.magton@flant.com>
…aming - Document canonical short kind names (RV/RVR/RVA/RSC/RSP) in `controller-terminology.mdc` - Require using short kind names for repo API kinds across controller predicates and reconcile helper naming rules Signed-off-by: David Magton <david.magton@flant.com>
- Define call-graph based ordering for Reconcile methods and non-I/O helper blocks - Specify canonical grouping/sorting for I/O helpers (get/create/patch/delete) at file end Signed-off-by: David Magton <david.magton@flant.com>
…state variable naming - Require `*T` for `omitempty` non-nil-able fields in controller POV artifacts to preserve “unset” - Define canonical naming for intended/actual/target/report variables and forbid new “desired” usage Signed-off-by: David Magton <david.magton@flant.com>
…iliation rules - Specify that `omitempty` scalar fields MUST be represented as pointers to preserve unset vs zero - Add `ptr.Equal`/nil handling guidance and update the TimeoutSeconds example Signed-off-by: David Magton <david.magton@flant.com>
- Document controller-runtime split client semantics and stale-read implications - Require idempotent, deterministic reconciliation under retry and cache lag - Outline protections for create/update operations to avoid non-deterministic duplicates Signed-off-by: David Magton <david.magton@flant.com>
- Refactor internal reconciliation flow into explicit scopes (`ReconcileFlow`, `EnsureFlow`, `StepFlow`) with dedicated outcome types and consistent phase logging/validation. - Update `rv_controller` reconciler to use the new API (`BeginRootReconcile` / `BeginReconcile`) and adjust tests accordingly. - Mark controller-related Cursor rules as always-applied and refine rule descriptions. Signed-off-by: David Magton <david.magton@flant.com>
Signed-off-by: David Magton <david.magton@flant.com>
- Keep existing status.deviceMinor when the device-minor pool source is unavailable and report the failure via DeviceMinorAssigned condition - Add coverage for the pool-not-ready error path - Normalize Cursor .mdc rule frontmatter descriptions and relax alwaysApply where appropriate Signed-off-by: David Magton <david.magton@flant.com>
…sureOutcome
Redesign the reconciliation flow API in controller .mdc rules:
- Split single `flow.Outcome` type into specialized types:
- `flow.ReconcileOutcome` for Reconcile methods
- `flow.EnsureOutcome` for ensure helpers (carries change/lock flags)
- Plain `error` for create/delete/patch/step helpers
- Replace phase API:
- `BeginPhase/EndPhase` → scoped constructors with `OnEnd` methods:
- `BeginRootReconcile` (root Reconcile, no OnEnd)
- `BeginReconcile` + `rf.OnEnd(&outcome)` (non-root Reconcile)
- `BeginEnsure` + `ef.OnEnd(&outcome)` (ensure helpers)
- `BeginStep` + `sf.OnEnd(&err)` (step helpers returning error)
- Update terminology throughout:
- "phase" → "phase scope"
- "Outcome" → "ReconcileOutcome" / "EnsureOutcome"
- Simplify helper return types:
- Create/Delete/Patch helpers: MUST return `error`, NOT outcome
- Compute helpers: MUST NOT return EnsureOutcome
- Ensure helpers: MUST create ensure phase scope, accept ctx
- Restructure controller-reconciliation-flow.mdc for clarity
Signed-off-by: David Magton <david.magton@flant.com>
- Unify placeholder type names: rename SKN/SomeKindName/EON to EK/ExampleKind for consistency across all helper rules - Add explicit inline comments to bad examples clarifying why ctx and client.Client are forbidden in apply/construction/is-in-sync helpers - Rewrite ensure helper examples to use proper flow.BeginEnsure() + defer ef.OnEnd(&outcome) pattern - Fix flow.Outcome → flow.EnsureOutcome naming in ensure rules - Align terminology: "desired" → "intended/target" in compute rules - Add implementation example section to patch helper rules showing optimistic lock handling - Fix confusing step function example in reconciliation-flow rules - Remove duplicate line in controller-reconcile-helper.mdc Signed-off-by: David Magton <david.magton@flant.com>
eb5ffb1 to
77d3b5e
Compare
Image modules were not listed in go.work, causing CI test failures with "directory prefix . does not contain modules listed in go.work" error. Additionally, images/controller was missing the internal module dependency required for internal/reconciliation/flow import. Changes: - Add all images/*/go.mod modules to go.work use() directive - Update hack/run-tests.sh case pattern to stay in sync with go.work - Add replace directive and require for internal module in images/controller/go.mod - Add internal to includePaths in images/controller/werf.inc.yaml so the directory is available during container build Signed-off-by: David Magton <david.magton@flant.com>
ae0044a to
e76bc15
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Add comprehensive controller development rules, reconciliation flow library, and refactor API/controllers
Summary
This PR introduces comprehensive Cursor AI rules for controller development, a new
flowpackage for standardized reconciliation patterns, a reusableobjutilv1utilities package, and refactors the controller architecture with a unifiedrv_controller.Key Changes
Cursor Rules (
.cursor/rules/) — +5,741 linesComprehensive documentation for AI-assisted controller development following RFC 2119/8174 conventions:
API Rules:
api-types.mdc— Type definitions, optional scalars, kubebuilder markersapi-conditions.mdc— Condition type/reason/message conventionsapi-labels-and-finalizers.mdc— Label keys, finalizer namingapi-file-structure.mdc— File organization (<kind>_types.go,<kind>_conditions.go)api-codegen.mdc— Code generation workflowController Rules:
controller-terminology.mdc— Shared terminology (intended/actual/target/report, patch domains)controller-file-structure.mdc— Package structure (controller.go,predicates.go,reconciler.go)controller-controller.mdc— Builder chain, watches, predicates wiringcontroller-predicate.mdc— Predicate implementation patternscontroller-reconciliation.mdc— Reconciliation pipeline, I/O boundariescontroller-reconciliation-flow.mdc— Flow package usage patternsReconcileHelper Rules (9 files):
controller-reconcile-helper.mdc— Overview and naming conventionscontroller-reconcile-helper-compute.mdc—compute*helpers (non-I/O)controller-reconcile-helper-construction.mdc—new*/build*/make*helperscontroller-reconcile-helper-is-in-sync.mdc—is*InSynccomparison helperscontroller-reconcile-helper-apply.mdc—apply*mutation helperscontroller-reconcile-helper-ensure.mdc—ensure*helpers with change trackingcontroller-reconcile-helper-get.mdc—get*single-call read helperscontroller-reconcile-helper-create.mdc/delete.mdc/patch.mdc— Write helpersGeneral Rules:
rfc-like-mdc.mdc— RFC-style writing conventions for.mdcfilesgo.mdc,go-tests.mdc— Go coding conventionsrepo-wide.mdc,tooling.mdc— Repository-wide patternsReconciliation Flow Library (
internal/reconciliation/flow/) — +1,749 linesNew
flowpackage providing typed scopes for reconciliation phases with standardized logging, panic handling, and error context:ReconcileFlow— For reconcile methods, returnsReconcileOutcome(requeue control + error)EnsureFlow— For ensure helpers, returnsEnsureOutcome(change tracking + optimistic lock intent)StepFlow— For plain steps returningerrorFeatures:
phase start/phase end+ duration)ShouldReturn()andToCtrl()convertersObject Utilities (
api/objutilv1/) — +1,065 linesNew reusable package for Kubernetes object manipulation:
conditions.go— Condition comparison, semantic equality, batch operationsfinalizers.go— Add/remove/check finalizerslabels.go— Label manipulation utilitiesownerrefs.go— Owner reference helpersinterfaces.go—StatusConditionObjectinterface for polymorphic condition accessAll utilities include comprehensive tests.
Controller Refactoring (
images/controller/)New
rv_controller:rv_metadataandrv_status_config_device_minorcontrollersGeneric ID Pool (
idpool/):IDPool[T]for allocating unique numeric IDsDuplicateIDError,PoolExhaustedError,NameConflictError)API Reorganization (
api/v1alpha1/)replicated_volume.go→rv_types.go, etc.*_conditions.gofilesconditions.go,errors.go,*_consts.goGetStatusConditions()/SetStatusConditions()methods forobjutilv1compatibilityOther Changes
drbd_configpredicatesmegatestfor ReplicatedVolumeAttachment