Handle the case where the volume a snapshot was created from is removed from 
the database


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/ebb96f5e
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/ebb96f5e
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/ebb96f5e

Branch: refs/heads/statscollector-graphite
Commit: ebb96f5e2f533802107492e5e7741786d6266a3b
Parents: 05bec59
Author: Mike Tutkowski <mike.tutkow...@solidfire.com>
Authored: Thu Nov 6 17:43:07 2014 -0700
Committer: Mike Tutkowski <mike.tutkow...@solidfire.com>
Committed: Thu Nov 6 19:44:46 2014 -0700

----------------------------------------------------------------------
 .../snapshot/StorageSystemSnapshotStrategy.java | 20 +++++++++-
 server/src/com/cloud/api/ApiResponseHelper.java | 42 +++++++++++++++++---
 .../com/cloud/template/TemplateManagerImpl.java | 13 ++++--
 3 files changed, 66 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ebb96f5e/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java
 
b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java
index 9a6c51b..2367825 100644
--- 
a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java
+++ 
b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java
@@ -37,6 +37,8 @@ import 
org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
 import org.apache.cloudstack.storage.command.SnapshotAndCopyAnswer;
 import org.apache.cloudstack.storage.command.SnapshotAndCopyCommand;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 
 import com.cloud.agent.AgentManager;
@@ -76,6 +78,7 @@ public class StorageSystemSnapshotStrategy extends 
SnapshotStrategyBase {
     @Inject private PrimaryDataStoreDao _storagePoolDao;
     @Inject private SnapshotDao _snapshotDao;
     @Inject private SnapshotDataFactory _snapshotDataFactory;
+    @Inject private SnapshotDataStoreDao _snapshotStoreDao;
     @Inject private SnapshotDetailsDao _snapshotDetailsDao;
     @Inject private VMInstanceDao _vmInstanceDao;
     @Inject private VolumeDao _volumeDao;
@@ -400,7 +403,22 @@ public class StorageSystemSnapshotStrategy extends 
SnapshotStrategyBase {
         long volumeId = snapshot.getVolumeId();
         VolumeVO volumeVO = _volumeDao.findById(volumeId);
 
-        long storagePoolId = volumeVO.getPoolId();
+        long storagePoolId;
+
+        if (volumeVO == null) {
+            SnapshotDataStoreVO snapshotStore = 
_snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Primary);
+
+            if (snapshotStore != null) {
+                storagePoolId = snapshotStore.getDataStoreId();
+            }
+            else {
+                throw new CloudRuntimeException("Unable to determine the 
storage pool of the snapshot");
+            }
+        }
+        else {
+            storagePoolId = volumeVO.getPoolId();
+        }
+
         DataStore dataStore = _dataStoreMgr.getDataStore(storagePoolId, 
DataStoreRole.Primary);
 
         Map<String, String> mapCapabilities = 
dataStore.getDriver().getCapabilities();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ebb96f5e/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java 
b/server/src/com/cloud/api/ApiResponseHelper.java
index 4c22127..8172987 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -149,8 +149,10 @@ import 
org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
 import org.apache.cloudstack.region.PortableIp;
 import org.apache.cloudstack.region.PortableIpRange;
 import org.apache.cloudstack.region.Region;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.cloudstack.usage.Usage;
 import org.apache.cloudstack.usage.UsageService;
 import org.apache.cloudstack.usage.UsageTypes;
@@ -295,6 +297,7 @@ import com.cloud.uservm.UserVm;
 import com.cloud.utils.Pair;
 import com.cloud.utils.StringUtils;
 import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.net.Ip;
 import com.cloud.utils.net.NetUtils;
 import com.cloud.vm.ConsoleProxyVO;
@@ -333,7 +336,9 @@ public class ApiResponseHelper implements ResponseGenerator 
{
     @Inject
     private DataStoreManager _dataStoreMgr;
     @Inject
-    SnapshotDataStoreDao _snapshotStoreDao;
+    private SnapshotDataStoreDao _snapshotStoreDao;
+    @Inject
+    private PrimaryDataStoreDao _storagePoolDao;
 
     @Override
     public UserResponse createUserResponse(User user) {
@@ -1447,14 +1452,41 @@ public class ApiResponseHelper implements 
ResponseGenerator {
 
     @Override
     public List<TemplateResponse> createTemplateResponses(ResponseView view, 
long templateId, Long snapshotId, Long volumeId, boolean readyOnly) {
-        VolumeVO volume = null;
+        Long zoneId = null;
+
         if (snapshotId != null) {
             Snapshot snapshot = ApiDBUtils.findSnapshotById(snapshotId);
-            volume = findVolumeById(snapshot.getVolumeId());
+            VolumeVO volume = findVolumeById(snapshot.getVolumeId());
+
+            // it seems that the volume can actually be removed from the DB at 
some point if it's deleted
+            // if volume comes back null, use another technique to try to 
discover the zone
+            if (volume == null) {
+                SnapshotDataStoreVO snapshotStore = 
_snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Primary);
+
+                if (snapshotStore != null) {
+                    long storagePoolId = snapshotStore.getDataStoreId();
+
+                    StoragePoolVO storagePool = 
_storagePoolDao.findById(storagePoolId);
+
+                    if (storagePool != null) {
+                        zoneId = storagePool.getDataCenterId();
+                    }
+                }
+            }
+            else {
+                zoneId = volume.getDataCenterId();
+            }
         } else {
-            volume = findVolumeById(volumeId);
+            VolumeVO volume = findVolumeById(volumeId);
+
+            zoneId = volume.getDataCenterId();
         }
-        return createTemplateResponses(view, templateId, 
volume.getDataCenterId(), readyOnly);
+
+        if (zoneId == null) {
+            throw new CloudRuntimeException("Unable to determine the zone ID");
+        }
+
+        return createTemplateResponses(view, templateId, zoneId, readyOnly);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ebb96f5e/server/src/com/cloud/template/TemplateManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java 
b/server/src/com/cloud/template/TemplateManagerImpl.java
index e495eb9..da3940c 100755
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@ -80,6 +80,8 @@ import org.apache.cloudstack.storage.command.AttachCommand;
 import org.apache.cloudstack.storage.command.CommandResult;
 import org.apache.cloudstack.storage.command.DettachCommand;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
@@ -245,6 +247,8 @@ public class TemplateManagerImpl extends ManagerBase 
implements TemplateManager,
     private EndPointSelector _epSelector;
     @Inject
     private UserVmJoinDao _userVmJoinDao;
+    @Inject
+    private SnapshotDataStoreDao _snapshotStoreDao;
 
     @Inject
     MessageBus _messageBus;
@@ -1470,10 +1474,13 @@ public class TemplateManagerImpl extends ManagerBase 
implements TemplateManager,
     }
 
     private DataStoreRole getDataStoreRole(Snapshot snapshot) {
-        long volumeId = snapshot.getVolumeId();
-        VolumeVO volumeVO = _volumeDao.findById(volumeId);
+        SnapshotDataStoreVO snapshotStore = 
_snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Primary);
+
+        if (snapshotStore == null) {
+            return DataStoreRole.Image;
+        }
 
-        long storagePoolId = volumeVO.getPoolId();
+        long storagePoolId = snapshotStore.getDataStoreId();
         DataStore dataStore = _dataStoreMgr.getDataStore(storagePoolId, 
DataStoreRole.Primary);
 
         Map<String, String> mapCapabilities = 
dataStore.getDriver().getCapabilities();

Reply via email to