genegr opened a new pull request, #13050:
URL: https://github.com/apache/cloudstack/pull/13050
### Description
This PR fixes `FlashArrayAdapter.getManagedStorageStats()` so that a
FlashArray primary pool registered against a pod **without** an explicit quota
reports real capacity to the CloudStack allocator instead of `0 / 0`.
#### Problem
`getManagedStorageStats()` returns `null` whenever the pod footprint is `0`,
and otherwise derives capacity purely from the pod quota:
```java
if (pod == null || pod.getFootprint() == 0) {
return null;
}
Long capacityBytes = pod.getQuotaLimit();
Long usedBytes = pod.getQuotaLimit() - (pod.getQuotaLimit() -
pod.getFootprint());
```
A freshly-registered pool on a pod without a quota therefore surfaces as:
```
disksizetotal = 0
disksizeused = 0
```
`ClusterScopeStoragePoolAllocator` treats a zero-capacity pool as ineligible
and skips it. The user's first attempt to deploy onto the pool fails with
`Unable to find suitable primary storage`, and there is no documented way to
fix it from the CloudStack side — the operator has to discover that pod quotas
drive the reported capacity and set one on the array by hand.
The secondary bug is the `usedBytes` math: `pod.getQuotaLimit() -
(pod.getQuotaLimit() - pod.getFootprint())` is just `pod.getFootprint()`, but
with an extra NullPointerException surface when `getQuotaLimit()` returns
`null`.
#### Fix
- Report `pod.getQuotaLimit()` when present and non-zero; otherwise fall
back to the array's total physical capacity via `GET /arrays?space=true` (a new
`getArrayTotalCapacity()` helper).
- Only return `null` when neither value is obtainable (i.e. the array REST
is unreachable) — not when the pod is simply empty.
- Report `pod.getFootprint()` as `usedBytes`, defaulting to `0` when the
field is absent. Drops the NPE-prone math.
**Expected behaviour**: `cmk list storagepools name=<pool>` shows a non-zero
`disksizetotal` (the pod quota if set, or the array total otherwise);
subsequent deploys route to the pool normally.
**Actual behaviour (before this PR)**: `disksizetotal=0`, the allocator
skips the pool, deploys fail with `Unable to find suitable primary storage`,
operator has to manually set a pod quota on the array.
<!-- Fixes: # -->
### Types of changes
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] New feature (non-breaking change which adds functionality)
- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] Enhancement (improves an existing feature and functionality)
- [ ] Cleanup (Code refactoring and cleanup, that may add test cases)
- [ ] Build/CI
- [ ] Test (unit or integration test code)
### Feature/Enhancement Scale or Bug Severity
#### Feature/Enhancement Scale
- [ ] Major
- [ ] Minor
#### Bug Severity
- [ ] BLOCKER
- [ ] Critical
- [x] Major
- [ ] Minor
- [ ] Trivial
A freshly-registered pool is unusable for allocation until the operator
discovers the undocumented pod-quota requirement and sets it by hand on the
array. Not a BLOCKER (the pool still builds up; create-from-API with an
explicit pool id still works), but any default-offering-based deploy hits it.
### Screenshots (if appropriate):
N/A — backend adapter change, no UI surface.
### How Has This Been Tested?
Tested against Purity 6.7 on a two-node KVM cluster with a FlashArray pool
registered against a pod that has **no quota** set.
1. Register pool via `cmk create storagepool ... provider=FlashArray
url=https://<user>:<pass>@<fa>:443/api?pod=<name>&api_skiptlsvalidation=true`.
2. `cmk list storagepools name=<pool>` — verified `disksizetotal` == array
total physical capacity (matches `GET /arrays?space=true` → `capacity` = 29.5
TB on the test array).
3. `cmk deploy virtualmachine ...` using an offering tagged to the pool —
succeeds.
4. `cmk create volume` + `cmk attach volume` — succeeds; `disksizeused`
increments by the provisioned size.
5. Repeated with a pod that **does** have an explicit quota — verified the
quota is reported instead of the array total (no behaviour change for that
path).
**Build**: `mvn -pl plugins/storage/volume/flasharray --also-make -am
-DskipTests -Dcheckstyle.skip=false --batch-mode package` passes with
checkstyle enabled.
#### How did you try to break this feature and the system with this change?
- **Array unreachable during a stats refresh**: `getArrayTotalCapacity()`
catches the exception, logs a warning, returns `null`; the outer method then
returns `null` and the allocator treats the pool as temporarily unavailable —
same behaviour as any other transient storage-pool-stats failure. No crash, no
NPE.
- **Pod exists but REST returns no quota field**: `pod.getQuotaLimit()` is
null → falls through to the array-total path → pool still reports real capacity.
- **Pod footprint absent**: `usedBytes` defaults to `0`. Verified with
`SELECT disksizeused FROM storage_pool WHERE name=...` before any volume has
been provisioned.
- **Array capacity field is non-numeric** (defensive, not seen in practice):
`cap instanceof Number` guards the cast; falls through to `null` without
throwing.
- **Pod with explicit quota smaller than current footprint**: still reports
the quota (not clamped) — matches prior behaviour, not changed by this PR.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]