Adding support for backend snapshots to Xenserver625StorageProcessor

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

Branch: refs/heads/statscollector-graphite
Commit: 18091e96429fee85f3677037e5f51768b5ba80b6
Parents: 94ee16a
Author: Mike Tutkowski <mike.tutkow...@solidfire.com>
Authored: Sat Nov 8 17:13:51 2014 -0700
Committer: Mike Tutkowski <mike.tutkow...@solidfire.com>
Committed: Mon Nov 10 22:41:00 2014 -0700

----------------------------------------------------------------------
 .../snapshot/StorageSystemSnapshotStrategy.java |   6 +-
 .../resource/Xenserver625StorageProcessor.java  | 113 +++++++++++++++++++
 2 files changed, 117 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/18091e96/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 2367825..c4946ab 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
@@ -219,9 +219,11 @@ public class StorageSystemSnapshotStrategy extends 
SnapshotStrategyBase {
 
             // if the VM is not associated with a host
             if (hostId == null) {
-                sourceDetails = getSourceDetails(volumeInfo);
-
                 hostId = vmInstanceVO.getLastHostId();
+
+                if (hostId == null) {
+                    sourceDetails = getSourceDetails(volumeInfo);
+                }
             }
         }
         // volume to snapshot is not associated with a VM (could be a data 
disk in the detached state)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/18091e96/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java
 
b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java
index 7e2a097..3529400 100644
--- 
a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java
+++ 
b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java
@@ -45,6 +45,7 @@ import com.cloud.agent.api.to.NfsTO;
 import com.cloud.agent.api.to.S3TO;
 import com.cloud.agent.api.to.SwiftTO;
 import com.cloud.exception.InternalErrorException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.storage.Storage;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.xensource.xenapi.Connection;
@@ -867,6 +868,11 @@ public class Xenserver625StorageProcessor extends 
XenServerStorageProcessor {
         Connection conn = hypervisorResource.getConnection();
         DataTO srcData = cmd.getSrcTO();
         DataTO destData = cmd.getDestTO();
+
+        if (srcData.getDataStore() instanceof PrimaryDataStoreTO && 
destData.getDataStore() instanceof NfsTO) {
+            return createTemplateFromSnapshot2(cmd);
+        }
+
         int wait = cmd.getWait();
         SnapshotObjectTO srcObj = (SnapshotObjectTO)srcData;
         TemplateObjectTO destObj = (TemplateObjectTO)destData;
@@ -964,4 +970,111 @@ public class Xenserver625StorageProcessor extends 
XenServerStorageProcessor {
         }
     }
 
+    public Answer createTemplateFromSnapshot2(CopyCommand cmd) {
+        Connection conn = hypervisorResource.getConnection();
+
+        SnapshotObjectTO snapshotObjTO = (SnapshotObjectTO)cmd.getSrcTO();
+        TemplateObjectTO templateObjTO = (TemplateObjectTO)cmd.getDestTO();
+
+        if (!(snapshotObjTO.getDataStore() instanceof PrimaryDataStoreTO) || 
!(templateObjTO.getDataStore() instanceof NfsTO)) {
+            return null;
+        }
+
+        NfsTO destStore = null;
+        URI destUri = null;
+
+        try {
+            destStore = (NfsTO)templateObjTO.getDataStore();
+
+            destUri = new URI(destStore.getUrl());
+        } catch (Exception ex) {
+            s_logger.debug("Invalid URI", ex);
+
+            return new CopyCmdAnswer("Invalid URI: " + ex.toString());
+        }
+
+        SR srcSr = null;
+        SR destSr = null;
+
+        String destDir = templateObjTO.getPath();
+        VDI destVdi = null;
+
+        boolean result = false;
+
+        try {
+            Map<String, String> srcDetails = cmd.getOptions();
+
+            String iScsiName = srcDetails.get(DiskTO.IQN);
+            String storageHost = srcDetails.get(DiskTO.STORAGE_HOST);
+            String chapInitiatorUsername = 
srcDetails.get(DiskTO.CHAP_INITIATOR_USERNAME);
+            String chapInitiatorSecret = 
srcDetails.get(DiskTO.CHAP_INITIATOR_SECRET);
+
+            srcSr = hypervisorResource.getIscsiSR(conn, iScsiName, 
storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, true);
+
+            String destNfsPath = destUri.getHost() + ":" + destUri.getPath();
+            String localDir = "/var/cloud_mount/" + 
UUID.nameUUIDFromBytes(destNfsPath.getBytes());
+
+            mountNfs(conn, destUri.getHost() + ":" + destUri.getPath(), 
localDir);
+            makeDirectory(conn, localDir + "/" + destDir);
+
+            destSr = createFileSR(conn, localDir + "/" + destDir);
+
+            // there should only be one VDI in this SR
+            VDI srcVdi = srcSr.getVDIs(conn).iterator().next();
+
+            destVdi = srcVdi.copy(conn, destSr);
+
+            String nameLabel = "cloud-" + UUID.randomUUID().toString();
+
+            destVdi.setNameLabel(conn, nameLabel);
+
+            // scan makes XenServer pick up VDI physicalSize
+            destSr.scan(conn);
+
+            String templateUuid = destVdi.getUuid(conn);
+            String templateFilename = templateUuid + ".vhd";
+            long virtualSize = destVdi.getVirtualSize(conn);
+            long physicalSize = destVdi.getPhysicalUtilisation(conn);
+
+            // create the template.properties file
+            String templatePath = destNfsPath + "/" + destDir;
+
+            templatePath = templatePath.replaceAll("//", "/");
+
+            TemplateObjectTO newTemplate = new TemplateObjectTO();
+
+            newTemplate.setPath(destDir + "/" + templateFilename);
+            newTemplate.setFormat(Storage.ImageFormat.VHD);
+            newTemplate.setHypervisorType(HypervisorType.XenServer);
+            newTemplate.setSize(virtualSize);
+            newTemplate.setPhysicalSize(physicalSize);
+            newTemplate.setName(templateUuid);
+
+            result = true;
+
+            return new CopyCmdAnswer(newTemplate);
+        } catch (Exception ex) {
+            s_logger.error("Failed to create a template from a snapshot", ex);
+
+            return new CopyCmdAnswer("Failed to create a template from a 
snapshot: " + ex.toString());
+        } finally {
+            if (!result) {
+                if (destVdi != null) {
+                    try {
+                        destVdi.destroy(conn);
+                    } catch (Exception e) {
+                        s_logger.debug("Cleaned up leftover VDI on destination 
storage due to failure: ", e);
+                    }
+                }
+            }
+
+            if (srcSr != null) {
+                hypervisorResource.removeSR(conn, srcSr);
+            }
+
+            if (destSr != null) {
+                hypervisorResource.removeSR(conn, destSr);
+            }
+        }
+    }
 }

Reply via email to