From 45d38c41422938f6ad21fe26484bce3fd49f8656 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 25 Jul 2013 17:33:28 -0700 Subject: [PATCH] CLOUDSTACK-3709:[Object_Store_Refactor][UI] Can't delete NFS Cache storage through UI. Fixed at API side. Conflicts: server/src/com/cloud/storage/StorageManagerImpl.java --- api/src/com/cloud/storage/StorageService.java | 5 +- client/tomcatconf/commands.properties.in | 1 + .../datastore/db/SnapshotDataStoreDao.java | 6 +- .../datastore/db/TemplateDataStoreDao.java | 4 +- .../datastore/db/VolumeDataStoreDao.java | 4 +- .../image/db/SnapshotDataStoreDaoImpl.java | 44 ++++++-- .../image/db/TemplateDataStoreDaoImpl.java | 35 ++++-- .../image/db/VolumeDataStoreDaoImpl.java | 33 ++++-- .../cloud/server/ManagementServerImpl.java | 106 +++++++++--------- .../com/cloud/storage/StorageManagerImpl.java | 64 +++++++++-- 10 files changed, 209 insertions(+), 93 deletions(-) diff --git a/api/src/com/cloud/storage/StorageService.java b/api/src/com/cloud/storage/StorageService.java index 869b2960e1c..7c5b0a786c3 100644 --- a/api/src/com/cloud/storage/StorageService.java +++ b/api/src/com/cloud/storage/StorageService.java @@ -22,6 +22,7 @@ import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd; import org.apache.cloudstack.api.command.admin.storage.CreateCacheStoreCmd; import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd; +import org.apache.cloudstack.api.command.admin.storage.DeleteCacheStoreCmd; import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd; import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd; @@ -48,7 +49,7 @@ public interface StorageService{ */ StoragePool createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException, ResourceUnavailableException; - + ImageStore createCacheStore(CreateCacheStoreCmd cmd); /** @@ -92,6 +93,8 @@ public interface StorageService{ boolean deleteImageStore(DeleteImageStoreCmd cmd); + boolean deleteCacheStore(DeleteCacheStoreCmd cmd); + ImageStore discoverImageStore(AddImageStoreCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException; } diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index e8012136b41..5451ed83190 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -252,6 +252,7 @@ listImageStores=1 deleteImageStore=1 createCacheStore=1 listCacheStores=1 +deleteCacheStore=1 #### host commands addHost=3 diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java index d129fe7f827..f9037150c93 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java @@ -26,11 +26,13 @@ import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateDao; public interface SnapshotDataStoreDao extends GenericDao, - StateDao { +StateDao { List listByStoreId(long id, DataStoreRole role); - void deletePrimaryRecordsForStore(long id); + List listActiveOnCache(long id); + + void deletePrimaryRecordsForStore(long id, DataStoreRole role); SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long storeId, long snapshotId); SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long volumeId); diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java index 13b84ff3dba..9350751ec63 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java @@ -28,12 +28,14 @@ import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateDao; public interface TemplateDataStoreDao extends GenericDao, - StateDao { +StateDao { List listByStoreId(long id); List listDestroyed(long storeId); + List listActiveOnCache(long id); + void deletePrimaryRecordsForStore(long id); void deletePrimaryRecordsForTemplate(long templateId); diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java index 4152516bcf0..698465fd726 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java @@ -25,10 +25,12 @@ import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateDao; public interface VolumeDataStoreDao extends GenericDao, - StateDao { +StateDao { List listByStoreId(long id); + List listActiveOnCache(long id); + void deletePrimaryRecordsForStore(long id); VolumeDataStoreVO findByVolume(long volumeId); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java index f5e7421dea0..f33d51aebe7 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java @@ -48,12 +48,13 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase updateStateSearch; private SearchBuilder storeSearch; private SearchBuilder destroyedSearch; + private SearchBuilder cacheSearch; private SearchBuilder snapshotSearch; private SearchBuilder storeSnapshotSearch; private String parentSearch = "select store_id, store_role, snapshot_id from cloud.snapshot_store_ref where store_id = ? " + - " and store_role = ? and volume_id = ? and state = 'Ready'" + - " order by created DESC " + - " limit 1"; + " and store_role = ? and volume_id = ? and state = 'Ready'" + + " order by created DESC " + + " limit 1"; @@ -61,6 +62,9 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase params) throws ConfigurationException { super.configure(name, params); + // Note that snapshot_store_ref stores snapshots on primary as well as + // those on secondary, so we need to + // use (store_id, store_role) to search storeSearch = createSearchBuilder(); storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); storeSearch.and("store_role", storeSearch.entity().getRole(), SearchCriteria.Op.EQ); @@ -72,6 +76,13 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase sc = storeSearch.create(); sc.setParameters("store_id", id); + sc.setParameters("store_role", role); Transaction txn = Transaction.currentTxn(); txn.start(); remove(sc); @@ -176,7 +188,7 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase listActiveOnCache(long id) { + SearchCriteria sc = cacheSearch.create(); + sc.setParameters("store_id", id); + sc.setParameters("store_role", DataStoreRole.ImageCache); + sc.setParameters("state", ObjectInDataStoreStateMachine.State.Destroyed); + sc.setParameters("ref_cnt", 0); + return listBy(sc); + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java index 362f7a6aa96..7388ca99ec1 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java @@ -51,6 +51,7 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase updateStateSearch; private SearchBuilder storeSearch; + private SearchBuilder cacheSearch; private SearchBuilder templateSearch; private SearchBuilder templateRoleSearch; private SearchBuilder storeTemplateSearch; @@ -69,6 +70,12 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase listActiveOnCache(long id) { + SearchCriteria sc = cacheSearch.create(); + sc.setParameters("store_id", id); + sc.setParameters("destroyed", false); + sc.setParameters("ref_cnt", 0); + return listIncludingRemovedBy(sc); + } + + @Override public void deletePrimaryRecordsForStore(long id) { SearchCriteria sc = storeSearch.create(); @@ -279,10 +297,11 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase updateStateSearch; private SearchBuilder volumeSearch; private SearchBuilder storeSearch; + private SearchBuilder cacheSearch; private SearchBuilder storeVolumeSearch; @Override @@ -54,6 +55,12 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase listActiveOnCache(long id) { + SearchCriteria sc = cacheSearch.create(); + sc.setParameters("store_id", id); + sc.setParameters("destroyed", false); + sc.setParameters("ref_cnt", 0); + return listIncludingRemovedBy(sc); + } + @Override public void deletePrimaryRecordsForStore(long id) { SearchCriteria sc = storeSearch.create(); @@ -156,10 +172,11 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase getUserAuthenticators() { - return _userAuthenticators; + return _userAuthenticators; } public void setUserAuthenticators(List authenticators) { - _userAuthenticators = authenticators; + _userAuthenticators = authenticators; } public List getUserPasswordEncoders() { @@ -781,18 +782,18 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe } public List getHostAllocators() { - return _hostAllocators; - } + return _hostAllocators; + } - public void setHostAllocators(List _hostAllocators) { - this._hostAllocators = _hostAllocators; - } + public void setHostAllocators(List _hostAllocators) { + this._hostAllocators = _hostAllocators; + } - @Override - public boolean configure(String name, Map params) - throws ConfigurationException { + @Override + public boolean configure(String name, Map params) + throws ConfigurationException { - _configs = _configDao.getConfiguration(); + _configs = _configDao.getConfiguration(); String value = _configs.get("event.purge.interval"); int cleanup = NumbersUtil.parseInt(value, 60 * 60 * 24); // 1 day. @@ -817,10 +818,10 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe _availableIdsMap.put(id, true); } - return true; - } + return true; + } - @Override + @Override public boolean start() { s_logger.info("Startup CloudStack management server..."); @@ -922,7 +923,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return result; } for (EventVO event : events) { - _eventDao.remove(event.getId()); + _eventDao.remove(event.getId()); } return result; } @@ -952,7 +953,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Override public Pair, Integer> searchForClusters(ListClustersCmd cmd) { - Object id = cmd.getId(); + Object id = cmd.getId(); Object name = cmd.getClusterName(); Object podId = cmd.getPodId(); Long zoneId = cmd.getZoneId(); @@ -963,7 +964,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId); - Filter searchFilter = new Filter(ClusterVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); + Filter searchFilter = new Filter(ClusterVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _clusterDao.createSearchBuilder(); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); @@ -1035,7 +1036,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Override public Ternary, Integer>, List, Map> - listHostsForMigrationOfVM(Long vmId, Long startIndex, Long pageSize) { + listHostsForMigrationOfVM(Long vmId, Long startIndex, Long pageSize) { // access check - only root admin can migrate VM Account caller = CallContext.current().getCallingAccount(); if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { @@ -1426,7 +1427,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId); - Filter searchFilter = new Filter(HostPodVO.class, "dataCenterId", true, cmd.getStartIndex(), cmd.getPageSizeVal()); + Filter searchFilter = new Filter(HostPodVO.class, "dataCenterId", true, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _hostPodDao.createSearchBuilder(); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); @@ -1768,7 +1769,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return templateZonePairSet; } -*/ + */ private VMTemplateVO updateTemplateOrIso(BaseUpdateTemplateOrIsoCmd cmd) { Long id = cmd.getId(); @@ -2814,6 +2815,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe cmdList.add(DeleteImageStoreCmd.class); cmdList.add(CreateCacheStoreCmd.class); cmdList.add(ListCacheStoresCmd.class); + cmdList.add(DeleteCacheStoreCmd.class); cmdList.add(CreateApplicationLoadBalancerCmd.class); cmdList.add(ListApplicationLoadBalancersCmd.class); cmdList.add(DeleteApplicationLoadBalancerCmd.class); @@ -3231,8 +3233,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe elasticLoadBalancerEnabled = elbEnabled == null ? false : Boolean.parseBoolean(elbEnabled); if (elasticLoadBalancerEnabled) { String networkType = _configDao.getValue(Config.ElasticLoadBalancerNetwork.key()); - if (networkType != null) + if (networkType != null) { supportELB = networkType; + } } } @@ -3338,10 +3341,12 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe String certificate = cmd.getCertificate(); String key = cmd.getPrivateKey(); try { - if (certificate != null) + if (certificate != null) { certificate = URLDecoder.decode(certificate, "UTF-8"); - if (key != null) + } + if (key != null) { key = URLDecoder.decode(key, "UTF-8"); + } } catch (UnsupportedEncodingException e) { } finally { } @@ -3358,8 +3363,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe _consoleProxyMgr.setManagementState(ConsoleProxyManagementState.ResetSuspending); List alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(null, State.Running, State.Migrating, State.Starting); - for (SecondaryStorageVmVO ssVmVm : alreadyRunning) + for (SecondaryStorageVmVO ssVmVm : alreadyRunning) { _secStorageVmMgr.rebootSecStorageVm(ssVmVm.getId()); + } return "Certificate has been updated, we will stop all running console proxy VMs and secondary storage VMs to propagate the new certificate, please give a few minutes for console access service to be up again"; } @@ -3404,7 +3410,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe // give us the same key if (_hashKey == null) { _hashKey = _configDao.getValueAndInitIfNotExist(Config.HashKey.key(), Config.HashKey.getCategory(), - getBase64EncodedRandomKey(128)); + getBase64EncodedRandomKey(128)); } return _hashKey; } @@ -3413,8 +3419,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe public String getEncryptionKey() { if (_encryptionKey == null) { _encryptionKey = _configDao.getValueAndInitIfNotExist(Config.EncryptionKey.key(), - Config.EncryptionKey.getCategory(), - getBase64EncodedRandomKey(128)); + Config.EncryptionKey.getCategory(), + getBase64EncodedRandomKey(128)); } return _encryptionKey; } @@ -3423,8 +3429,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe public String getEncryptionIV() { if (_encryptionIV == null) { _encryptionIV = _configDao.getValueAndInitIfNotExist(Config.EncryptionIV.key(), - Config.EncryptionIV.getCategory(), - getBase64EncodedRandomKey(128)); + Config.EncryptionIV.getCategory(), + getBase64EncodedRandomKey(128)); } return _encryptionIV; } @@ -3433,18 +3439,18 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @DB public void resetEncryptionKeyIV() { - SearchBuilder sb = _configDao.createSearchBuilder(); - sb.and("name1", sb.entity().getName(), SearchCriteria.Op.EQ); - sb.or("name2", sb.entity().getName(), SearchCriteria.Op.EQ); - sb.done(); + SearchBuilder sb = _configDao.createSearchBuilder(); + sb.and("name1", sb.entity().getName(), SearchCriteria.Op.EQ); + sb.or("name2", sb.entity().getName(), SearchCriteria.Op.EQ); + sb.done(); - SearchCriteria sc = sb.create(); - sc.setParameters("name1", Config.EncryptionKey.key()); - sc.setParameters("name2", Config.EncryptionIV.key()); + SearchCriteria sc = sb.create(); + sc.setParameters("name1", Config.EncryptionKey.key()); + sc.setParameters("name2", Config.EncryptionIV.key()); - _configDao.expunge(sc); - _encryptionKey = null; - _encryptionIV = null; + _configDao.expunge(sc); + _encryptionKey = null; + _encryptionIV = null; } @Override @@ -3453,16 +3459,16 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe } private static String getBase64EncodedRandomKey(int nBits) { - SecureRandom random; - try { - random = SecureRandom.getInstance("SHA1PRNG"); - byte[] keyBytes = new byte[nBits/8]; - random.nextBytes(keyBytes); - return Base64.encodeBase64URLSafeString(keyBytes); - } catch (NoSuchAlgorithmException e) { - s_logger.error("Unhandled exception: ", e); - } - return null; + SecureRandom random; + try { + random = SecureRandom.getInstance("SHA1PRNG"); + byte[] keyBytes = new byte[nBits/8]; + random.nextBytes(keyBytes); + return Base64.encodeBase64URLSafeString(keyBytes); + } catch (NoSuchAlgorithmException e) { + s_logger.error("Unhandled exception: ", e); + } + return null; } @Override diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 40117512457..25aee8c6b93 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -48,6 +48,7 @@ import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd; import org.apache.cloudstack.api.command.admin.storage.CreateCacheStoreCmd; import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd; +import org.apache.cloudstack.api.command.admin.storage.DeleteCacheStoreCmd; import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd; import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd; @@ -401,8 +402,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Override public StoragePool findStoragePool(DiskProfile dskCh, final DataCenterVO dc, Pod pod, Long clusterId, Long hostId, VMInstanceVO vm, - final Set avoid) { - + final Set avoid) { VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); for (StoragePoolAllocator allocator : _storagePoolAllocators) { @@ -638,7 +638,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Override @SuppressWarnings("rawtypes") public PrimaryDataStoreInfo createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException, - ResourceUnavailableException { + ResourceUnavailableException { String providerName = cmd.getStorageProviderName(); DataStoreProvider storeProvider = dataStoreProviderMgr.getDataStoreProvider(providerName); @@ -1194,7 +1194,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Override @DB public PrimaryDataStoreInfo preparePrimaryStorageForMaintenance(Long primaryStorageId) throws ResourceUnavailableException, - InsufficientCapacityException { + InsufficientCapacityException { Long userId = CallContext.current().getCallingUserId(); User user = _userDao.findById(userId); Account account = CallContext.current().getCallingAccount(); @@ -1288,8 +1288,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C // check if pool is in an inconsistent state if (pool != null && (pool.getStatus().equals(StoragePoolStatus.ErrorInMaintenance) - || pool.getStatus().equals(StoragePoolStatus.PrepareForMaintenance) || pool.getStatus().equals( - StoragePoolStatus.CancelMaintenance))) { + || pool.getStatus().equals(StoragePoolStatus.PrepareForMaintenance) || pool.getStatus().equals( + StoragePoolStatus.CancelMaintenance))) { _storagePoolWorkDao.removePendingJobsOnMsRestart(vo.getMsid(), poolId); pool.setStatus(StoragePoolStatus.ErrorInMaintenance); _storagePoolDao.update(poolId, pool); @@ -1501,7 +1501,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Override public boolean storagePoolHasEnoughIops(List requestedVolumes, - StoragePool pool) { + StoragePool pool) { if (requestedVolumes == null || requestedVolumes.isEmpty() || pool == null) { return false; } @@ -1533,19 +1533,19 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } long futureIops = currentIops + requestedIops; - + // getCapacityIops returns a Long so we need to check for null if (pool.getCapacityIops() == null) { s_logger.warn("Storage pool " + pool.getName() + " (" + pool.getId() + ") does not supply Iops capacity, assuming enough capacity"); return true; } - + return futureIops <= pool.getCapacityIops(); } @Override public boolean storagePoolHasEnoughSpace(List volumes, - StoragePool pool) { + StoragePool pool) { if (volumes == null || volumes.isEmpty()){ return false; } @@ -1788,7 +1788,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C // we are not actually deleting record from main // image_data_store table, so delete cascade will not work _imageStoreDetailsDao.deleteDetails(storeId); - _snapshotStoreDao.deletePrimaryRecordsForStore(storeId); + _snapshotStoreDao.deletePrimaryRecordsForStore(storeId, DataStoreRole.Image); _volumeStoreDao.deletePrimaryRecordsForStore(storeId); _templateStoreDao.deletePrimaryRecordsForStore(storeId); _imageStoreDao.remove(storeId); @@ -1864,6 +1864,48 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.ImageCache); } + @Override + public boolean deleteCacheStore(DeleteCacheStoreCmd cmd) { + long storeId = cmd.getId(); + User caller = _accountMgr.getActiveUser(CallContext.current().getCallingUserId()); + // Verify that cache store exists + ImageStoreVO store = _imageStoreDao.findById(storeId); + if (store == null) { + throw new InvalidParameterValueException("Cache store with id " + storeId + " doesn't exist"); + } + _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), store.getDataCenterId()); + + // Verify that there are no live snapshot, template, volume on the cache + // store that is currently referenced + List snapshots = _snapshotStoreDao.listActiveOnCache(storeId); + if (snapshots != null && snapshots.size() > 0) { + throw new InvalidParameterValueException("Cannot delete cache store with staging snapshots currently in use!"); + } + List volumes = _volumeStoreDao.listActiveOnCache(storeId); + if (volumes != null && volumes.size() > 0) { + throw new InvalidParameterValueException("Cannot delete cache store with staging volumes currently in use!"); + } + + List templates = this._templateStoreDao.listActiveOnCache(storeId); + if (templates != null && templates.size() > 0) { + throw new InvalidParameterValueException("Cannot delete cache store with staging templates currently in use!"); + } + + // ready to delete + Transaction txn = Transaction.currentTxn(); + txn.start(); + // first delete from image_store_details table, we need to do that since + // we are not actually deleting record from main + // image_data_store table, so delete cascade will not work + _imageStoreDetailsDao.deleteDetails(storeId); + _snapshotStoreDao.deletePrimaryRecordsForStore(storeId, DataStoreRole.ImageCache); + _volumeStoreDao.deletePrimaryRecordsForStore(storeId); + _templateStoreDao.deletePrimaryRecordsForStore(storeId); + _imageStoreDao.remove(storeId); + txn.commit(); + return true; + } + // get bytesReadRate from service_offering, disk_offering and vm.disk.throttling.bytes_read_rate @Override public Long getDiskBytesReadRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering) {