This is an automated email from the ASF dual-hosted git repository. pearl11594 pushed a commit to branch 4.19 in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.19 by this push: new f4a7c8ab89a linstor: implement missing deleteDatastore (#10561) f4a7c8ab89a is described below commit f4a7c8ab89ac04aa70350f643f26c3280ff37c9e Author: Rene Peinthor <rene.peint...@linbit.com> AuthorDate: Tue Mar 18 13:50:19 2025 +0100 linstor: implement missing deleteDatastore (#10561) Somehow deleteDatastore was never implemented, that meant: templates haven't been cleaned up on datastore delete and also agents have never been informed about storage pool removal. --- .../BasePrimaryDataStoreLifeCycleImpl.java | 47 ++++++++++++++++++++++ plugins/storage/volume/linstor/CHANGELOG.md | 6 +++ .../LinstorPrimaryDataStoreLifeCycleImpl.java | 5 ++- .../ScaleIOPrimaryDataStoreLifeCycle.java | 39 ++---------------- 4 files changed, 61 insertions(+), 36 deletions(-) diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/BasePrimaryDataStoreLifeCycleImpl.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/BasePrimaryDataStoreLifeCycleImpl.java index adc74a77d43..021e49155d3 100644 --- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/BasePrimaryDataStoreLifeCycleImpl.java +++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/BasePrimaryDataStoreLifeCycleImpl.java @@ -22,8 +22,13 @@ import java.util.List; import javax.inject.Inject; +import com.cloud.storage.VMTemplateStoragePoolVO; +import com.cloud.storage.VMTemplateStorageResourceAssoc; +import com.cloud.template.TemplateManager; import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper; import org.apache.log4j.Logger; @@ -54,6 +59,10 @@ public class BasePrimaryDataStoreLifeCycleImpl { protected HostDao hostDao; @Inject protected StoragePoolHostDao storagePoolHostDao; + @Inject + private PrimaryDataStoreDao primaryDataStoreDao; + @Inject + private TemplateManager templateMgr; private List<HostVO> getPoolHostsList(ClusterScope clusterScope, HypervisorType hypervisorType) { List<HostVO> hosts; @@ -103,4 +112,42 @@ public class BasePrimaryDataStoreLifeCycleImpl { } dataStoreHelper.switchToCluster(store, clusterScope); } + + private void evictTemplates(StoragePoolVO storagePoolVO) { + List<VMTemplateStoragePoolVO> unusedTemplatesInPool = templateMgr.getUnusedTemplatesInPool(storagePoolVO); + for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) { + if (templatePoolVO.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + templateMgr.evictTemplateFromStoragePool(templatePoolVO); + } + } + } + + private void deleteAgentStoragePools(StoragePool storagePool) { + List<StoragePoolHostVO> poolHostVOs = storagePoolHostDao.listByPoolId(storagePool.getId()); + for (StoragePoolHostVO poolHostVO : poolHostVOs) { + DeleteStoragePoolCommand deleteStoragePoolCommand = new DeleteStoragePoolCommand(storagePool); + final Answer answer = agentMgr.easySend(poolHostVO.getHostId(), deleteStoragePoolCommand); + if (answer != null && answer.getResult()) { + s_logger.info("Successfully deleted storage pool: " + storagePool.getId() + " from host: " + poolHostVO.getHostId()); + } else { + if (answer != null) { + s_logger.error("Failed to delete storage pool: " + storagePool.getId() + " from host: " + poolHostVO.getHostId() + " , result: " + answer.getResult()); + } else { + s_logger.error("Failed to delete storage pool: " + storagePool.getId() + " from host: " + poolHostVO.getHostId()); + } + } + } + } + + protected boolean cleanupDatastore(DataStore store) { + StoragePool storagePool = (StoragePool)store; + StoragePoolVO storagePoolVO = primaryDataStoreDao.findById(storagePool.getId()); + if (storagePoolVO == null) { + return false; + } + + evictTemplates(storagePoolVO); + deleteAgentStoragePools(storagePool); + return true; + } } diff --git a/plugins/storage/volume/linstor/CHANGELOG.md b/plugins/storage/volume/linstor/CHANGELOG.md index e27e521bcd8..7e9d754b9f6 100644 --- a/plugins/storage/volume/linstor/CHANGELOG.md +++ b/plugins/storage/volume/linstor/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to Linstor CloudStack plugin will be documented in this file The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2025-03-13] + +### Fixed + +- Implemented missing delete datastore, to correctly cleanup on datastore removal + ## [2025-02-21] ### Fixed diff --git a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/LinstorPrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/LinstorPrimaryDataStoreLifeCycleImpl.java index 0ef97ae4796..cbe7b3f7d81 100644 --- a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/LinstorPrimaryDataStoreLifeCycleImpl.java +++ b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/LinstorPrimaryDataStoreLifeCycleImpl.java @@ -289,7 +289,10 @@ public class LinstorPrimaryDataStoreLifeCycleImpl extends BasePrimaryDataStoreLi @Override public boolean deleteDataStore(DataStore store) { - return dataStoreHelper.deletePrimaryDataStore(store); + if (cleanupDatastore(store)) { + return dataStoreHelper.deletePrimaryDataStore(store); + } + return false; } /* (non-Javadoc) diff --git a/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/ScaleIOPrimaryDataStoreLifeCycle.java b/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/ScaleIOPrimaryDataStoreLifeCycle.java index c1a7411d29f..7ddd41fb7b6 100644 --- a/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/ScaleIOPrimaryDataStoreLifeCycle.java +++ b/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/ScaleIOPrimaryDataStoreLifeCycle.java @@ -50,8 +50,6 @@ import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.StoragePoolInfo; import com.cloud.capacity.CapacityManager; import com.cloud.dc.ClusterVO; @@ -65,9 +63,6 @@ import com.cloud.storage.Storage; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolAutomation; -import com.cloud.storage.StoragePoolHostVO; -import com.cloud.storage.VMTemplateStoragePoolVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.template.TemplateManager; import com.cloud.utils.UriUtils; @@ -345,37 +340,11 @@ public class ScaleIOPrimaryDataStoreLifeCycle extends BasePrimaryDataStoreLifeCy @Override public boolean deleteDataStore(DataStore dataStore) { - StoragePool storagePool = (StoragePool)dataStore; - StoragePoolVO storagePoolVO = primaryDataStoreDao.findById(storagePool.getId()); - if (storagePoolVO == null) { - return false; - } - - List<VMTemplateStoragePoolVO> unusedTemplatesInPool = templateMgr.getUnusedTemplatesInPool(storagePoolVO); - for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) { - if (templatePoolVO.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - templateMgr.evictTemplateFromStoragePool(templatePoolVO); - } + if (cleanupDatastore(dataStore)) { + ScaleIOGatewayClientConnectionPool.getInstance().removeClient(dataStore.getId()); + return dataStoreHelper.deletePrimaryDataStore(dataStore); } - - List<StoragePoolHostVO> poolHostVOs = storagePoolHostDao.listByPoolId(dataStore.getId()); - for (StoragePoolHostVO poolHostVO : poolHostVOs) { - DeleteStoragePoolCommand deleteStoragePoolCommand = new DeleteStoragePoolCommand(storagePool); - final Answer answer = agentMgr.easySend(poolHostVO.getHostId(), deleteStoragePoolCommand); - if (answer != null && answer.getResult()) { - LOGGER.info("Successfully deleted storage pool: " + storagePool.getId() + " from host: " + poolHostVO.getHostId()); - } else { - if (answer != null) { - LOGGER.error("Failed to delete storage pool: " + storagePool.getId() + " from host: " + poolHostVO.getHostId() + " , result: " + answer.getResult()); - } else { - LOGGER.error("Failed to delete storage pool: " + storagePool.getId() + " from host: " + poolHostVO.getHostId()); - } - } - } - - ScaleIOGatewayClientConnectionPool.getInstance().removeClient(dataStore.getId()); - - return dataStoreHelper.deletePrimaryDataStore(dataStore); + return false; } @Override