Skip to content

CSTACKEX-234: Enabling storage pool resize (grow and shrink) - #87

Open
sathvikaragi wants to merge 1 commit into
mainfrom
feature/CSTACKEX-234
Open

CSTACKEX-234: Enabling storage pool resize (grow and shrink)#87
sathvikaragi wants to merge 1 commit into
mainfrom
feature/CSTACKEX-234

Conversation

@sathvikaragi

@sathvikaragi sathvikaragi commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Description

storage pool resize (Grow and shrink)

This PR...

[updateStoragePool] API now resizes the ONTAP FlexVolume backing the pool. When called with a new [capacityBytes], StorageManagerImpl (previously never called the lifecycle hook) now invokes [OntapPrimaryDatastoreLifecycle.updateStoragePool()], which calls the ONTAP REST API
(PATCH /api/storage/volumes/{uuid}) and polls the async job to completion. No validation is applied — the new size is passed directly to ONTAP, which enforces all constraints and returns any errors as-is.

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • 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
  • Major
  • Minor
  • Trivial

Screenshots (if appropriate):

How Has This Been Tested?

the flex volume is created with size 20GiB:
Screenshot 2026-08-07 at 2 53 44 PM

case 1: when A valid input for resize is filled by user:

Screenshot 2026-08-07 at 2 54 17 PM Screenshot 2026-08-07 at 2 54 44 PM

after successful resize:
Screenshot 2026-08-07 at 3 23 15 PM

case 2: capacity bytes given is smaller than ontap volume minimum size
Screenshot 2026-08-07 at 2 49 58 PM

case 3: capacity bytes given is smaller than ontap volume maximum size
Screenshot 2026-08-07 at 2 52 11 PM

How did you try to break this feature and the system with this change?

Copilot AI 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.

Pull request overview

This PR enables storage pool resize (grow/shrink) for ONTAP-backed primary storage by wiring the existing updateStoragePool API flow into the primary datastore lifecycle, allowing the ONTAP plugin to PATCH the backing FlexVolume size and wait for job completion.

Changes:

  • Invoke PrimaryDataStoreLifeCycle.updateStoragePool(...) from StorageManagerImpl.updateStoragePool(...) when capacity changes are requested.
  • Implement ONTAP pool-resize behavior in OntapPrimaryDatastoreLifecycle.updateStoragePool(...) by calling into the ONTAP storage strategy.
  • Add an ONTAP strategy method to request volume resize via updateVolumeRebalancing(...) and poll async completion.

Reviewed changes

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

File Description
server/src/main/java/com/cloud/storage/StorageManagerImpl.java Calls the primary datastore lifecycle hook during storage pool updates to enable backend resize actions.
plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/StorageStrategy.java Adds ONTAP FlexVolume resize operation via REST update + job polling.
plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java Implements pool resize by translating capacityBytes updates into an ONTAP volume resize call.
Suppressed comments (3)

plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java:552

  • This new code path is the core of the pool resize feature (validates ONTAP volume identifiers and triggers the ONTAP resize). The ontap plugin module already has unit tests for lifecycle behavior, but there are no tests covering updateStoragePool(): skipping when CAPACITY_BYTES is absent, failing when volume UUID/name are missing, and invoking StorageStrategy.updateStorageVolume() with the parsed byte size.
            if (volume.getUuid() == null || volume.getUuid().isEmpty() || volume.getName() == null || volume.getName().isEmpty()) {
                logger.error("updateStoragePool: Volume UUID/Name not found in details for pool: {}, cannot resize", storagePool.getName());
                throw new CloudRuntimeException("Volume UUID/Name not found in details, cannot resize ONTAP FlexVolume");
            }
            storageStrategy.updateStorageVolume(volume, newCapacityBytes);

plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/StorageStrategy.java:379

  • updateStorageVolume dereferences jobResponse.getJob().getUuid() without checking for a null response/job, which can cause an NPE. This class already has pollJobIfPresent(...) that safely treats a missing job as synchronous success, so using it here both avoids the NPE and aligns with existing job-handling behavior.
        try {
            JobResponse jobResponse = volumeFeignClient.updateVolumeRebalancing(authHeader, volume.getUuid(), resizeRequest);
            Boolean jobSucceeded = jobPollForSuccess(jobResponse.getJob().getUuid(), 10, 1000);
            if (!jobSucceeded) {
                logger.error("resizeStorageVolume: resize job failed for FlexVolume: " + volume.getName());

plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/StorageStrategy.java:389

  • This Javadoc opener is indented as if it were inside a block, which looks like a formatting artifact and can trip style checks. Align it with the other method-level Javadocs.
            /**

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server/src/main/java/com/cloud/storage/StorageManagerImpl.java
Comment on lines 362 to +370
/**
* Updates ONTAP Flex-Volume
* Eligible only for Unified ONTAP storage
* throw exception in case of disaggregated ONTAP storage
*
* @param volume the volume to update
* @return the updated Volume object
*/
public Volume updateStorageVolume(Volume volume) {
return null;
public Volume updateStorageVolume(Volume volume, Long newSizeBytes) {
if (cmd.getUrl() != null) {
details.put("url", cmd.getUrl());
}
((PrimaryDataStoreLifeCycle)dataStoreLifeCycle).updateStoragePool(pool, details);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do we need to handle exceptions here? Maybe a try-catch block over this is needed.

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.

3 participants