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.
This commit is contained in:
Rene Peinthor 2025-03-18 13:50:19 +01:00 committed by GitHub
parent 7978141464
commit f4a7c8ab89
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 61 additions and 36 deletions

View File

@ -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;
}
}

View File

@ -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

View File

@ -289,8 +289,11 @@ public class LinstorPrimaryDataStoreLifeCycleImpl extends BasePrimaryDataStoreLi
@Override
public boolean deleteDataStore(DataStore store) {
if (cleanupDatastore(store)) {
return dataStoreHelper.deletePrimaryDataStore(store);
}
return false;
}
/* (non-Javadoc)
* @see org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle#migrateToObjectStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore)

View File

@ -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,38 +340,12 @@ 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);
}
}
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());
}
}
}
if (cleanupDatastore(dataStore)) {
ScaleIOGatewayClientConnectionPool.getInstance().removeClient(dataStore.getId());
return dataStoreHelper.deletePrimaryDataStore(dataStore);
}
return false;
}
@Override
public boolean migrateToObjectStore(DataStore store) {