Skip to content

fix: clamp ResourcePool available at zero and stop corrupting Hard#2024

Open
AruneshDwivedi wants to merge 4 commits into
projectcapsule:mainfrom
AruneshDwivedi:fix/resourcepool-negative-allocation
Open

fix: clamp ResourcePool available at zero and stop corrupting Hard#2024
AruneshDwivedi wants to merge 4 commits into
projectcapsule:mainfrom
AruneshDwivedi:fix/resourcepool-negative-allocation

Conversation

@AruneshDwivedi

Copy link
Copy Markdown

What

CalculateAvailableResources subtracted the claimed amount from the live Hard map entry (qt.Sub(amount) mutates the range value in place). When claims exceeded the hard limit this wrote a negative value into both Status.Allocation.Available and Status.Allocation.Hard, so the pool reported negative capacity and Hard itself got corrupted on every reconcile.

Fix

  • Compute available into a DeepCopy() of the hard quantity, leaving Hard intact.
  • Clamp available at zero: a pool can never offer a negative amount of resources.

Why this is the right place

With available clamped at zero, CanClaimFromPool correctly rejects a new oversized claim (available.Cmp(req) < 0), and Hard stays correct for downstream math. The webhook re-validates a patched ResourcePoolClaim against the pool, so an over-subscribed patch now surfaces a PoolExhausted condition instead of silently leaving a negative pool.

Verification

Added TestCalculateResources_OverSubscriptionDoesNotGoNegative in api/v1beta2/resourcepool_func_test.go. go test ./api/v1beta2/ passes, including the existing TestCalculateResources.

Fixes #1977

CalculateAvailableResources subtracted the claimed amount from the live Hard
map entry (qt.Sub mutates the range value in place), so an over-subscribed
pool wrote a negative value into both Status.Allocation.Available and
Status.Allocation.Hard. Clamp available at zero and compute into a copy so
Hard stays intact. Fixes projectcapsule#1977.

Signed-off-by: Arunesh Dwivedi <arunesh.dwivedi@example.com>
Copilot AI review requested due to automatic review settings July 12, 2026 16:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes ResourcePool available-capacity calculation so it can’t go negative and avoids mutating/corrupting the underlying Hard quantities when subtracting claimed resources (addressing oversubscription behavior reported in #1977).

Changes:

  • Compute “available” from a copied quantity instead of mutating the Hard quantity during subtraction.
  • Clamp computed availability at zero to prevent negative capacity reporting.
  • Add a regression test covering oversubscription and ensuring Hard stays intact.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
api/v1beta2/resourcepool_func.go Avoids mutating underlying quota quantities during available computation and clamps available at zero.
api/v1beta2/resourcepool_func_test.go Adds regression coverage for oversubscription to prevent negative available and ensure Hard remains unchanged.

Comment thread api/v1beta2/resourcepool_func.go Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 13, 2026 07:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment on lines 166 to +168
amount, exists := r.Status.Allocation.Claimed[res]
if exists {
qt.Sub(amount)
remaining.Sub(amount)
Comment on lines +171 to 175
// A pool can never offer a negative amount of resources, so clamp
// at zero. This also keeps Hard intact for downstream math.
if remaining.Sign() < 0 {
remaining = resource.MustParse("0")
}
…rces

The follow-up edit removed the 'remaining := qt.DeepCopy()' line, leaving
'remaining' undefined and breaking the build. Re-add the declaration so the
available-resources computation compiles and Hard is not mutated in place.

Signed-off-by: Arunesh Dwivedi <arunesh.devops@gmail.com>
Copilot AI review requested due to automatic review settings July 16, 2026 09:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Signed-off-by: AruneshDwivedi <arunesh.dwivedi@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 19, 2026 09:04
@AruneshDwivedi

Copy link
Copy Markdown
Author

Added the same zero clamp to GetAvailableClaimableResources so an over-claimed pool no longer surfaces negative available quantities in PoolExhausted messages, with a regression test covering the over-subscription case.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

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.

ResourcePool quota may become negative

3 participants