From dd1844cc5c2ac19a7ea853816012926d5200df70 Mon Sep 17 00:00:00 2001 From: sr73318 Date: Fri, 7 Aug 2026 15:11:09 +0530 Subject: [PATCH 1/5] CSTACKEX-234: Enabling storage pool resize (grow and shrink) --- .../OntapPrimaryDatastoreLifecycle.java | 30 +++++++++++++++++++ .../storage/service/StorageStrategy.java | 23 +++++++++++--- .../com/cloud/storage/StorageManagerImpl.java | 2 +- 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java index a206eaa053df..59852aa9bca9 100755 --- a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java @@ -526,7 +526,37 @@ public boolean migrateToObjectStore(DataStore store) { @Override public void updateStoragePool(StoragePool storagePool, Map details) { + StoragePoolVO poolVO = storagePoolDao.findById(storagePool.getId()); + if (poolVO == null) { + throw new CloudRuntimeException("updateStoragePool: storage pool not found: " + storagePool.getId()); + } + String strNewCapacityBytes = details.get(PrimaryDataStoreLifeCycle.CAPACITY_BYTES); + if (strNewCapacityBytes == null) { + logger.debug("updateStoragePool: no capacityBytes change requested, skipping ONTAP resize"); + return; + } + long newCapacityBytes = Long.parseLong(strNewCapacityBytes); + + Map poolDetails = storagePoolDetailsDao.listDetailsKeyPairs(storagePool.getId()); + StorageStrategy storageStrategy = OntapStorageUtils.getStrategyByStoragePoolDetails(poolDetails); + logger.info("updateStoragePool: resizing ONTAP FlexVolume for pool '{}'", storagePool.getId()); + Volume volume = new Volume(); + volume.setUuid(poolDetails.get(OntapStorageConstants.VOLUME_UUID)); + volume.setName(poolDetails.get(OntapStorageConstants.VOLUME_NAME)); + try { + 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); + logger.info("updateStoragePool: Successfully resized ONTAP FlexVolume '{}' (UUID: {}) for pool '{}'", + volume.getName(), volume.getUuid(), storagePool.getName()); + } catch (Exception e) { + logger.error("updateStoragePool: Exception while resizing FlexVolume for pool: {}. Error: {}", + storagePool.getName(), e.getMessage(), e); + throw new CloudRuntimeException("Failed to resize ONTAP FlexVolume for pool: " + storagePool.getName() + ". " + e.getMessage(), e); + } } @Override diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/StorageStrategy.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/StorageStrategy.java index 0ef295418118..0e7dc9aebd5b 100644 --- a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/StorageStrategy.java +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/StorageStrategy.java @@ -367,11 +367,26 @@ public Volume createStorageVolume(String volumeName, Long size) { * @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) { + logger.info("Resizing ONTAP volume by name: " + volume.getName() + " and uuid: " + volume.getUuid()); + String authHeader = OntapStorageUtils.generateAuthHeader(storage.getUsername(), storage.getPassword()); + Volume resizeRequest = new Volume(); + resizeRequest.setSize(newSizeBytes); + 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()); + throw new CloudRuntimeException("resizeStorageVolume: resize job failed for FlexVolume: " + volume.getName()); + } + } catch (FeignException e) { + logger.error("Exception while resizing FlexVolume: " + volume.getName(), e); + throw new CloudRuntimeException("Failed to resize ONTAP FlexVolume: " + e.getMessage(), e); + } + logger.info("resizeStorageVolume: FlexVolume {} resized successfully to {} bytes", volume.getName(), newSizeBytes); + return volume; } - - /** + /** * Delete ONTAP Flex-Volume * Eligible only for Unified ONTAP storage * throw exception in case of disaggregated ONTAP storage diff --git a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java index b25da50d4d92..475bbd257e54 100644 --- a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java @@ -1289,7 +1289,6 @@ public PrimaryDataStoreInfo updateStoragePool(UpdateStoragePoolCmd cmd) throws I StoragePoolVO storagePool = _storagePoolDao.findById(id); DataStoreProvider dataStoreProvider = _dataStoreProviderMgr.getDataStoreProvider(storagePool.getStorageProviderName()); DataStoreLifeCycle dataStoreLifeCycle = dataStoreProvider.getDataStoreLifeCycle(); - if (dataStoreLifeCycle instanceof PrimaryDataStoreLifeCycle) { if (updatedCapacityBytes != null) { details.put(PrimaryDataStoreLifeCycle.CAPACITY_BYTES, updatedCapacityBytes != null ? String.valueOf(updatedCapacityBytes) : null); @@ -1302,6 +1301,7 @@ public PrimaryDataStoreInfo updateStoragePool(UpdateStoragePoolCmd cmd) throws I if (cmd.getUrl() != null) { details.put("url", cmd.getUrl()); } + ((PrimaryDataStoreLifeCycle)dataStoreLifeCycle).updateStoragePool(pool, details); _storagePoolDao.update(id, storagePool); _storagePoolDao.updateDetails(id, details); } From 0ab1f6838324985bda3ecff6313cebe83bafbdad Mon Sep 17 00:00:00 2001 From: sr73318 Date: Sat, 8 Aug 2026 11:23:07 +0530 Subject: [PATCH 2/5] CSTACKEX-234: resolving comments --- .../OntapPrimaryDatastoreLifecycle.java | 22 +++++-------------- .../storage/service/StorageStrategy.java | 7 +++--- .../com/cloud/storage/StorageManagerImpl.java | 13 +++++------ 3 files changed, 15 insertions(+), 27 deletions(-) diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java index 59852aa9bca9..5ed07b424695 100755 --- a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java @@ -526,34 +526,24 @@ public boolean migrateToObjectStore(DataStore store) { @Override public void updateStoragePool(StoragePool storagePool, Map details) { - StoragePoolVO poolVO = storagePoolDao.findById(storagePool.getId()); - if (poolVO == null) { - throw new CloudRuntimeException("updateStoragePool: storage pool not found: " + storagePool.getId()); - } - String strNewCapacityBytes = details.get(PrimaryDataStoreLifeCycle.CAPACITY_BYTES); - if (strNewCapacityBytes == null) { - logger.debug("updateStoragePool: no capacityBytes change requested, skipping ONTAP resize"); - return; - } - long newCapacityBytes = Long.parseLong(strNewCapacityBytes); - + long currentCapacityBytes = storagePool.getCapacityBytes(); + long newCapacityBytes = Long.parseLong(details.get(PrimaryDataStoreLifeCycle.CAPACITY_BYTES)); Map poolDetails = storagePoolDetailsDao.listDetailsKeyPairs(storagePool.getId()); StorageStrategy storageStrategy = OntapStorageUtils.getStrategyByStoragePoolDetails(poolDetails); - logger.info("updateStoragePool: resizing ONTAP FlexVolume for pool '{}'", storagePool.getId()); Volume volume = new Volume(); volume.setUuid(poolDetails.get(OntapStorageConstants.VOLUME_UUID)); volume.setName(poolDetails.get(OntapStorageConstants.VOLUME_NAME)); try { 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()); + logger.error("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); - logger.info("updateStoragePool: Successfully resized ONTAP FlexVolume '{}' (UUID: {}) for pool '{}'", - volume.getName(), volume.getUuid(), storagePool.getName()); + logger.info("Successfully resized ONTAP FlexVolume '{}' (UUID: {}) for pool '{}' from {} bytes to {} bytes", + volume.getName(), volume.getUuid(), storagePool.getName(), currentCapacityBytes, newCapacityBytes); } catch (Exception e) { - logger.error("updateStoragePool: Exception while resizing FlexVolume for pool: {}. Error: {}", + logger.error(" Exception while resizing FlexVolume for pool: {}. Error: {}", storagePool.getName(), e.getMessage(), e); throw new CloudRuntimeException("Failed to resize ONTAP FlexVolume for pool: " + storagePool.getName() + ". " + e.getMessage(), e); } diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/StorageStrategy.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/StorageStrategy.java index 0e7dc9aebd5b..cbb5c43d3779 100644 --- a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/StorageStrategy.java +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/StorageStrategy.java @@ -368,7 +368,6 @@ public Volume createStorageVolume(String volumeName, Long size) { * @return the updated Volume object */ public Volume updateStorageVolume(Volume volume, Long newSizeBytes) { - logger.info("Resizing ONTAP volume by name: " + volume.getName() + " and uuid: " + volume.getUuid()); String authHeader = OntapStorageUtils.generateAuthHeader(storage.getUsername(), storage.getPassword()); Volume resizeRequest = new Volume(); resizeRequest.setSize(newSizeBytes); @@ -376,14 +375,14 @@ public Volume updateStorageVolume(Volume volume, Long newSizeBytes) { 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()); - throw new CloudRuntimeException("resizeStorageVolume: resize job failed for FlexVolume: " + volume.getName()); + logger.error("resize job failed for FlexVolume: " + volume.getName()); + throw new CloudRuntimeException("resize job failed for FlexVolume: " + volume.getName()); } + logger.info("Volume is resized successfully for : " + volume.getName()); } catch (FeignException e) { logger.error("Exception while resizing FlexVolume: " + volume.getName(), e); throw new CloudRuntimeException("Failed to resize ONTAP FlexVolume: " + e.getMessage(), e); } - logger.info("resizeStorageVolume: FlexVolume {} resized successfully to {} bytes", volume.getName(), newSizeBytes); return volume; } /** diff --git a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java index 475bbd257e54..d4a0c0fe83f2 100644 --- a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java @@ -1286,23 +1286,22 @@ public PrimaryDataStoreInfo updateStoragePool(UpdateStoragePoolCmd cmd) throws I } if (changes) { - StoragePoolVO storagePool = _storagePoolDao.findById(id); - DataStoreProvider dataStoreProvider = _dataStoreProviderMgr.getDataStoreProvider(storagePool.getStorageProviderName()); + DataStoreProvider dataStoreProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName()); DataStoreLifeCycle dataStoreLifeCycle = dataStoreProvider.getDataStoreLifeCycle(); if (dataStoreLifeCycle instanceof PrimaryDataStoreLifeCycle) { if (updatedCapacityBytes != null) { - details.put(PrimaryDataStoreLifeCycle.CAPACITY_BYTES, updatedCapacityBytes != null ? String.valueOf(updatedCapacityBytes) : null); - _storagePoolDao.updateCapacityBytes(id, updatedCapacityBytes); + details.put(PrimaryDataStoreLifeCycle.CAPACITY_BYTES, String.valueOf(updatedCapacityBytes)); + pool.setCapacityBytes(updatedCapacityBytes); } if (updatedCapacityIops != null) { - details.put(PrimaryDataStoreLifeCycle.CAPACITY_IOPS, updatedCapacityIops != null ? String.valueOf(updatedCapacityIops) : null); - _storagePoolDao.updateCapacityIops(id, updatedCapacityIops); + details.put(PrimaryDataStoreLifeCycle.CAPACITY_IOPS, String.valueOf(updatedCapacityIops)); + pool.setCapacityIops(updatedCapacityIops); } if (cmd.getUrl() != null) { details.put("url", cmd.getUrl()); } ((PrimaryDataStoreLifeCycle)dataStoreLifeCycle).updateStoragePool(pool, details); - _storagePoolDao.update(id, storagePool); + _storagePoolDao.update(id, pool); _storagePoolDao.updateDetails(id, details); } } From b1f78c1f55dba9986af5e672b8b540c10326d23e Mon Sep 17 00:00:00 2001 From: sr73318 Date: Mon, 10 Aug 2026 10:33:03 +0530 Subject: [PATCH 3/5] CSTACKEX-234: using details parameter instead of fetching them from storage pool again in lifecycle --- .../storage/lifecycle/OntapPrimaryDatastoreLifecycle.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java index 5ed07b424695..bd238ee70515 100755 --- a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java @@ -528,12 +528,11 @@ public boolean migrateToObjectStore(DataStore store) { public void updateStoragePool(StoragePool storagePool, Map details) { long currentCapacityBytes = storagePool.getCapacityBytes(); long newCapacityBytes = Long.parseLong(details.get(PrimaryDataStoreLifeCycle.CAPACITY_BYTES)); - Map poolDetails = storagePoolDetailsDao.listDetailsKeyPairs(storagePool.getId()); - StorageStrategy storageStrategy = OntapStorageUtils.getStrategyByStoragePoolDetails(poolDetails); + StorageStrategy storageStrategy = OntapStorageUtils.getStrategyByStoragePoolDetails(details); Volume volume = new Volume(); - volume.setUuid(poolDetails.get(OntapStorageConstants.VOLUME_UUID)); - volume.setName(poolDetails.get(OntapStorageConstants.VOLUME_NAME)); + volume.setUuid(details.get(OntapStorageConstants.VOLUME_UUID)); + volume.setName(details.get(OntapStorageConstants.VOLUME_NAME)); try { if (volume.getUuid() == null || volume.getUuid().isEmpty() || volume.getName() == null || volume.getName().isEmpty()) { logger.error("Volume UUID/Name not found in details for pool: {}, cannot resize", storagePool.getName()); From 67913b02e84caecc2aba5117262e324ef94f56ca Mon Sep 17 00:00:00 2001 From: sr73318 Date: Mon, 10 Aug 2026 23:24:55 +0530 Subject: [PATCH 4/5] CSTACKEX-234: removing the storagemanagerimpl changes --- .../com/cloud/storage/StorageManagerImpl.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java index d4a0c0fe83f2..b25da50d4d92 100644 --- a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java @@ -1286,22 +1286,23 @@ public PrimaryDataStoreInfo updateStoragePool(UpdateStoragePoolCmd cmd) throws I } if (changes) { - DataStoreProvider dataStoreProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName()); + StoragePoolVO storagePool = _storagePoolDao.findById(id); + DataStoreProvider dataStoreProvider = _dataStoreProviderMgr.getDataStoreProvider(storagePool.getStorageProviderName()); DataStoreLifeCycle dataStoreLifeCycle = dataStoreProvider.getDataStoreLifeCycle(); + if (dataStoreLifeCycle instanceof PrimaryDataStoreLifeCycle) { if (updatedCapacityBytes != null) { - details.put(PrimaryDataStoreLifeCycle.CAPACITY_BYTES, String.valueOf(updatedCapacityBytes)); - pool.setCapacityBytes(updatedCapacityBytes); + details.put(PrimaryDataStoreLifeCycle.CAPACITY_BYTES, updatedCapacityBytes != null ? String.valueOf(updatedCapacityBytes) : null); + _storagePoolDao.updateCapacityBytes(id, updatedCapacityBytes); } if (updatedCapacityIops != null) { - details.put(PrimaryDataStoreLifeCycle.CAPACITY_IOPS, String.valueOf(updatedCapacityIops)); - pool.setCapacityIops(updatedCapacityIops); + details.put(PrimaryDataStoreLifeCycle.CAPACITY_IOPS, updatedCapacityIops != null ? String.valueOf(updatedCapacityIops) : null); + _storagePoolDao.updateCapacityIops(id, updatedCapacityIops); } if (cmd.getUrl() != null) { details.put("url", cmd.getUrl()); } - ((PrimaryDataStoreLifeCycle)dataStoreLifeCycle).updateStoragePool(pool, details); - _storagePoolDao.update(id, pool); + _storagePoolDao.update(id, storagePool); _storagePoolDao.updateDetails(id, details); } } From d68200e1cfeb59472f38b991a6a412091a64386e Mon Sep 17 00:00:00 2001 From: sr73318 Date: Thu, 13 Aug 2026 08:16:36 +0530 Subject: [PATCH 5/5] CSTACKEX-234: resolving comments --- .../feign/client/VolumeFeignClient.java | 2 +- .../OntapPrimaryDatastoreLifecycle.java | 26 +++++++++++------- .../storage/service/StorageStrategy.java | 27 ++++++++++--------- .../storage/service/UnifiedNASStrategy.java | 2 +- .../service/UnifiedNASStrategyTest.java | 8 +++--- 5 files changed, 38 insertions(+), 27 deletions(-) diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/feign/client/VolumeFeignClient.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/feign/client/VolumeFeignClient.java index 6384566487d4..8427f5ba7f67 100644 --- a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/feign/client/VolumeFeignClient.java +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/feign/client/VolumeFeignClient.java @@ -52,5 +52,5 @@ public interface VolumeFeignClient { @RequestLine("PATCH /api/storage/volumes/{uuid}") @Headers({ "Authorization: {authHeader}"}) - JobResponse updateVolumeRebalancing(@Param("authHeader") String authHeader, @Param("uuid") String uuid, Volume volumeRequest); + JobResponse updateVolume(@Param("authHeader") String authHeader, @Param("uuid") String uuid, Volume volumeRequest); } diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java index bd238ee70515..d20cdf1ee28a 100755 --- a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java @@ -526,24 +526,32 @@ public boolean migrateToObjectStore(DataStore store) { @Override public void updateStoragePool(StoragePool storagePool, Map details) { + String newCapacityStr = details.get(PrimaryDataStoreLifeCycle.CAPACITY_BYTES); + if (newCapacityStr == null) { + logger.debug("No capacity change requested for pool: {}, skipping FlexVolume resize", storagePool.getName()); + return; + } + long currentCapacityBytes = storagePool.getCapacityBytes(); - long newCapacityBytes = Long.parseLong(details.get(PrimaryDataStoreLifeCycle.CAPACITY_BYTES)); + long newCapacityBytes = Long.parseLong(newCapacityStr); StorageStrategy storageStrategy = OntapStorageUtils.getStrategyByStoragePoolDetails(details); + String volumeUuid = details.get(OntapStorageConstants.VOLUME_UUID); + if (volumeUuid == null || volumeUuid.isEmpty()) { + logger.error("Volume UUID or name not found in details for pool: {}, cannot resize", storagePool.getName()); + throw new CloudRuntimeException("Volume UUID or name not found in details, cannot resize ONTAP FlexVolume"); + } + Volume volume = new Volume(); - volume.setUuid(details.get(OntapStorageConstants.VOLUME_UUID)); + volume.setUuid(volumeUuid); volume.setName(details.get(OntapStorageConstants.VOLUME_NAME)); + volume.setSize(newCapacityBytes); try { - if (volume.getUuid() == null || volume.getUuid().isEmpty() || volume.getName() == null || volume.getName().isEmpty()) { - logger.error("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); + storageStrategy.updateStorageVolume(volume); logger.info("Successfully resized ONTAP FlexVolume '{}' (UUID: {}) for pool '{}' from {} bytes to {} bytes", volume.getName(), volume.getUuid(), storagePool.getName(), currentCapacityBytes, newCapacityBytes); } catch (Exception e) { - logger.error(" Exception while resizing FlexVolume for pool: {}. Error: {}", - storagePool.getName(), e.getMessage(), e); + logger.error("Exception while resizing FlexVolume for pool: {}. Error: {}", storagePool.getName(), e.getMessage(), e); throw new CloudRuntimeException("Failed to resize ONTAP FlexVolume for pool: " + storagePool.getName() + ". " + e.getMessage(), e); } } diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/StorageStrategy.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/StorageStrategy.java index cbb5c43d3779..9af89945f983 100644 --- a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/StorageStrategy.java +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/StorageStrategy.java @@ -367,25 +367,28 @@ public Volume createStorageVolume(String volumeName, Long size) { * @param volume the volume to update * @return the updated Volume object */ - public Volume updateStorageVolume(Volume volume, Long newSizeBytes) { + public Volume updateStorageVolume(Volume volume) { + logger.info("Resizing ONTAP FlexVolume '{}' (UUID: {}) to {} bytes", volume.getName(), volume.getUuid(), volume.getSize()); String authHeader = OntapStorageUtils.generateAuthHeader(storage.getUsername(), storage.getPassword()); - Volume resizeRequest = new Volume(); - resizeRequest.setSize(newSizeBytes); try { - JobResponse jobResponse = volumeFeignClient.updateVolumeRebalancing(authHeader, volume.getUuid(), resizeRequest); - Boolean jobSucceeded = jobPollForSuccess(jobResponse.getJob().getUuid(), 10, 1000); - if (!jobSucceeded) { - logger.error("resize job failed for FlexVolume: " + volume.getName()); - throw new CloudRuntimeException("resize job failed for FlexVolume: " + volume.getName()); - } - logger.info("Volume is resized successfully for : " + volume.getName()); + Volume resizeRequest = new Volume(); + resizeRequest.setSize(volume.getSize()); + JobResponse jobResponse = volumeFeignClient.updateVolume(authHeader, volume.getUuid(), resizeRequest); + pollJobIfPresent(jobResponse, "resize FlexVolume [" + volume.getUuid() + "]", 10, 1000); + logger.info("FlexVolume '{}' (UUID: {}) resized successfully to {} bytes", volume.getName(), volume.getUuid(), volume.getSize()); } catch (FeignException e) { - logger.error("Exception while resizing FlexVolume: " + volume.getName(), e); + if (OntapStorageUtils.isOntapObjectNotFoundError(e)) { + String msg = String.format("Cannot resize FlexVolume '%s' (UUID: %s): volume not found on ONTAP (404). ", volume.getName(), volume.getUuid()); + logger.error(msg); + throw new CloudRuntimeException(msg, e); + } + logger.error("Exception while resizing FlexVolume '{}' (UUID: {}): {}", volume.getName(), volume.getUuid(), e.getMessage(), e); throw new CloudRuntimeException("Failed to resize ONTAP FlexVolume: " + e.getMessage(), e); } return volume; } - /** + + /** * Delete ONTAP Flex-Volume * Eligible only for Unified ONTAP storage * throw exception in case of disaggregated ONTAP storage diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/UnifiedNASStrategy.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/UnifiedNASStrategy.java index 131d15bc6a38..0f55a742952d 100644 --- a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/UnifiedNASStrategy.java +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/UnifiedNASStrategy.java @@ -391,7 +391,7 @@ private void assignExportPolicyToVolume(String volumeUuid, String policyName) { volumeUpdate.setNas(nas); try { - JobResponse jobResponse = volumeFeignClient.updateVolumeRebalancing(authHeader, volumeUuid, volumeUpdate); + JobResponse jobResponse = volumeFeignClient.updateVolume(authHeader, volumeUuid, volumeUpdate); if (jobResponse == null || jobResponse.getJob() == null) { throw new CloudRuntimeException("Failed to attach policy " + policyName + "to volume " + volumeUuid); } diff --git a/plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/service/UnifiedNASStrategyTest.java b/plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/service/UnifiedNASStrategyTest.java index f0eb5f0ccced..60d20df8aae6 100755 --- a/plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/service/UnifiedNASStrategyTest.java +++ b/plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/service/UnifiedNASStrategyTest.java @@ -296,7 +296,7 @@ public void testCreateAccessGroup_Success() throws Exception { when(accessGroup.getHostsToConnect()).thenReturn(hosts); doNothing().when(nasFeignClient).createExportPolicy(anyString(), any(ExportPolicy.class)); when(nasFeignClient.getExportPolicyResponse(anyString(), anyMap())).thenReturn(policyResponse); - when(volumeFeignClient.updateVolumeRebalancing(anyString(), anyString(), any())).thenReturn(jobResponse); + when(volumeFeignClient.updateVolume(anyString(), anyString(), any())).thenReturn(jobResponse); when(jobFeignClient.getJobByUUID(anyString(), anyString())).thenReturn(job); doNothing().when(storagePoolDetailsDao).addDetail(anyLong(), anyString(), anyString(), eq(true)); @@ -307,7 +307,7 @@ public void testCreateAccessGroup_Success() throws Exception { assertNotNull(result); verify(nasFeignClient).createExportPolicy(anyString(), any(ExportPolicy.class)); verify(nasFeignClient).getExportPolicyResponse(anyString(), anyMap()); - verify(volumeFeignClient).updateVolumeRebalancing(anyString(), eq("vol-uuid-123"), any()); + verify(volumeFeignClient).updateVolume(anyString(), eq("vol-uuid-123"), any()); verify(storagePoolDetailsDao, times(2)).addDetail(anyLong(), anyString(), anyString(), eq(true)); } @@ -402,7 +402,7 @@ public void testCreateAccessGroup_JobFailure() throws Exception { when(accessGroup.getHostsToConnect()).thenReturn(hosts); doNothing().when(nasFeignClient).createExportPolicy(anyString(), any(ExportPolicy.class)); when(nasFeignClient.getExportPolicyResponse(anyString(), anyMap())).thenReturn(policyResponse); - when(volumeFeignClient.updateVolumeRebalancing(anyString(), anyString(), any())).thenReturn(jobResponse); + when(volumeFeignClient.updateVolume(anyString(), anyString(), any())).thenReturn(jobResponse); when(jobFeignClient.getJobByUUID(anyString(), anyString())).thenReturn(job); assertThrows(CloudRuntimeException.class, () -> { @@ -446,7 +446,7 @@ public void testCreateAccessGroup_HostWithPrivateIP() throws Exception { when(accessGroup.getHostsToConnect()).thenReturn(hosts); doNothing().when(nasFeignClient).createExportPolicy(anyString(), any(ExportPolicy.class)); when(nasFeignClient.getExportPolicyResponse(anyString(), anyMap())).thenReturn(policyResponse); - when(volumeFeignClient.updateVolumeRebalancing(anyString(), anyString(), any())).thenReturn(jobResponse); + when(volumeFeignClient.updateVolume(anyString(), anyString(), any())).thenReturn(jobResponse); when(jobFeignClient.getJobByUUID(anyString(), anyString())).thenReturn(job); doNothing().when(storagePoolDetailsDao).addDetail(anyLong(), anyString(), anyString(), eq(true));