The package field exposed by VirtFusion as `primaryStorageProfile` is a storage *type code* (mirrors `server_packages.storage_type` in the VF database), not a profile id. It's meant to filter to any pool whose `storageType` matches — multiple pools across the fleet can carry the same code, which is exactly how multi-hypervisor placement works for mountpoint/datastore storage. `capForStorage()` was checking `pool.id` against this code. Pool ids are unique per hypervisor (e.g. for the same logical mountpoint on three hypervisors, ids 23/28/30) and almost never match the type-code domain (0=local default, 4=mountpoint, etc.). The mismatch silently returned 0 for every hypervisor, zeroing qty fleet-wide whenever the package's type code didn't accidentally collide with some pool id. Symptoms in the wild: every stock-controlled VPS product showed qty=0 in WHMCS even with abundant memory/CPU/IPv4 capacity. Disabling `stockcontrol` on the product or removing `primaryStorageProfile` from the package were the only known workarounds; both lose the actual stock gating this module is meant to provide. Fix: - Match `pool.storageType` instead of `pool.id`. - Walk all pools that match (a hypervisor may have multiple pools of the same type) and use the one that fits the most VMs, instead of short-circuiting on the first match. A disabled pool no longer kills the whole hypervisor's capacity for that type — we just skip it and keep looking for an enabled peer. - Rename the parameter from `$profileId` to `$storageTypeId` so future readers don't fall into the same naming trap. Updated the docblock with a NOTE explaining the VirtFusion-side naming inconsistency. Verified on a 3-hypervisor cluster with `storageType=4` (mountpoint) packages: qty went from 0/0/0/0/0/0/0/0 to 66/32/15/7/3/1/32/15 across the VPS-1 through VPS-32 + storage products without any other config change.
21 KiB
21 KiB