Skip to content

Return Released addresses to the pool after a class's releaseDelay - #11

Open
Timofei Larkin (lllamnyp) wants to merge 1 commit into
feat/class-deletion-guardfrom
feat/release-delay
Open

Timofei Larkin (lllamnyp) wants to merge 1 commit into
feat/class-deletion-guardfrom
feat/release-delay

Conversation

@lllamnyp

Copy link
Copy Markdown
Member

Implements the release delay of the ip-address-claims proposal (Failure and edge cases: "A class may set releaseDelay: after it elapses the controller clears claimRef and the address returns to Available. An address marked held by an annotation is exempt"). A review of cozystack/cozystack#3382 noted that Released addresses under the default Retain accumulate, attributed to no one, until an admin clears them. Stacked on #10.

Changes

  • API.
    • IPAddressClass.spec.releaseDelay, a metav1.Duration. It is optional and applies under Retain only. The CRD and deepcopy are regenerated.
    • ipaddress.local.sdn.cozystack.io/held: "true" on an IPAddress exempts it from the delay.
    • AnnotationTrue names the value that turns on the group's boolean annotations.
  • Bound condition on IPAddress. The core sets it together with each phase it owns: True for Bound, and False with reason Available, Released or Pending otherwise. Its lastTransitionTime dates the release. Both the address controller and the claim finalizer set phases through one helper, markPhase.
  • Delay.
    • Once releaseDelay has passed since an address was released, the address controller clears its claimRef and the address becomes Available on the next pass.
    • Before then, it requeues for the remaining time.
    • A class event re-evaluates that class's Released addresses, so changing the delay takes effect. The delay is read from the class, not copied onto the address.
  • Docs. docs/design.md §5 gains step 7 and the state diagram's new edge; the README lifecycle is updated.

Behaviour to know

  • An address that was Released before this version has no Bound condition. Its delay counts from the first pass that sets the condition, so upgrading does not immediately reissue old releases.
  • The delay applies only to addresses whose claim is gone. Claims with a controller owner delete their addresses instead (Auto-claim addresses for LoadBalancer Services that name no claim #7), so it never applies to auto-claims.
  • Conflict and Lost remain driver-owned and are not touched.

Not in this PR

The Associated condition from the proposal. It is driver-owned, alongside status.associatedTo.

go test ./internal/controller/ and golangci-lint run pass.

IPAddressClass gains spec.releaseDelay. Under Retain, the core clears
the claimRef of a Released address once the delay has passed since its
release, and the address becomes Available. An address annotated
ipaddress.local.sdn.cozystack.io/held: "true" is exempt.

The release is dated by a Bound condition on IPAddress, which the core
now sets together with every phase it owns. AnnotationTrue names the
value boolean annotations of the group take.

Assisted-By: LLM
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
@coderabbitai

coderabbitai Bot commented Nov 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 61a61827-d59c-45f9-948c-41271903fa2f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@IvanHunters IvanHunters left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: return Released addresses to the pool after a class's releaseDelay

Conforms to the design. releaseAfterDelay (internal/controller/ipaddress_controller.go:193) acts only on a Released address that is not held, only for a class whose releaseDelay is set and positive, measures from the Bound/Released condition's lastTransitionTime, and requeues with a strict remaining > 0 so there is no negative or zero RequeueAfter. The clock is injectable. Tests pass.

[NIT] held pauses the action, not the clock

The held check returns early without touching the condition, so releaseDelay keeps elapsing while an address is quarantined. Removing held from an address that has sat quarantined longer than releaseDelay returns it to the pool on the next reconcile, with no cooling-off after the quarantine is lifted. This may be intended (lifting the hold means you want the address back), but it is not obvious and is not documented; a line in the operator guide would help.

Minor notes

  • markPhase sets the condition's lastTransitionTime from meta.SetStatusCondition (real time.Now()), not the injectable r.Now, so the clock injection is partial; harmless in production but worth knowing.
  • Nothing enforces that releaseDelay is meaningful only under Retain; under Delete the field is silently inert. A CEL note or validation would match the "Retain only" wording.
  • See the cross-PR note on #10: a Retain class's releaseDelay returns addresses to Available rather than deleting them, which blocks the class-deletion finalizer. Worth documenting together.

LGTM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants