basical stuff works

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

Branch: refs/heads/4.2-workplace
Commit: e8a87bbf05a7d863e9406e3472eb9768ef187fa1
Parents: 4cd6f31
Author: Edison Su <[email protected]>
Authored: Tue Dec 10 17:16:51 2013 -0800
Committer: Edison Su <[email protected]>
Committed: Tue Dec 10 17:16:51 2013 -0800

----------------------------------------------------------------------
 .../xen/resource/XenServer620Resource.java      |   8 +
 .../xen/resource/XenServerStorageProcessor.java |   9 +-
 .../resource/Xenserver620StorageProcessor.java  | 636 +++++++++++++++++++
 3 files changed, 649 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e8a87bbf/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer620Resource.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer620Resource.java
 
b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer620Resource.java
index 0d6e159..e623aca 100644
--- 
a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer620Resource.java
+++ 
b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer620Resource.java
@@ -27,6 +27,8 @@ import org.apache.log4j.Logger;
 import org.apache.cloudstack.hypervisor.xenserver.XenServerResourceNewBase;
 
 import com.cloud.resource.ServerResource;
+import com.cloud.storage.resource.StorageSubsystemCommandHandler;
+import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.script.Script;
 
@@ -86,4 +88,10 @@ public class XenServer620Resource extends 
XenServerResourceNewBase {
         return dynamicMinRam;
     }
 
+    @Override
+    protected StorageSubsystemCommandHandler getStorageHandler() {
+        XenServerStorageProcessor processor = new 
Xenserver620StorageProcessor(this);
+        return new StorageSubsystemCommandHandlerBase(processor);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e8a87bbf/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
 
b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
index a90c829..c89e58a 100644
--- 
a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
+++ 
b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
@@ -88,7 +88,7 @@ import com.xensource.xenapi.VMGuestMetrics;
 public class XenServerStorageProcessor implements StorageProcessor {
     private static final Logger s_logger = 
Logger.getLogger(XenServerStorageProcessor.class);
     protected CitrixResourceBase hypervisorResource;
-    private String BaseMountPointOnHost = "/var/run/cloud_mount";
+    protected String BaseMountPointOnHost = "/var/run/cloud_mount";
 
     public XenServerStorageProcessor(CitrixResourceBase resource) {
         hypervisorResource = resource;
@@ -446,6 +446,7 @@ public class XenServerStorageProcessor implements 
StorageProcessor {
         return new CreateObjectAnswer(details);
     }
 
+
     @Override
     public Answer deleteVolume(DeleteCommand cmd) {
         DataTO volume = cmd.getData();
@@ -767,7 +768,7 @@ public class XenServerStorageProcessor implements 
StorageProcessor {
         }
     }
 
-    private boolean IsISCSI(String type) {
+    protected boolean IsISCSI(String type) {
         return SRType.LVMOHBA.equals(type) || SRType.LVMOISCSI.equals(type) || 
SRType.LVM.equals(type) ;
     }
 
@@ -1069,7 +1070,7 @@ public class XenServerStorageProcessor implements 
StorageProcessor {
         return lfilename;
     }
 
-    private String backupSnapshotToS3(final Connection connection, final S3TO 
s3, final String srUuid, final String folder, final String snapshotUuid,
+    protected String backupSnapshotToS3(final Connection connection, final 
S3TO s3, final String srUuid, final String folder, final String snapshotUuid,
             final Boolean iSCSIFlag, final int wait) {
 
         final String filename = iSCSIFlag ? "VHD-" + snapshotUuid
@@ -1182,7 +1183,7 @@ public class XenServerStorageProcessor implements 
StorageProcessor {
         }
     }
 
-    private boolean destroySnapshotOnPrimaryStorageExceptThis(Connection conn, 
String volumeUuid, String avoidSnapshotUuid){
+    protected boolean destroySnapshotOnPrimaryStorageExceptThis(Connection 
conn, String volumeUuid, String avoidSnapshotUuid){
         try {
             VDI volume = getVDIbyUuid(conn, volumeUuid);
             if (volume == null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e8a87bbf/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/Xenserver620StorageProcessor.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/Xenserver620StorageProcessor.java
 
b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/Xenserver620StorageProcessor.java
new file mode 100644
index 0000000..2d80747
--- /dev/null
+++ 
b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/Xenserver620StorageProcessor.java
@@ -0,0 +1,636 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.cloud.hypervisor.xen.resource;
+
+import java.io.File;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
+import org.apache.cloudstack.storage.to.SnapshotObjectTO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+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.storage.Storage;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.SR;
+import com.xensource.xenapi.Task;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.VDI;
+
+public class Xenserver620StorageProcessor extends XenServerStorageProcessor {
+    private static final Logger s_logger = 
Logger.getLogger(XenServerStorageProcessor.class);
+
+    public Xenserver620StorageProcessor(CitrixResourceBase resource) {
+        super(resource);
+    }
+    protected boolean mountNfs(Connection conn, String remoteDir, String 
localDir) {
+        if (localDir == null) {
+            localDir = "/var/cloud_mount/" + UUID.randomUUID().toString();
+        }
+        String results = hypervisorResource.callHostPluginAsync(conn, 
"cloud-plugin-snapshot", "mountNfsSecondaryStorage", 100 * 1000,
+                "localDir", localDir, "remoteDir", remoteDir);
+        if (results == null || results.isEmpty()) {
+            String errMsg = "Could not mount secondary storage " + remoteDir + 
" on host ";
+            s_logger.warn(errMsg);
+            throw new CloudRuntimeException(errMsg);
+        }
+        return true;
+    }
+    protected SR createFileSr(Connection conn, String remotePath, String dir) {
+        String localDir = "/var/cloud_mount/" + UUID.randomUUID().toString();
+        mountNfs(conn, remotePath, localDir);
+        SR sr = hypervisorResource.createFileSR(conn, localDir + "/" + dir);
+        return sr;
+    }
+
+    @Override
+    public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) {
+        DataTO srcData = cmd.getSrcTO();
+        DataTO destData = cmd.getDestTO();
+        int wait = cmd.getWait();
+        DataStoreTO srcStore = srcData.getDataStore();
+        Connection conn = hypervisorResource.getConnection();
+        SR srcSr = null;
+        try {
+            if ((srcStore instanceof NfsTO) && (srcData.getObjectType() == 
DataObjectType.TEMPLATE)) {
+                NfsTO srcImageStore = (NfsTO)srcStore;
+                TemplateObjectTO srcTemplate = (TemplateObjectTO)srcData;
+                String storeUrl = srcImageStore.getUrl();
+                URI uri = new URI(storeUrl);
+                String volumePath = srcData.getPath();
+
+                int index = volumePath.lastIndexOf("/");
+                String volumeDirectory = volumePath.substring(0, index);
+                srcSr = createFileSr(conn, uri.getHost() + ":" + 
uri.getPath(), volumeDirectory);
+                Set<VDI> vdis = srcSr.getVDIs(conn);
+                if (vdis.size() != 1) {
+                    return new CopyCmdAnswer("Can't find template VDI under: " 
+ uri.getHost() + ":" + uri.getPath() + "/" + volumeDirectory);
+                }
+
+                VDI srcVdi = vdis.iterator().next();
+
+                PrimaryDataStoreTO destStore = 
(PrimaryDataStoreTO)destData.getDataStore();
+                String poolName = destStore.getUuid();
+
+
+                SR poolsr = null;
+                Set<SR> srs = SR.getByNameLabel(conn, poolName);
+                if (srs.size() != 1) {
+                    String msg = "There are " + srs.size() + " SRs with same 
name: " + poolName;
+                    s_logger.warn(msg);
+                    return new CopyCmdAnswer(msg);
+                } else {
+                    poolsr = srs.iterator().next();
+                }
+                String pUuid = poolsr.getUuid(conn);
+                boolean isISCSI = IsISCSI(poolsr.getType(conn));
+                Task task = srcVdi.copyAsync(conn, poolsr, null, null);
+                // poll every 1 seconds ,
+                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                hypervisorResource.checkForSuccess(conn, task);
+                VDI tmpl = Types.toVDI(task, conn);
+                VDI snapshotvdi = tmpl.snapshot(conn, new HashMap<String, 
String>());
+                String snapshotUuid = snapshotvdi.getUuid(conn);
+                snapshotvdi.setNameLabel(conn, "Template " + 
srcTemplate.getName());
+                String parentuuid = getVhdParent(conn, pUuid, snapshotUuid, 
isISCSI);
+                VDI parent = getVDIbyUuid(conn, parentuuid);
+                Long phySize = parent.getPhysicalUtilisation(conn);
+                tmpl.destroy(conn);
+                poolsr.scan(conn);
+                try{
+                    Thread.sleep(5000);
+                } catch (Exception e) {
+                }
+
+                TemplateObjectTO newVol = new TemplateObjectTO();
+                newVol.setUuid(snapshotvdi.getUuid(conn));
+                newVol.setPath(newVol.getUuid());
+                newVol.setFormat(Storage.ImageFormat.VHD);
+                return new CopyCmdAnswer(newVol);
+            }
+        }catch (Exception e) {
+            String msg = "Catch Exception " + e.getClass().getName() + " for 
template + " + " due to " + e.toString();
+            s_logger.warn(msg, e);
+            return new CopyCmdAnswer(msg);
+        } finally {
+            if (srcSr != null) {
+                hypervisorResource.removeSR(conn, srcSr);
+            }
+        }
+        return new CopyCmdAnswer("not implemented yet");
+    }
+
+    protected String backupSnapshot(Connection conn, String 
primaryStorageSRUuid, String localMountPoint, String path, String 
secondaryStorageMountPath, String snapshotUuid, String prevBackupUuid, String 
prevSnapshotUuid, Boolean isISCSI, int wait) {
+        String errMsg = null;
+        boolean mounted = false;
+        boolean filesrcreated = false;
+        boolean copied = false;
+        if (prevBackupUuid == null) {
+            prevBackupUuid = "";
+        }
+        SR ssSR = null;
+
+        String remoteDir = secondaryStorageMountPath;
+
+        try {
+            ssSR = createFileSr(conn, remoteDir, path);
+            filesrcreated = true;
+
+            VDI snapshotvdi = VDI.getByUuid(conn, snapshotUuid);
+            Task task = null;
+            if (wait == 0) {
+                wait = 2 * 60 * 60;
+            }
+            VDI dvdi = null;
+            try {
+                VDI previousSnapshotVdi = null;
+                if (prevSnapshotUuid != null) {
+                    previousSnapshotVdi = VDI.getByUuid(conn,prevSnapshotUuid);
+                }
+                task = snapshotvdi.copyAsync(conn, ssSR, previousSnapshotVdi, 
null);
+                // poll every 1 seconds ,
+                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                hypervisorResource.checkForSuccess(conn, task);
+                dvdi = Types.toVDI(task, conn);
+                copied = true;
+            } catch (TimeoutException e) {
+                throw new CloudRuntimeException(e.toString());
+            } finally {
+                if (task != null) {
+                    try {
+                        task.destroy(conn);
+                    } catch (Exception e1) {
+                        s_logger.warn("unable to destroy task(" + 
task.toString() + ") on host("
+                                + ") due to ", e1);
+                    }
+                }
+            }
+            String backupUuid = dvdi.getUuid(conn);
+            return backupUuid;
+        } catch (Exception e) {
+            String msg = "Exception in backupsnapshot stage due to " + 
e.toString();
+            s_logger.debug(msg);
+            throw new CloudRuntimeException(msg, e);
+        } finally {
+            try {
+                if (filesrcreated && ssSR != null) {
+                    hypervisorResource.removeSR(conn, ssSR);
+                }
+            } catch (Exception e) {
+                s_logger.debug("Exception in backupsnapshot cleanup stage due 
to " + e.toString());
+            }
+        }
+    }
+
+    @Override
+    public Answer backupSnapshot(CopyCommand cmd) {
+        Connection conn = hypervisorResource.getConnection();
+        DataTO srcData = cmd.getSrcTO();
+        DataTO cacheData = cmd.getCacheTO();
+        DataTO destData = cmd.getDestTO();
+        int wait = cmd.getWait();
+        PrimaryDataStoreTO primaryStore = 
(PrimaryDataStoreTO)srcData.getDataStore();
+        String primaryStorageNameLabel = primaryStore.getUuid();
+        String secondaryStorageUrl = null;
+        NfsTO cacheStore = null;
+        String destPath = null;
+        if (cacheData != null) {
+            cacheStore = (NfsTO)cacheData.getDataStore();
+            secondaryStorageUrl = cacheStore.getUrl();
+            destPath = cacheData.getPath();
+        } else {
+            cacheStore = (NfsTO)destData.getDataStore();
+            secondaryStorageUrl = cacheStore.getUrl();
+            destPath = destData.getPath();
+        }
+
+        SnapshotObjectTO snapshotTO = (SnapshotObjectTO)srcData;
+        SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO)destData;
+        String snapshotUuid = snapshotTO.getPath();
+
+        String prevBackupUuid = snapshotOnImage.getParentSnapshotPath();
+        String prevSnapshotUuid = snapshotTO.getParentSnapshotPath();
+
+        // By default assume failure
+        String details = null;
+        String snapshotBackupUuid = null;
+        boolean fullbackup = true;
+        try {
+            SR primaryStorageSR = 
hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel);
+            if (primaryStorageSR == null) {
+                throw new InternalErrorException("Could not backup snapshot 
because the primary Storage SR could not be created from the name label: " + 
primaryStorageNameLabel);
+            }
+            String psUuid = primaryStorageSR.getUuid(conn);
+            Boolean isISCSI = IsISCSI(primaryStorageSR.getType(conn));
+
+            VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid);
+            String snapshotPaUuid = null;
+            if ( prevBackupUuid != null ) {
+                try {
+                    snapshotPaUuid = getVhdParent(conn, psUuid, snapshotUuid, 
isISCSI);
+                    if( snapshotPaUuid != null ) {
+                        String snashotPaPaPaUuid = getVhdParent(conn, psUuid, 
snapshotPaUuid, isISCSI);
+                        String prevSnashotPaUuid = getVhdParent(conn, psUuid, 
prevSnapshotUuid, isISCSI);
+                        if (snashotPaPaPaUuid != null && prevSnashotPaUuid!= 
null && prevSnashotPaUuid.equals(snashotPaPaPaUuid)) {
+                            fullbackup = false;
+                        }
+                    }
+                } catch (Exception e) {
+                }
+            }
+
+            URI uri = new URI(secondaryStorageUrl);
+            String secondaryStorageMountPath = uri.getHost() + ":" + 
uri.getPath();
+            DataStoreTO destStore = destData.getDataStore();
+            String folder = destPath;
+            String finalPath = null;
+
+            String localMountPoint =  BaseMountPointOnHost + File.separator + 
UUID.nameUUIDFromBytes(secondaryStorageUrl.getBytes()).toString();
+            if (fullbackup) {
+                // the first snapshot is always a full snapshot
+
+                if( !hypervisorResource.createSecondaryStorageFolder(conn, 
secondaryStorageMountPath, folder)) {
+                    details = " Filed to create folder " + folder + " in 
secondary storage";
+                    s_logger.warn(details);
+                    return new CopyCmdAnswer(details);
+                }
+                SR snapshotSr = null;
+                try {
+                    snapshotSr = createFileSr(conn, secondaryStorageMountPath, 
folder);
+                    Task task = snapshotVdi.copyAsync(conn, snapshotSr, null, 
null);
+                    // poll every 1 seconds ,
+                    hypervisorResource.waitForTask(conn, task, 1000, wait * 
1000);
+                    hypervisorResource.checkForSuccess(conn, task);
+                    VDI backedVdi = Types.toVDI(task, conn);
+                    snapshotBackupUuid = backedVdi.getUuid(conn);
+
+                    if( destStore instanceof SwiftTO) {
+                        try {
+                            String container = "S-" + 
snapshotTO.getVolume().getVolumeId().toString();
+                            String destSnapshotName = 
swiftBackupSnapshot(conn, (SwiftTO)destStore, snapshotSr.getUuid(conn), 
snapshotBackupUuid, container, false, wait);
+                            String swiftPath = container + File.separator + 
destSnapshotName;
+                            finalPath = swiftPath;
+                        } finally {
+                            try {
+                                deleteSnapshotBackup(conn, localMountPoint, 
folder, secondaryStorageMountPath, snapshotBackupUuid);
+                            } catch (Exception e) {
+                                s_logger.debug("Failed to delete snapshot on 
cache storages" ,e);
+                            }
+                        }
+
+                    } else if (destStore instanceof S3TO) {
+                        try {
+                            finalPath = backupSnapshotToS3(conn, (S3TO) 
destStore, snapshotSr.getUuid(conn), folder, snapshotBackupUuid, isISCSI, wait);
+                            if (finalPath == null) {
+                                throw new CloudRuntimeException("S3 upload of 
snapshots " + snapshotBackupUuid + " failed");
+                            }
+                        } finally {
+                            try {
+                                deleteSnapshotBackup(conn, localMountPoint, 
folder, secondaryStorageMountPath, snapshotBackupUuid);
+                            } catch (Exception e) {
+                                s_logger.debug("Failed to delete snapshot on 
cache storages" ,e);
+                            }
+                        }
+                        // finalPath = folder + File.separator + 
snapshotBackupUuid;
+                    } else {
+                        finalPath = folder + File.separator + 
snapshotBackupUuid;
+                    }
+
+                } finally {
+                    if( snapshotSr != null) {
+                        hypervisorResource.removeSR(conn, snapshotSr);
+                    }
+                }
+            } else {
+                String primaryStorageSRUuid = primaryStorageSR.getUuid(conn);
+                if( destStore instanceof SwiftTO ) {
+                    String container = "S-" + 
snapshotTO.getVolume().getVolumeId().toString();
+                    snapshotBackupUuid = swiftBackupSnapshot(conn, 
(SwiftTO)destStore, primaryStorageSRUuid, snapshotPaUuid, "S-" + 
snapshotTO.getVolume().getVolumeId().toString(), isISCSI, wait);
+                    finalPath = container + File.separator + 
snapshotBackupUuid;
+                } else if (destStore instanceof S3TO ) {
+                    finalPath = backupSnapshotToS3(conn, (S3TO) destStore, 
primaryStorageSRUuid, folder, snapshotPaUuid, isISCSI, wait);
+                    if (finalPath == null) {
+                        throw new CloudRuntimeException("S3 upload of 
snapshots " + snapshotPaUuid + " failed");
+                    }
+                } else {
+                    snapshotBackupUuid = backupSnapshot(conn, 
primaryStorageSRUuid, localMountPoint, folder,
+                            secondaryStorageMountPath, snapshotUuid, 
prevBackupUuid, prevSnapshotUuid, isISCSI, wait);
+
+                    finalPath = folder + File.separator + snapshotBackupUuid;
+                }
+            }
+            String volumeUuid = snapshotTO.getVolume().getPath();
+            destroySnapshotOnPrimaryStorageExceptThis(conn, volumeUuid, 
snapshotUuid);
+
+            SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
+            newSnapshot.setPath(finalPath);
+            if (fullbackup) {
+                newSnapshot.setParentSnapshotPath(null);
+            } else {
+                newSnapshot.setParentSnapshotPath(prevBackupUuid);
+            }
+            return new CopyCmdAnswer(newSnapshot);
+        } catch (Types.XenAPIException e) {
+            details = "BackupSnapshot Failed due to " + e.toString();
+            s_logger.warn(details, e);
+        } catch (Exception e) {
+            details = "BackupSnapshot Failed due to " + e.getMessage();
+            s_logger.warn(details, e);
+        }
+
+        return new CopyCmdAnswer(details);
+    }
+
+    @Override
+    public Answer createTemplateFromVolume(CopyCommand cmd) {
+        Connection conn = hypervisorResource.getConnection();
+        VolumeObjectTO volume = (VolumeObjectTO)cmd.getSrcTO();
+        TemplateObjectTO template = (TemplateObjectTO)cmd.getDestTO();
+        NfsTO destStore = (NfsTO)cmd.getDestTO().getDataStore();
+        int wait = cmd.getWait();
+
+        String secondaryStoragePoolURL = destStore.getUrl();
+        String volumeUUID = volume.getPath();
+
+        String userSpecifiedName = template.getName();
+
+
+        String details = null;
+        SR tmpltSR = null;
+        boolean result = false;
+        String secondaryStorageMountPath = null;
+        String installPath = null;
+        try {
+            URI uri = new URI(secondaryStoragePoolURL);
+            secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
+            installPath = template.getPath();
+            if( !hypervisorResource.createSecondaryStorageFolder(conn, 
secondaryStorageMountPath, installPath)) {
+                details = " Filed to create folder " + installPath + " in 
secondary storage";
+                s_logger.warn(details);
+                return new CopyCmdAnswer(details);
+            }
+
+            VDI vol = getVDIbyUuid(conn, volumeUUID);
+            // create template SR
+            tmpltSR = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), 
installPath);
+
+            // copy volume to template SR
+            Task task = vol.copyAsync(conn, tmpltSR, null, null);
+            // poll every 1 seconds ,
+            hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+            hypervisorResource.checkForSuccess(conn, task);
+            VDI tmpltVDI = Types.toVDI(task, conn);
+            // scan makes XenServer pick up VDI physicalSize
+            tmpltSR.scan(conn);
+            if (userSpecifiedName != null) {
+                tmpltVDI.setNameLabel(conn, userSpecifiedName);
+            }
+
+            String tmpltUUID = tmpltVDI.getUuid(conn);
+            String tmpltFilename = tmpltUUID + ".vhd";
+            long virtualSize = tmpltVDI.getVirtualSize(conn);
+            long physicalSize = tmpltVDI.getPhysicalUtilisation(conn);
+            // create the template.properties file
+            String templatePath = secondaryStorageMountPath + "/" + 
installPath;
+            result = hypervisorResource.postCreatePrivateTemplate(conn, 
templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, 
virtualSize, template.getId());
+            if (!result) {
+                throw new CloudRuntimeException("Could not create the 
template.properties file on secondary storage dir");
+            }
+            installPath = installPath + "/" + tmpltFilename;
+            hypervisorResource.removeSR(conn, tmpltSR);
+            tmpltSR = null;
+            TemplateObjectTO newTemplate = new TemplateObjectTO();
+            newTemplate.setPath(installPath);
+            newTemplate.setFormat(Storage.ImageFormat.VHD);
+            newTemplate.setSize(virtualSize);
+            newTemplate.setPhysicalSize(physicalSize);
+            newTemplate.setName(tmpltUUID);
+            CopyCmdAnswer answer = new CopyCmdAnswer(newTemplate);
+            return answer;
+        } catch (Exception e) {
+            if (tmpltSR != null) {
+                hypervisorResource.removeSR(conn, tmpltSR);
+            }
+            if ( secondaryStorageMountPath != null) {
+                hypervisorResource.deleteSecondaryStorageFolder(conn, 
secondaryStorageMountPath, installPath);
+            }
+            details = "Creating template from volume " + volumeUUID + " failed 
due to " + e.toString();
+            s_logger.error(details, e);
+        }
+        return new CopyCmdAnswer(details);
+    }
+
+    @Override
+    public Answer createVolumeFromSnapshot(CopyCommand cmd) {
+        Connection conn = hypervisorResource.getConnection();
+        DataTO srcData = cmd.getSrcTO();
+        SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
+        DataTO destData = cmd.getDestTO();
+        PrimaryDataStoreTO pool = (PrimaryDataStoreTO)destData.getDataStore();
+        DataStoreTO imageStore = srcData.getDataStore();
+
+        if (!(imageStore instanceof NfsTO)) {
+            return new CopyCmdAnswer("unsupported protocol");
+        }
+
+        NfsTO nfsImageStore = (NfsTO)imageStore;
+        String primaryStorageNameLabel = pool.getUuid();
+        String secondaryStorageUrl = nfsImageStore.getUrl();
+        int wait = cmd.getWait();
+        boolean result = false;
+        // Generic error message.
+        String details = null;
+        String volumeUUID = null;
+
+        if (secondaryStorageUrl == null) {
+            details += " because the URL passed: " + secondaryStorageUrl + " 
is invalid.";
+            return new CopyCmdAnswer(details);
+        }
+        SR srcSr = null;
+        try {
+            SR primaryStorageSR = 
hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel);
+            if (primaryStorageSR == null) {
+                throw new InternalErrorException("Could not create volume from 
snapshot because the primary Storage SR could not be created from the name 
label: "
+                        + primaryStorageNameLabel);
+            }
+            // Get the absolute path of the snapshot on the secondary storage.
+            String snapshotInstallPath = snapshot.getPath();
+            int index = snapshotInstallPath.lastIndexOf(File.separator);
+            String snapshotUuid = snapshotInstallPath.substring(index + 1);
+            String snapshotDirectory = snapshotInstallPath.substring(0, index);
+            index = snapshotUuid.lastIndexOf(".");
+            if (index != -1) {
+                snapshotUuid = snapshotUuid.substring(0, index);
+            }
+
+            URI uri = new URI(secondaryStorageUrl);
+
+            srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), 
snapshotDirectory);
+
+            VDI snapshotVdi = VDI.getByUuid(conn, snapshotUuid);
+            Task task = snapshotVdi.copyAsync(conn, primaryStorageSR, null, 
null);
+            // poll every 1 seconds ,
+            hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+            hypervisorResource.checkForSuccess(conn, task);
+            VDI volumeVdi = Types.toVDI(task, conn);
+            volumeUUID = volumeVdi.getUuid(conn);
+            result = true;
+            VDI volume = VDI.getByUuid(conn, volumeUUID);
+            VDI.Record vdir = volume.getRecord(conn);
+            VolumeObjectTO newVol = new VolumeObjectTO();
+            newVol.setPath(volumeUUID);
+            newVol.setSize(vdir.virtualSize);
+            return new CopyCmdAnswer(newVol);
+        } catch (Types.XenAPIException e) {
+            details += " due to " + e.toString();
+            s_logger.warn(details, e);
+        } catch (Exception e) {
+            details += " due to " + e.getMessage();
+            s_logger.warn(details, e);
+        } finally {
+            if (srcSr != null) {
+                hypervisorResource.removeSR(conn, srcSr);
+            }
+        }
+        if (!result) {
+            // Is this logged at a higher level?
+            s_logger.error(details);
+        }
+
+        // In all cases return something.
+        return new CopyCmdAnswer(details);
+    }
+
+    @Override
+    public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) {
+        Connection conn = hypervisorResource.getConnection();
+        VolumeObjectTO srcVolume = (VolumeObjectTO)cmd.getSrcTO();
+        VolumeObjectTO destVolume = (VolumeObjectTO)cmd.getDestTO();
+        int wait = cmd.getWait();
+        DataStoreTO destStore = destVolume.getDataStore();
+
+        if (destStore instanceof NfsTO) {
+            SR secondaryStorage = null;
+            try {
+                NfsTO nfsStore = (NfsTO)destStore;
+                URI uri = new URI(nfsStore.getUrl());
+                // Create the volume folder
+                if (!hypervisorResource.createSecondaryStorageFolder(conn, 
uri.getHost() + ":" + uri.getPath(), destVolume.getPath())) {
+                    throw new InternalErrorException("Failed to create the 
volume folder.");
+                }
+
+                // Create a SR for the volume UUID folder
+                secondaryStorage = createFileSr(conn, uri.getHost() + ":" + 
uri.getPath(), destVolume.getPath());
+                // Look up the volume on the source primary storage pool
+                VDI srcVdi = getVDIbyUuid(conn, srcVolume.getPath());
+                // Copy the volume to secondary storage
+                Task task = srcVdi.copyAsync(conn, secondaryStorage, null, 
null);
+                // poll every 1 seconds ,
+                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                hypervisorResource.checkForSuccess(conn, task);
+                VDI destVdi = Types.toVDI(task, conn);
+                String destVolumeUUID = destVdi.getUuid(conn);
+
+                VolumeObjectTO newVol = new VolumeObjectTO();
+                newVol.setPath(destVolume.getPath() + File.separator + 
destVolumeUUID + ".vhd");
+                newVol.setSize(srcVolume.getSize());
+                return new CopyCmdAnswer(newVol);
+            } catch (Exception e) {
+                s_logger.debug("Failed to copy volume to secondary: " + 
e.toString());
+                return new CopyCmdAnswer("Failed to copy volume to secondary: 
" + e.toString());
+            } finally {
+                hypervisorResource.removeSR(conn, secondaryStorage);
+            }
+        }
+        return new CopyCmdAnswer("unsupported protocol");
+    }
+
+    @Override
+    public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) {
+        Connection conn = hypervisorResource.getConnection();
+        DataTO srcData = cmd.getSrcTO();
+        DataTO destData = cmd.getDestTO();
+        int wait = cmd.getWait();
+        VolumeObjectTO srcVolume = (VolumeObjectTO)srcData;
+        VolumeObjectTO destVolume = (VolumeObjectTO)destData;
+        PrimaryDataStoreTO primaryStore = 
(PrimaryDataStoreTO)destVolume.getDataStore();
+        DataStoreTO srcStore = srcVolume.getDataStore();
+
+        if (srcStore instanceof NfsTO) {
+            NfsTO nfsStore = (NfsTO)srcStore;
+            String volumePath = srcVolume.getPath();
+            int index = volumePath.lastIndexOf("/");
+            String volumeDirectory = volumePath.substring(0, index);
+            String volumeUuid = volumePath.substring(index + 1);
+            index = volumeUuid.indexOf(".");
+            if (index != -1) {
+                volumeUuid = volumeUuid.substring(0, index);
+            }
+            URI uri = null;
+            try {
+                uri = new URI(nfsStore.getUrl());
+            } catch (Exception e) {
+                return new CopyCmdAnswer(e.toString());
+            }
+            SR srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), 
volumeDirectory);
+            try {
+                SR primaryStoragePool = 
hypervisorResource.getStorageRepository(conn, primaryStore.getUuid());
+                VDI srcVdi = VDI.getByUuid(conn, volumeUuid);
+                Task task = srcVdi.copyAsync(conn, primaryStoragePool, null, 
null);
+                // poll every 1 seconds ,
+                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                hypervisorResource.checkForSuccess(conn, task);
+                VDI destVdi = Types.toVDI(task, conn);
+                VolumeObjectTO newVol = new VolumeObjectTO();
+                newVol.setPath(destVdi.getUuid(conn));
+                newVol.setSize(srcVolume.getSize());
+
+                return new CopyCmdAnswer(newVol);
+            } catch (Exception e) {
+                String msg = "Catch Exception " + e.getClass().getName() + " 
due to " + e.toString();
+                s_logger.warn(msg, e);
+                return new CopyCmdAnswer(e.toString());
+            } finally {
+                if (srcSr != null) {
+                    hypervisorResource.removeSR(conn, srcSr);
+                }
+            }
+        }
+
+        s_logger.debug("unsupported protocol");
+        return new CopyCmdAnswer("unsupported protocol");
+    }
+
+}

Reply via email to