You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mc...@apache.org on 2013/07/24 18:57:13 UTC

[1/4] git commit: updated refs/heads/master to df452ba

Updated Branches:
  refs/heads/master b7a483608 -> df452ba13


fix create template from snapshot if it's swift


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

Branch: refs/heads/master
Commit: be3883b67820126328ff5dd9098b267c2d656354
Parents: b7a4836
Author: Edison Su <su...@gmail.com>
Authored: Fri Jul 19 18:17:37 2013 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Wed Jul 24 09:48:07 2013 -0700

----------------------------------------------------------------------
 .../cloud/agent/api/GetStorageStatsCommand.java |  10 ++
 .../src/com/cloud/storage/JavaStorageLayer.java |  16 ++
 core/src/com/cloud/storage/StorageLayer.java    |   2 +
 .../datastore/db/SnapshotDataStoreVO.java       |   2 +-
 .../datastore/db/TemplateDataStoreVO.java       |   2 +-
 .../storage/datastore/db/VolumeDataStoreVO.java |   2 +-
 .../storage/volume/VolumeServiceImpl.java       |   1 +
 .../xen/resource/XenServerStorageProcessor.java |  25 +--
 scripts/vm/hypervisor/xenserver/vmopsSnapshot   |  28 ++--
 server/src/com/cloud/server/StatsCollector.java |   3 +-
 .../resource/NfsSecondaryStorageResource.java   | 159 ++++++++++++++++---
 .../LocalNfsSecondaryStorageResourceTest.java   |  18 ++-
 setup/db/db/schema-410to420.sql                 |   2 +-
 utils/src/com/cloud/utils/SwiftUtil.java        | 104 +++++++++++-
 14 files changed, 315 insertions(+), 59 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/be3883b6/core/src/com/cloud/agent/api/GetStorageStatsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/GetStorageStatsCommand.java b/core/src/com/cloud/agent/api/GetStorageStatsCommand.java
index f7ebd51..8f51e35 100755
--- a/core/src/com/cloud/agent/api/GetStorageStatsCommand.java
+++ b/core/src/com/cloud/agent/api/GetStorageStatsCommand.java
@@ -17,6 +17,7 @@
 package com.cloud.agent.api;
 
 import com.cloud.agent.api.LogLevel.Log4jLevel;
+import com.cloud.agent.api.to.DataStoreTO;
 import com.cloud.storage.Storage.StoragePoolType;
 
 @LogLevel(Log4jLevel.Trace)
@@ -25,6 +26,7 @@ public class GetStorageStatsCommand extends Command {
     private String localPath;
     private StoragePoolType pooltype;
     private String secUrl;
+    private DataStoreTO store;
 
 
     public String getSecUrl() {
@@ -46,6 +48,10 @@ public class GetStorageStatsCommand extends Command {
         this.pooltype = pooltype;
     }
 
+    public GetStorageStatsCommand(DataStoreTO store) {
+        this.store = store;
+    }
+
     public GetStorageStatsCommand(String secUrl) {
         this.secUrl = secUrl;
     }
@@ -69,6 +75,10 @@ public class GetStorageStatsCommand extends Command {
         return this.localPath;
     }
 
+    public DataStoreTO getStore() {
+        return this.store;
+    }
+
     @Override
     public boolean executeInSequence() {
         return false;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/be3883b6/core/src/com/cloud/storage/JavaStorageLayer.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/JavaStorageLayer.java b/core/src/com/cloud/storage/JavaStorageLayer.java
index 525d429..bfaa767 100644
--- a/core/src/com/cloud/storage/JavaStorageLayer.java
+++ b/core/src/com/cloud/storage/JavaStorageLayer.java
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 
 import javax.ejb.Local;
 import javax.naming.ConfigurationException;
@@ -164,6 +165,21 @@ public class JavaStorageLayer implements StorageLayer {
     }
 
     @Override
+    public File createUniqDir() {
+        String dirName = System.getProperty("java.io.tmpdir");
+        if (dirName != null) {
+            File dir = new File(dirName);
+            if (dir.exists()) {
+                String uniqDirName = dir.getAbsolutePath() + File.separator + UUID.randomUUID().toString();
+                if (this.mkdir(uniqDirName)) {
+                    return new File(uniqDirName);
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
     public boolean mkdirs(String path) {
         synchronized(path.intern()) {
             File dir = new File(path);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/be3883b6/core/src/com/cloud/storage/StorageLayer.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/StorageLayer.java b/core/src/com/cloud/storage/StorageLayer.java
index b640191..7d8583d 100644
--- a/core/src/com/cloud/storage/StorageLayer.java
+++ b/core/src/com/cloud/storage/StorageLayer.java
@@ -39,6 +39,8 @@ public interface StorageLayer extends Manager {
      */
     long getSize(String path);
 
+    File createUniqDir();
+
     /**
      * Is this path a directory?
      * @param path path to check.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/be3883b6/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
index 2ae3e8c..929b2c8 100644
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
@@ -93,7 +93,7 @@ public class SnapshotDataStoreVO implements StateObject<ObjectInDataStoreStateMa
     ObjectInDataStoreStateMachine.State state;
 
     @Column(name = "ref_cnt")
-    Long refCnt;
+    Long refCnt = 0L;
 
     public String getInstallPath() {
         return installPath;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/be3883b6/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
index c6b434d..b6af559 100755
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
@@ -113,7 +113,7 @@ public class TemplateDataStoreVO implements StateObject<ObjectInDataStoreStateMa
     ObjectInDataStoreStateMachine.State state;
 
     @Column(name = "ref_cnt")
-    Long refCnt;
+    Long refCnt = 0L;
 
     public TemplateDataStoreVO(Long hostId, long templateId) {
         super();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/be3883b6/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
index 222447f..a5d0830 100755
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
@@ -112,7 +112,7 @@ public class VolumeDataStoreVO implements StateObject<ObjectInDataStoreStateMach
     ObjectInDataStoreStateMachine.State state;
 
     @Column(name = "ref_cnt")
-    Long refCnt;
+    Long refCnt = 0L;
 
     public String getInstallPath() {
         return installPath;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/be3883b6/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
index cc73b47..559bd37 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@ -395,6 +395,7 @@ public class VolumeServiceImpl implements VolumeService {
         int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(
                 configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
         templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolRefId, storagePoolMaxWaitSeconds);
+
         if (templatePoolRef == null) {
             templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId());
             if (templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready ) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/be3883b6/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 f13225d..17a4856 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
@@ -90,6 +90,7 @@ import java.util.UUID;
 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";
 
     public XenServerStorageProcessor(CitrixResourceBase resource) {
         this.hypervisorResource = resource;
@@ -1043,10 +1044,10 @@ public class XenServerStorageProcessor implements StorageProcessor {
         return false;
     }
 
-    protected String deleteSnapshotBackup(Connection conn, String path, String secondaryStorageMountPath, String backupUUID) {
+    protected String deleteSnapshotBackup(Connection conn, String localMountPoint, String path, String secondaryStorageMountPath, String backupUUID) {
 
         // If anybody modifies the formatting below again, I'll skin them
-        String result = hypervisorResource.callHostPlugin(conn, "vmopsSnapshot", "deleteSnapshotBackup", "backupUUID", backupUUID, "path", path, "secondaryStorageMountPath", secondaryStorageMountPath);
+        String result = hypervisorResource.callHostPlugin(conn, "vmopsSnapshot", "deleteSnapshotBackup", "backupUUID", backupUUID, "path", path, "secondaryStorageMountPath", secondaryStorageMountPath, "localMountPoint", localMountPoint);
 
         return result;
     }
@@ -1147,7 +1148,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
 
     }
 
-    protected String backupSnapshot(Connection conn, String primaryStorageSRUuid, String path, String secondaryStorageMountPath, String snapshotUuid, String prevBackupUuid, Boolean isISCSI, int wait) {
+    protected String backupSnapshot(Connection conn, String primaryStorageSRUuid, String localMountPoint, String path, String secondaryStorageMountPath, String snapshotUuid, String prevBackupUuid, Boolean isISCSI, int wait) {
         String backupSnapshotUuid = null;
 
         if (prevBackupUuid == null) {
@@ -1159,7 +1160,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
         String backupUuid = UUID.randomUUID().toString();
         String results = hypervisorResource.callHostPluginAsync(conn, "vmopsSnapshot", "backupSnapshot", wait,
                 "primaryStorageSRUuid", primaryStorageSRUuid, "path", path, "secondaryStorageMountPath", secondaryStorageMountPath,
-                "snapshotUuid", snapshotUuid, "prevBackupUuid", prevBackupUuid, "backupUuid", backupUuid, "isISCSI", isISCSI.toString());
+                "snapshotUuid", snapshotUuid, "prevBackupUuid", prevBackupUuid, "backupUuid", backupUuid, "isISCSI", isISCSI.toString(), "localMountPath", localMountPoint);
         String errMsg = null;
         if (results == null || results.isEmpty()) {
             errMsg = "Could not copy backupUuid: " + backupSnapshotUuid
@@ -1282,6 +1283,8 @@ public class XenServerStorageProcessor implements StorageProcessor {
             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
 
@@ -1300,11 +1303,11 @@ public class XenServerStorageProcessor implements StorageProcessor {
                     if( destStore instanceof SwiftTO) {
                         try {
                             String container = "S-" + snapshotTO.getVolume().getVolumeId().toString();
-                            snapshotBackupUuid = swiftBackupSnapshot(conn, (SwiftTO)destStore, snapshotSr.getUuid(conn), snapshotBackupUuid, container, false, wait);
-                            String swiftPath = container + File.separator + snapshotBackupUuid;
-                            finalPath = container + File.separator + swiftPath;
+                            String destSnapshotName = swiftBackupSnapshot(conn, (SwiftTO)destStore, snapshotSr.getUuid(conn), snapshotBackupUuid, container, false, wait);
+                            String swiftPath = container + File.separator + destSnapshotName;
+                            finalPath = swiftPath;
                         } finally {
-                            deleteSnapshotBackup(conn, folder, secondaryStorageMountPath, snapshotBackupUuid);
+                            deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid);
                         }
 
                     } else if (destStore instanceof S3TO) {
@@ -1312,7 +1315,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
                             backupSnapshotToS3(conn, (S3TO)destStore, snapshotSr.getUuid(conn), snapshotBackupUuid, isISCSI, wait);
                             snapshotBackupUuid = snapshotBackupUuid + ".vhd";
                         } finally {
-                            deleteSnapshotBackup(conn, folder, secondaryStorageMountPath, snapshotBackupUuid);
+                            deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid);
                         }
                         finalPath = folder + File.separator + snapshotBackupUuid;
                     } else {
@@ -1334,8 +1337,8 @@ public class XenServerStorageProcessor implements StorageProcessor {
                     backupSnapshotToS3(conn, (S3TO)destStore, primaryStorageSRUuid, snapshotPaUuid, isISCSI, wait);
                     finalPath = folder + File.separator + snapshotPaUuid;
                 } else {
-                    snapshotBackupUuid = backupSnapshot(conn, primaryStorageSRUuid, folder + File.separator + UUID.nameUUIDFromBytes(secondaryStorageMountPath.getBytes())
-                             , secondaryStorageMountPath, snapshotUuid, prevBackupUuid, isISCSI, wait);
+                    snapshotBackupUuid = backupSnapshot(conn, primaryStorageSRUuid, localMountPoint, folder,
+                             secondaryStorageMountPath, snapshotUuid, prevBackupUuid, isISCSI, wait);
                     finalPath = folder + File.separator + snapshotBackupUuid;
                 }
             }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/be3883b6/scripts/vm/hypervisor/xenserver/vmopsSnapshot
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/vmopsSnapshot b/scripts/vm/hypervisor/xenserver/vmopsSnapshot
index 87a5083..9673986 100755
--- a/scripts/vm/hypervisor/xenserver/vmopsSnapshot
+++ b/scripts/vm/hypervisor/xenserver/vmopsSnapshot
@@ -321,19 +321,18 @@ def umount(localDir):
     util.SMlog("Successfully unmounted " + localDir)
     return
 
-def mountSnapshotsDir(secondaryStorageMountPath, relativeDir, dcId, accountId, instanceId, secHostId):
+def mountSnapshotsDir(secondaryStorageMountPath, localMountPoint, path):
     # The aim is to mount secondaryStorageMountPath on 
     # And create <accountId>/<instanceId> dir on it, if it doesn't exist already.
     # Assuming that secondaryStorageMountPath  exists remotely
 
     # Just mount secondaryStorageMountPath/<relativeDir>/SecondaryStorageHost/ everytime
     # Never unmount.
+    # path is like "snapshots/account/volumeId", we mount secondary_storage:/snapshots
+    relativeDir = path.split("/")[0]
+    restDir = "/".join(path.split("/")[1:])
     snapshotsDir = os.path.join(secondaryStorageMountPath, relativeDir)
 
-    # Mkdir local mount point dir, if it doesn't exist.
-    localMountPointPath = os.path.join(CLOUD_DIR, dcId)
-    localMountPointPath = os.path.join(localMountPointPath, relativeDir, secHostId)
-
     makedirs(localMountPointPath)
     # if something is not mounted already on localMountPointPath,
     # mount secondaryStorageMountPath on localMountPath
@@ -346,8 +345,7 @@ def mountSnapshotsDir(secondaryStorageMountPath, relativeDir, dcId, accountId, i
         mount(snapshotsDir, localMountPointPath)
 
     # Create accountId/instanceId dir on localMountPointPath, if it doesn't exist
-    backupsDir = os.path.join(localMountPointPath, accountId)
-    backupsDir = os.path.join(backupsDir, instanceId)
+    backupsDir = os.path.join(localMountPointPath, restDir)
     makedirs(backupsDir)
     return backupsDir
 
@@ -485,16 +483,13 @@ def getVhdParent(session, args):
 def backupSnapshot(session, args):
     util.SMlog("Called backupSnapshot with " + str(args))
     primaryStorageSRUuid      = args['primaryStorageSRUuid']
-    dcId                      = args['dcId']
-    accountId                 = args['accountId']
-    volumeId                  = args['volumeId']
     secondaryStorageMountPath = args['secondaryStorageMountPath']
     snapshotUuid              = args['snapshotUuid']
     prevBackupUuid            = args['prevBackupUuid']
     backupUuid                = args['backupUuid']
     isISCSI                   = getIsTrueString(args['isISCSI'])
-    secHostId                 = args['secHostId']
-
+    path = args['path']
+    localMountPoint = args['localMountPoint']
     primarySRPath = getPrimarySRPath(primaryStorageSRUuid, isISCSI)
     util.SMlog("primarySRPath: " + primarySRPath)
 
@@ -507,7 +502,7 @@ def backupSnapshot(session, args):
     # Mount secondary storage mount path on XenServer along the path
     # /var/run/sr-mount/<dcId>/snapshots/ and create <accountId>/<volumeId> dir
     # on it.
-    backupsDir = mountSnapshotsDir(secondaryStorageMountPath, "snapshots", dcId, accountId, volumeId, secHostId)
+    backupsDir = mountSnapshotsDir(secondaryStorageMountPath, localMountPoint, path)
     util.SMlog("Backups dir " + backupsDir)
 
     # Check existence of snapshot on primary storage
@@ -538,13 +533,12 @@ def backupSnapshot(session, args):
 @echo
 def deleteSnapshotBackup(session, args):
     util.SMlog("Calling deleteSnapshotBackup with " + str(args))
-    dcId                      = args['dcId']
-    accountId                 = args['accountId']
-    volumeId                  = args['volumeId']
     secondaryStorageMountPath = args['secondaryStorageMountPath']
     backupUUID                = args['backupUUID']
+    path = args['path']
+    localMountPoint = args['localMountPoint']
 
-    backupsDir = mountSnapshotsDir(secondaryStorageMountPath, "snapshots", dcId, accountId, volumeId)
+    backupsDir = mountSnapshotsDir(secondaryStorageMountPath, localMountPoint, path)
     # chdir to the backupsDir for convenience
     chdir(backupsDir)
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/be3883b6/server/src/com/cloud/server/StatsCollector.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java
index 1a6e424..3be7461 100755
--- a/server/src/com/cloud/server/StatsCollector.java
+++ b/server/src/com/cloud/server/StatsCollector.java
@@ -534,7 +534,8 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
                     if ( store.getUri() == null ) {
                         continue;
                     }
-                    GetStorageStatsCommand command = new GetStorageStatsCommand(store.getUri());
+
+                    GetStorageStatsCommand command = new GetStorageStatsCommand(store.getTO());
                     EndPoint ssAhost = _epSelector.select(store);
                     if (ssAhost == null) {
                         s_logger.debug("There is no secondary storage VM for secondary storage host " + store.getName());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/be3883b6/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 003c87a..a82714b 100755
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -164,6 +164,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
     public void disconnected() {
     }
 
+    public void setInSystemVM(boolean inSystemVM) {
+        this._inSystemVM = inSystemVM;
+    }
+
     @Override
     public Answer executeRequest(Command cmd) {
         if (cmd instanceof DownloadProgressCommand) {
@@ -215,6 +219,13 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
 
 
     protected CopyCmdAnswer postProcessing(File destFile, String downloadPath, String destPath, DataTO srcData, DataTO destData) throws ConfigurationException {
+        if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
+            SnapshotObjectTO snapshot = new SnapshotObjectTO();
+            snapshot.setPath(destPath + File.separator + destFile.getName());
+
+            CopyCmdAnswer answer = new CopyCmdAnswer(snapshot);
+            return answer;
+        }
         // do post processing to unzip the file if it is compressed
         String scriptsDir = "scripts/storage/secondary";
         String createTmpltScr = Script.findScript(scriptsDir, "createtmplt.sh");
@@ -238,7 +249,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         String extension = null;
         if (srcData.getObjectType() == DataObjectType.TEMPLATE) {
             extension = ((TemplateObjectTO) srcData).getFormat().getFileExtension();
-        } else {
+        } else if (srcData.getObjectType() == DataObjectType.VOLUME) {
             extension = ((VolumeObjectTO) srcData).getFormat().getFileExtension();
         }
 
@@ -403,11 +414,51 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
 
         if (srcData.getHypervisorType() == HypervisorType.XenServer) {
             return copySnapshotToTemplateFromNfsToNfsXenserver(cmd, srcData, srcDataStore, destData, destDataStore);
+        } else if (srcData.getHypervisorType() == HypervisorType.KVM) {
+            File srcFile = getFile(srcData.getPath(), srcDataStore.getUrl());
+            File destFile = getFile(destData.getPath(), destDataStore.getUrl());
+            s_logger.debug("copy snapshot to template");
+            Script.runSimpleBashScript("cp " + srcFile.getAbsolutePath() + " " + destFile.getAbsolutePath());
+            QCOW2Processor processor = new QCOW2Processor();
+            Map<String, Object> params = new HashMap<String, Object>();
+            params.put(StorageLayer.InstanceConfigKey, _storage);
+            try {
+                processor.configure("qcow2 processor", params);
+                String destPath = destFile.getAbsolutePath();
+                String templateName = srcFile.getName();
+                FormatInfo info = processor.process(destPath, null, templateName);
+                TemplateLocation loc = new TemplateLocation(_storage, destPath);
+                loc.create(1, true, srcFile.getName());
+                loc.addFormat(info);
+                loc.save();
+                TemplateProp prop = loc.getTemplateInfo();
+                TemplateObjectTO newTemplate = new TemplateObjectTO();
+                newTemplate.setPath(destData.getPath() + File.separator + templateName);
+                newTemplate.setFormat(ImageFormat.VHD);
+                newTemplate.setSize(prop.getSize());
+                return new CopyCmdAnswer(newTemplate);
+            } catch (ConfigurationException e) {
+                s_logger.debug("Failed to create template:" + e.toString());
+                return new CopyCmdAnswer(e.toString());
+            } catch (IOException e) {
+                s_logger.debug("Failed to create template:" + e.toString());
+                return new CopyCmdAnswer(e.toString());
+            }
         }
 
         return new CopyCmdAnswer("");
     }
 
+    protected File getFile(String path, String nfsPath) {
+        String filePath = getRootDir(nfsPath) + File.separator + path;
+        File f = new File(filePath);
+        if (!f.exists()) {
+            _storage.mkdirs(filePath);
+            f = new File(filePath);
+        }
+        return f;
+    }
+
     protected Answer createTemplateFromSnapshot(CopyCommand cmd) {
         DataTO srcData = cmd.getSrcTO();
         DataTO destData = cmd.getDestTO();
@@ -422,8 +473,32 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
             if (destDataStore instanceof NfsTO) {
                 return copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO) srcData, (NfsTO) srcDataStore,
                         (TemplateObjectTO) destData, (NfsTO) destDataStore);
-            }
+            } else if (destDataStore instanceof SwiftTO) {
+                //create template on the same data store
+                CopyCmdAnswer answer = (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO) srcData, (NfsTO) srcDataStore,
+                        (TemplateObjectTO) destData, (NfsTO) srcDataStore);
+                if (!answer.getResult()) {
+                    return answer;
+                }
+                s_logger.debug("starting copy template to swift");
+                DataTO newTemplate = (DataTO)answer.getNewData();
+                File templateFile = getFile(newTemplate.getPath(), ((NfsTO) srcDataStore).getUrl());
+                SwiftTO swift = (SwiftTO)destDataStore;
+                String containterName = SwiftUtil.getContainerName(destData.getObjectType().toString(), destData.getId());
+                String swiftPath = SwiftUtil.putObject(swift, templateFile, containterName, templateFile.getName());
+                //upload template.properties
+                File properties = new File(templateFile.getParent() + File.separator + _tmpltpp);
+                if (properties.exists()) {
+                    SwiftUtil.putObject(swift, properties, containterName, _tmpltpp);
+                }
 
+                TemplateObjectTO template = new TemplateObjectTO();
+                template.setPath(swiftPath);
+                template.setSize(templateFile.length());
+                SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
+                template.setFormat(snapshot.getVolume().getFormat());
+                return new CopyCmdAnswer(template);
+            }
         }
         return new CopyCmdAnswer("");
     }
@@ -581,9 +656,29 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         File file = null;
         try {
             NfsTO nfsCacheStore = (NfsTO)cacheStore;
-            String fileName = UUID.randomUUID().toString() + "." + cmd.getFormat().getFileExtension();
+            String fileName = cmd.getName() + "." + cmd.getFormat().getFileExtension();
             file = downloadFromUrlToNfs(cmd.getUrl(), nfsCacheStore, path, fileName);
-            String swiftPath = SwiftUtil.putObject(swiftTO, file, "T-" + cmd.getId());
+            String container = "T-" + cmd.getId();
+            String swiftPath = SwiftUtil.putObject(swiftTO, file, container, null);
+
+            //put metda file
+            File uniqDir = _storage.createUniqDir();
+            String metaFileName = uniqDir.getAbsolutePath() + File.separator + "template.properties";
+            _storage.create(uniqDir.getAbsolutePath(), "template.properties");
+            File metaFile = new File(metaFileName);
+            FileWriter writer = new FileWriter(metaFile);
+            BufferedWriter bufferWriter = new BufferedWriter(writer);
+            bufferWriter.write("uniquename=" + cmd.getName());
+            bufferWriter.write("\n");
+            bufferWriter.write("filename=" + fileName);
+            bufferWriter.write("\n");
+            bufferWriter.write("size=" + file.length());
+            bufferWriter.close();
+            writer.close();
+
+            SwiftUtil.putObject(swiftTO, metaFile, container, "template.properties");
+            metaFile.delete();
+            uniqDir.delete();
             String md5sum = null;
             try {
                 md5sum = DigestUtils.md5Hex(new FileInputStream(file));
@@ -1361,32 +1456,52 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
     }
 
     Map<String, TemplateProp> swiftListTemplate(SwiftTO swift) {
-        String[] containers = swiftList(swift, "", "");
+        String[] containers = SwiftUtil.list(swift, "", null);
         if (containers == null) {
             return null;
         }
         Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
         for (String container : containers) {
             if (container.startsWith("T-")) {
-                String ldir = _tmpltDir + "/" + UUID.randomUUID().toString();
-                createLocalDir(ldir);
-                String lFullPath = ldir + "/" + _tmpltpp;
-                swiftDownload(swift, container, _tmpltpp, lFullPath);
-                TemplateLocation loc = new TemplateLocation(_storage, ldir);
+                String[] files = SwiftUtil.list(swift, container, "template.properties");
+                if (files.length != 1) {
+                    continue;
+                }
                 try {
-                    if (!loc.load()) {
-                        s_logger.warn("Can not parse template.properties file for template " + container);
+                    File tempFile = File.createTempFile("template", ".tmp");
+                    File tmpFile = SwiftUtil.getObject(swift, tempFile, container + File.separator + "template.properties");
+                    if (tmpFile == null) {
                         continue;
                     }
+                    FileReader fr = new FileReader(tmpFile);
+                    BufferedReader brf = new BufferedReader(fr);
+                    String line = null;
+                    String uniqName = null;
+                    Long size = null;
+                    String name = null;
+                    while ((line = brf.readLine()) != null) {
+                        if (line.startsWith("uniquename=")) {
+                            uniqName = line.split("=")[1];
+                        } else if (line.startsWith("size=")) {
+                            size = Long.parseLong(line.split("=")[1]);
+                        } else if (line.startsWith("filename=")) {
+                            name = line.split("=")[1];
+                        }
+                    }
+                    brf.close();
+                    tempFile.delete();
+                    if (uniqName != null) {
+                        TemplateProp prop = new TemplateProp(uniqName, container + File.separator + name, size, size, true, false);
+                        tmpltInfos.put(uniqName, prop);
+                    }
+
                 } catch (IOException e) {
-                    s_logger.warn("Unable to load template location " + ldir + " due to " + e.toString(), e);
+                    s_logger.debug("Failed to create templ file:" + e.toString());
+                    continue;
+                } catch (Exception e) {
+                    s_logger.debug("Failed to get properties: " + e.toString());
                     continue;
                 }
-                TemplateProp tInfo = loc.getTemplateInfo();
-                tInfo.setInstallPath(container);
-                tmpltInfos.put(tInfo.getTemplateName(), tInfo);
-                loc.purge();
-                deleteLocalDir(ldir);
             }
         }
         return tmpltInfos;
@@ -1612,7 +1727,13 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
     }
 
     protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
-        String rootDir = getRootDir(cmd.getSecUrl());
+        DataStoreTO store = cmd.getStore();
+        if (store instanceof S3TO || store instanceof SwiftTO) {
+            long infinity = Integer.MAX_VALUE;
+            return new GetStorageStatsAnswer(cmd, infinity, 0L);
+        }
+
+        String rootDir = getRootDir(((NfsTO) store).getUrl());
         final long usedSize = getUsedSize(rootDir);
         final long totalSize = getTotalSize(rootDir);
         if (usedSize == -1 || totalSize == -1) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/be3883b6/services/secondary-storage/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java b/services/secondary-storage/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
index 7723321..0c355ec 100644
--- a/services/secondary-storage/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
+++ b/services/secondary-storage/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
@@ -20,6 +20,8 @@ package org.apache.cloudstack.storage.resource;
 
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.storage.DownloadAnswer;
+import com.cloud.agent.api.storage.ListTemplateAnswer;
+import com.cloud.agent.api.storage.ListTemplateCommand;
 import com.cloud.agent.api.to.DataObjectType;
 import com.cloud.agent.api.to.NfsTO;
 import com.cloud.agent.api.to.SwiftTO;
@@ -28,9 +30,11 @@ import com.cloud.storage.Storage;
 import com.cloud.utils.SwiftUtil;
 import junit.framework.Assert;
 import junit.framework.TestCase;
+import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
 import org.apache.cloudstack.storage.command.CopyCmdAnswer;
 import org.apache.cloudstack.storage.command.CopyCommand;
 import org.apache.cloudstack.storage.command.DownloadCommand;
+import org.apache.cloudstack.storage.to.SnapshotObjectTO;
 import org.apache.cloudstack.storage.to.TemplateObjectTO;
 import org.junit.Before;
 import org.junit.Test;
@@ -39,6 +43,7 @@ import org.mockito.Mockito;
 
 import javax.naming.ConfigurationException;
 import java.util.HashMap;
+import java.util.UUID;
 
 public class LocalNfsSecondaryStorageResourceTest extends TestCase {
     LocalNfsSecondaryStorageResource resource;
@@ -46,6 +51,8 @@ public class LocalNfsSecondaryStorageResourceTest extends TestCase {
     @Override
     public void setUp() throws ConfigurationException {
         resource = new LocalNfsSecondaryStorageResource();
+        resource.setInSystemVM(true);
+
         resource.setParentPath("/mnt");
         System.setProperty("paths.script", "/Users/edison/develop/asf-master/script");
         //resource.configure("test", new HashMap<String, Object>());
@@ -59,14 +66,15 @@ public class LocalNfsSecondaryStorageResourceTest extends TestCase {
         Mockito.when(swift.getEndPoint()).thenReturn("https://objects.dreamhost.com/auth");
         Mockito.when(swift.getAccount()).thenReturn("cloudstack");
         Mockito.when(swift.getUserName()).thenReturn("images");
-        //Mockito.when(swift.getKey()).thenReturn("something");
+        Mockito.when(swift.getKey()).thenReturn("oxvELQaOD1U5_VyosGfA-wpZ7uBWEff-CUBGCM0u");
 
         Mockito.when(template.getDataStore()).thenReturn(swift);
         Mockito.when(template.getPath()).thenReturn("template/1/1/");
         Mockito.when(template.isRequiresHvm()).thenReturn(true);
         Mockito.when(template.getId()).thenReturn(1L);
         Mockito.when(template.getFormat()).thenReturn(Storage.ImageFormat.VHD);
-        Mockito.when(template.getOrigUrl()).thenReturn("http://nfs1.lab.vmops.com/templates/ttylinux_pv.vhd");
+        Mockito.when(template.getOrigUrl()).thenReturn("http://nfs1.lab.vmops.com/templates/test.bz2");
+        Mockito.when(template.getName()).thenReturn(UUID.randomUUID().toString());
         Mockito.when(template.getObjectType()).thenReturn(DataObjectType.TEMPLATE);
 
         DownloadCommand cmd = new DownloadCommand(template, 100000L);
@@ -86,5 +94,11 @@ public class LocalNfsSecondaryStorageResourceTest extends TestCase {
         CopyCmdAnswer copyCmdAnswer = (CopyCmdAnswer)resource.executeRequest(cpyCmd);
         Assert.assertTrue(copyCmdAnswer.getResult());
 
+        //list template
+        ListTemplateCommand listCmd = new ListTemplateCommand(swift);
+        ListTemplateAnswer listAnswer = (ListTemplateAnswer)resource.executeRequest(listCmd);
+
+        Assert.assertTrue(listAnswer.getTemplateInfo().size() > 0);
     }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/be3883b6/setup/db/db/schema-410to420.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql
index 7fc5ea2..e109f9b 100644
--- a/setup/db/db/schema-410to420.sql
+++ b/setup/db/db/schema-410to420.sql
@@ -161,7 +161,7 @@ CREATE TABLE  `cloud`.`template_store_ref` (
   `destroyed` tinyint(1) COMMENT 'indicates whether the template_store entry was destroyed by the user or not',
   `is_copy` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'indicates whether this was copied ',
   `update_count` bigint unsigned,
-  `ref_cnt` bigint unsigned,
+  `ref_cnt` bigint unsigned DEFAULT 0,
   `updated` datetime, 
   PRIMARY KEY  (`id`),
 --  CONSTRAINT `fk_template_store_ref__store_id` FOREIGN KEY `fk_template_store_ref__store_id` (`store_id`) REFERENCES `image_store` (`id`) ON DELETE CASCADE,

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/be3883b6/utils/src/com/cloud/utils/SwiftUtil.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/SwiftUtil.java b/utils/src/com/cloud/utils/SwiftUtil.java
index c01de86..85da505 100644
--- a/utils/src/com/cloud/utils/SwiftUtil.java
+++ b/utils/src/com/cloud/utils/SwiftUtil.java
@@ -24,6 +24,8 @@ import com.cloud.utils.script.Script;
 import org.apache.log4j.Logger;
 
 import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
 
 
 public class SwiftUtil {
@@ -45,8 +47,34 @@ public class SwiftUtil {
         return swiftCLI;
     }
 
-    public static String putObject(SwiftClientCfg cfg, File srcFile, String container) {
+    public static boolean postMeta(SwiftClientCfg cfg, String container, String object, Map<String, String> metas) {
         String swiftCli = getSwiftCLIPath();
+        StringBuilder cms = new StringBuilder();
+        for(Map.Entry<String, String> entry : metas.entrySet()) {
+            cms.append(" -m ");
+            cms.append(entry.getKey());
+            cms.append(":");
+            cms.append(entry.getValue());
+            cms.append(" ");
+        }
+        Script command = new Script("/bin/bash", logger);
+        command.add("-c");
+        command.add("/usr/bin/python " + swiftCli + " -A "
+                + cfg.getEndPoint() + " -U " + cfg.getAccount() + ":" + cfg.getUserName() + " -K "
+                + cfg.getKey() + " post " + container + " " + object + " " + cms.toString());
+        OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
+        String result = command.execute(parser);
+        if (result != null) {
+            throw new CloudRuntimeException("Failed to post meta" + result);
+        }
+        return true;
+    }
+
+    public static String putObject(SwiftClientCfg cfg, File srcFile, String container, String fileName) {
+        String swiftCli = getSwiftCLIPath();
+        if (fileName == null) {
+            fileName = srcFile.getName();
+        }
         String srcDirectory = srcFile.getParent();
         Script command = new Script("/bin/bash", logger);
         long size = srcFile.length();
@@ -55,12 +83,12 @@ public class SwiftUtil {
             command.add("cd " + srcDirectory
                     + ";/usr/bin/python " + swiftCli + " -A "
                     + cfg.getEndPoint() + " -U " + cfg.getAccount() + ":" + cfg.getUserName() + " -K "
-                    + cfg.getKey() + " upload " + container + " " + srcFile.getName());
+                    + cfg.getKey() + " upload " + container + " " + fileName);
         } else {
             command.add("cd " + srcDirectory
                     + ";/usr/bin/python " + swiftCli + " -A "
                     + cfg.getEndPoint() + " -U " + cfg.getAccount() + ":" + cfg.getUserName() + " -K "
-                    + cfg.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + " " + srcFile.getName());
+                    + cfg.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + " " + fileName);
         }
         OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
         String result = command.execute(parser);
@@ -71,19 +99,74 @@ public class SwiftUtil {
         if (parser.getLines() != null) {
             String[] lines = parser.getLines().split("\\n");
             for (String line : lines) {
-                if (line.contains("Errno") || line.contains("failed")) {
+                if (line.contains("Errno") || line.contains("failed") || line.contains("not found")) {
                     throw new CloudRuntimeException("Failed to upload file: " + lines.toString());
                 }
             }
         }
+
         return container + File.separator + srcFile.getName();
     }
 
+    private static StringBuilder buildSwiftCmd(SwiftClientCfg swift) {
+        String swiftCli = getSwiftCLIPath();
+        StringBuilder sb = new StringBuilder();
+        sb.append(" /usr/bin/python ");
+        sb.append(swiftCli);
+        sb.append(" -A ");
+        sb.append(swift.getEndPoint());
+        sb.append(" -U ");
+        sb.append(swift.getAccount());
+        sb.append(":");
+        sb.append(swift.getUserName());
+        sb.append(" -K ");
+        sb.append(swift.getKey());
+        sb.append(" ");
+        return sb;
+    }
+
+    public static String[] list(SwiftClientCfg swift, String container, String rFilename) {
+        String swiftCli = getSwiftCLIPath();
+        Script command = new Script("/bin/bash", logger);
+        command.add("-c");
+
+        StringBuilder swiftCmdBuilder = buildSwiftCmd(swift);
+        swiftCmdBuilder.append(" list ");
+        swiftCmdBuilder.append(container);
+
+        if (rFilename != null) {
+            swiftCmdBuilder.append(" -p ");
+            swiftCmdBuilder.append(rFilename);
+        }
+
+        command.add(swiftCmdBuilder.toString());
+        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+        String result = command.execute(parser);
+        if (result == null && parser.getLines() != null && !parser.getLines().equalsIgnoreCase("")) {
+            String[] lines = parser.getLines().split("\\n");
+            return lines;
+        } else {
+            if (result != null) {
+                String errMsg = "swiftList failed , err=" + result;
+                logger.debug("Failed to list " + errMsg);
+            } else {
+                String errMsg = "swiftList failed, no lines returns";
+                logger.debug("Failed to list " + errMsg);
+            }
+        }
+        return new String[0];
+    }
+
     public static File getObject(SwiftClientCfg cfg, File destDirectory, String swiftPath) {
         int firstIndexOfSeparator = swiftPath.indexOf(File.separator);
         String container = swiftPath.substring(0, firstIndexOfSeparator);
         String srcPath = swiftPath.substring(firstIndexOfSeparator + 1);
-        String destFilePath = destDirectory.getAbsolutePath() + File.separator + srcPath;
+        String destFilePath = null;
+        if (destDirectory.isDirectory()) {
+            destFilePath = destDirectory.getAbsolutePath() + File.separator + srcPath;
+        } else {
+            destFilePath = destDirectory.getAbsolutePath();
+        }
         String swiftCli = getSwiftCLIPath();
         Script command = new Script("/bin/bash", logger);
         command.add("-c");
@@ -109,4 +192,15 @@ public class SwiftUtil {
         }
         return new File(destFilePath);
     }
+
+    public static String getContainerName(String type, Long id) {
+        if (type.startsWith("T")) {
+            return "T-" + id;
+        } else if (type.startsWith("S")) {
+            return "S-" + id;
+        } else if (type.startsWith("V")) {
+            return "V-" + id;
+        }
+        return null;
+    }
 }


[2/4] git commit: updated refs/heads/master to df452ba

Posted by mc...@apache.org.
CLOUDSTACK-2630: fix delta snashpt


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

Branch: refs/heads/master
Commit: fa358cf01f4adbe315976688a21fb89e7a34adca
Parents: be3883b
Author: Edison Su <ed...@citrix.com>
Authored: Sat Jul 20 13:04:29 2013 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Wed Jul 24 09:48:41 2013 -0700

----------------------------------------------------------------------
 client/pom.xml                                  |  1 +
 .../datastore/db/SnapshotDataStoreDao.java      |  1 +
 .../datastore/db/SnapshotDataStoreVO.java       | 11 +++++
 .../cloudstack/storage/to/SnapshotObjectTO.java |  5 +-
 .../storage/snapshot/SnapshotObject.java        | 29 ++++++------
 .../storage/snapshot/SnapshotServiceImpl.java   |  4 ++
 .../snapshot/XenserverSnapshotStrategy.java     | 49 ++++++++++++++++----
 .../datastore/ObjectInDataStoreManagerImpl.java | 11 +++++
 .../image/db/SnapshotDataStoreDaoImpl.java      | 36 +++++++++++++-
 .../CloudStackPrimaryDataStoreDriverImpl.java   |  1 +
 setup/db/db/schema-410to420.sql                 |  1 +
 11 files changed, 122 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa358cf0/client/pom.xml
----------------------------------------------------------------------
diff --git a/client/pom.xml b/client/pom.xml
index 32ab94a..d25576a 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -329,6 +329,7 @@
         <artifactId>maven-jetty-plugin</artifactId>
         <version>6.1.26</version>
         <configuration>
+          <scanIntervalSeconds>0</scanIntervalSeconds>
           <stopPort>9966</stopPort>
           <stopKey>stop-jetty</stopKey>
           <connectors>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa358cf0/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
----------------------------------------------------------------------
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 01f0220..d129fe7 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
@@ -33,6 +33,7 @@ public interface SnapshotDataStoreDao extends GenericDao<SnapshotDataStoreVO, Lo
     void deletePrimaryRecordsForStore(long id);
 
     SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long storeId, long snapshotId);
+    SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long volumeId);
 
     SnapshotDataStoreVO findBySnapshot(long snapshotId, DataStoreRole role);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa358cf0/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
index 929b2c8..300df1e 100644
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
@@ -95,6 +95,9 @@ public class SnapshotDataStoreVO implements StateObject<ObjectInDataStoreStateMa
     @Column(name = "ref_cnt")
     Long refCnt = 0L;
 
+    @Column(name = "volume_id")
+    Long volumeId;
+
     public String getInstallPath() {
         return installPath;
     }
@@ -257,4 +260,12 @@ public class SnapshotDataStoreVO implements StateObject<ObjectInDataStoreStateMa
     public void decrRefCnt() {
         this.refCnt--;
     }
+
+    public Long getVolumeId() {
+        return volumeId;
+    }
+
+    public void setVolumeId(Long volumeId) {
+        this.volumeId = volumeId;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa358cf0/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
index 1115aec..4754dcf 100644
--- a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
@@ -42,8 +42,9 @@ public class SnapshotObjectTO implements DataTO {
         this.setId(snapshot.getId());
         this.volume = (VolumeObjectTO) snapshot.getBaseVolume().getTO();
         this.setVmName(snapshot.getBaseVolume().getAttachedVmName());
-        if (snapshot.getParent() != null) {
-            this.parentSnapshotPath = snapshot.getParent().getPath();
+        SnapshotInfo parentSnapshot = snapshot.getParent();
+        if (parentSnapshot != null) {
+            this.parentSnapshotPath = parentSnapshot.getPath();
         }
         this.dataStore = snapshot.getDataStore().getTO();
         this.setName(snapshot.getName());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa358cf0/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java
index 1cba96e..2fc576b 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java
@@ -22,12 +22,7 @@ import java.util.Date;
 
 import javax.inject.Inject;
 
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.*;
 import org.apache.cloudstack.storage.command.CopyCmdAnswer;
 import org.apache.cloudstack.storage.command.CreateObjectAnswer;
 import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
@@ -92,18 +87,18 @@ public class SnapshotObject implements SnapshotInfo {
 
     @Override
     public SnapshotInfo getParent() {
+
         SnapshotDataStoreVO snapStoreVO = this.snapshotStoreDao.findByStoreSnapshot(this.store.getRole(),
                 this.store.getId(), this.snapshot.getId());
-        if (snapStoreVO == null) {
-            return null;
-        }
-
-        long parentId = snapStoreVO.getParentSnapshotId();
-        if (parentId == 0) {
-            return null;
+        Long parentId = null;
+        if (snapStoreVO != null) {
+            parentId = snapStoreVO.getParentSnapshotId();
+            if (parentId != null && parentId != 0) {
+                return this.snapshotFactory.getSnapshot(parentId, store);
+            }
         }
 
-        return this.snapshotFactory.getSnapshot(parentId, store);
+        return null;
     }
 
     @Override
@@ -181,7 +176,11 @@ public class SnapshotObject implements SnapshotInfo {
 
     @Override
     public String getPath() {
-        return this.objectInStoreMgr.findObject(this, getDataStore()).getInstallPath();
+        DataObjectInStore objectInStore = this.objectInStoreMgr.findObject(this, getDataStore());
+        if (objectInStore != null) {
+            return objectInStore.getInstallPath();
+        }
+        return null;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa358cf0/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
index 3d7d4f2..81036d0 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
@@ -199,6 +199,7 @@ public class SnapshotServiceImpl implements SnapshotService {
             s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e);
             try {
                 snapshot.processEvent(Snapshot.Event.OperationFailed);
+                snapshot.processEvent(Event.OperationFailed);
             } catch (NoTransitionException e1) {
                 s_logger.debug("Failed to change state for event: OperationFailed", e);
             }
@@ -237,6 +238,9 @@ public class SnapshotServiceImpl implements SnapshotService {
             // find the image store where the parent snapshot backup is located
             SnapshotDataStoreVO parentSnapshotOnBackupStore = _snapshotStoreDao.findBySnapshot(parentSnapshot.getId(),
                     DataStoreRole.Image);
+            if (parentSnapshotOnBackupStore == null) {
+                return dataStoreMgr.getImageStore(snapshot.getDataCenterId());
+            }
             return dataStoreMgr.getDataStore(parentSnapshotOnBackupStore.getDataStoreId(),
                     parentSnapshotOnBackupStore.getRole());
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa358cf0/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
index 92af8c2..e30972d 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
@@ -18,13 +18,9 @@ package org.apache.cloudstack.storage.snapshot;
 
 import javax.inject.Inject;
 
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.*;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
 import org.apache.cloudstack.storage.command.CreateObjectAnswer;
 import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
@@ -65,7 +61,8 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
     @Override
     public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) {
         SnapshotInfo parentSnapshot = snapshot.getParent();
-        if (parentSnapshot != null && parentSnapshot.getPath().equalsIgnoreCase(snapshot.getPath())) {
+
+        if (parentSnapshot != null && snapshot.getPath().equalsIgnoreCase(parentSnapshot.getPath())) {
             s_logger.debug("backup an empty snapshot");
             // don't need to backup this snapshot
             SnapshotDataStoreVO parentSnapshotOnBackupStore = this.snapshotStoreDao.findBySnapshot(
@@ -79,6 +76,7 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
 
                 SnapshotObjectTO snapTO = new SnapshotObjectTO();
                 snapTO.setPath(parentSnapshotOnBackupStore.getInstallPath());
+
                 CreateObjectAnswer createSnapshotAnswer = new CreateObjectAnswer(snapTO);
 
                 snapshotOnImageStore.processEvent(Event.OperationSuccessed, createSnapshotAnswer);
@@ -109,7 +107,9 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
             for (i = 1; i < deltaSnap; i++) {
                 parentSnapshotOnBackupStore = this.snapshotStoreDao.findBySnapshot(parentSnapshot.getId(),
                         DataStoreRole.Image);
-
+                if (parentSnapshotOnBackupStore == null) {
+                    break;
+                }
                 Long prevBackupId = parentSnapshotOnBackupStore.getParentSnapshotId();
 
                 if (prevBackupId == 0) {
@@ -193,8 +193,39 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
 
     @Override
     public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) {
-        snapshot = snapshotSvr.takeSnapshot(snapshot).getSnashot();
-        return this.backupSnapshot(snapshot);
+        SnapshotResult result =  snapshotSvr.takeSnapshot(snapshot);
+        if (result.isFailed()) {
+            s_logger.debug("Failed to take snapshot: " + result.getResult());
+            throw new CloudRuntimeException(result.getResult());
+        }
+        snapshot = result.getSnashot();
+        DataStore primaryStore = snapshot.getDataStore();
+
+        SnapshotInfo backupedSnapshot = this.backupSnapshot(snapshot);
+        try {
+            SnapshotInfo parent = snapshot.getParent();
+            if (backupedSnapshot != null && parent != null) {
+                Long parentSnapshotId = parent.getId();
+                while (parentSnapshotId != null && parentSnapshotId != 0L) {
+                    SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(),primaryStore.getId(), parentSnapshotId);
+                    if (snapshotDataStoreVO != null) {
+                        parentSnapshotId = snapshotDataStoreVO.getParentSnapshotId();
+                        snapshotStoreDao.remove(snapshotDataStoreVO.getId());
+                    } else {
+                        parentSnapshotId = null;
+                    }
+                }
+                SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), primaryStore.getId(),
+                        snapshot.getId());
+                if (snapshotDataStoreVO != null) {
+                    snapshotDataStoreVO.setParentSnapshotId(0L);
+                    snapshotStoreDao.update(snapshotDataStoreVO.getId(), snapshotDataStoreVO);
+                }
+            }
+        } catch (Exception e) {
+            s_logger.debug("Failed to clean up snapshots on primary storage", e);
+        }
+        return backupedSnapshot;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa358cf0/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
index 427609e..c673776 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
@@ -107,10 +107,16 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
                 VMTemplateStoragePoolVO vo = new VMTemplateStoragePoolVO(dataStore.getId(), obj.getId());
                 vo = templatePoolDao.persist(vo);
             } else if (obj.getType() == DataObjectType.SNAPSHOT) {
+                SnapshotInfo snapshotInfo = (SnapshotInfo)obj;
                 SnapshotDataStoreVO ss = new SnapshotDataStoreVO();
                 ss.setSnapshotId(obj.getId());
                 ss.setDataStoreId(dataStore.getId());
                 ss.setRole(dataStore.getRole());
+                ss.setVolumeId(snapshotInfo.getVolumeId());
+                SnapshotDataStoreVO snapshotDataStoreVO = snapshotDataStoreDao.findParent(dataStore.getRole(), dataStore.getId(),snapshotInfo.getVolumeId());
+                if (snapshotDataStoreVO != null) {
+                    ss.setParentSnapshotId(snapshotDataStoreVO.getSnapshotId());
+                }
                 ss.setState(ObjectInDataStoreStateMachine.State.Allocated);
                 ss = snapshotDataStoreDao.persist(ss);
             }
@@ -148,6 +154,11 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
                 ss.setDataStoreId(dataStore.getId());
                 ss.setRole(dataStore.getRole());
                 ss.setRole(dataStore.getRole());
+                ss.setVolumeId(snapshot.getVolumeId());
+                SnapshotDataStoreVO snapshotDataStoreVO = snapshotDataStoreDao.findParent(dataStore.getRole(), dataStore.getId(),snapshot.getVolumeId());
+                if (snapshotDataStoreVO != null) {
+                    ss.setParentSnapshotId(snapshotDataStoreVO.getSnapshotId());
+                }
                 ss.setInstallPath(TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/"
                         + snapshotDao.findById(obj.getId()).getAccountId() + "/" + snapshot.getVolumeId());
                 ss.setState(ObjectInDataStoreStateMachine.State.Allocated);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa358cf0/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
----------------------------------------------------------------------
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 a198004..f5e7421 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
@@ -16,6 +16,9 @@
 // under the License.
 package org.apache.cloudstack.storage.image.db;
 
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -47,6 +50,12 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
     private SearchBuilder<SnapshotDataStoreVO> destroyedSearch;
     private SearchBuilder<SnapshotDataStoreVO> snapshotSearch;
     private SearchBuilder<SnapshotDataStoreVO> 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";
+
+
 
     @Override
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
@@ -146,7 +155,32 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
         sc.setParameters("store_id", storeId);
         sc.setParameters("snapshot_id", snapshotId);
         sc.setParameters("store_role", role);
-        return findOneIncludingRemovedBy(sc);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long volumeId) {
+        Transaction txn = Transaction.currentTxn();
+        PreparedStatement pstmt = null;
+        ResultSet rs = null;
+        try {
+            pstmt = txn.prepareStatement(parentSearch);
+            pstmt.setLong(1, storeId);
+            pstmt.setString(2, role.toString());
+            pstmt.setLong(3, volumeId);
+            rs = pstmt.executeQuery();
+            while (rs.next()) {
+                long sid = rs.getLong(1);
+                String rl = rs.getString(2);
+                long snid = rs.getLong(3);
+                return this.findByStoreSnapshot(role, sid, snid);
+            }
+        } catch (SQLException e) {
+           s_logger.debug("Failed to find parent snapshot: " + e.toString());
+        } finally {
+            txn.close();
+        }
+        return null;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa358cf0/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java
index a233407..9ea91b5 100644
--- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java
+++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java
@@ -155,6 +155,7 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri
         try {
             DataTO snapshotTO = snapshot.getTO();
 
+
             CreateObjectCommand cmd = new CreateObjectCommand(snapshotTO);
             EndPoint ep = this.epSelector.select(snapshot);
             Answer answer = ep.sendMessage(cmd);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa358cf0/setup/db/db/schema-410to420.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql
index e109f9b..82ca403 100644
--- a/setup/db/db/schema-410to420.sql
+++ b/setup/db/db/schema-410to420.sql
@@ -198,6 +198,7 @@ CREATE TABLE  `cloud`.`snapshot_store_ref` (
   `update_count` bigint unsigned,
   `ref_cnt` bigint unsigned,
   `updated` datetime,   
+  `volume_id` bigint unsigned,
   PRIMARY KEY  (`id`),
   INDEX `i_snapshot_store_ref__store_id`(`store_id`),
   CONSTRAINT `fk_snapshot_store_ref__snapshot_id` FOREIGN KEY `fk_snapshot_store_ref__snapshot_id` (`snapshot_id`) REFERENCES `snapshots` (`id`),


[4/4] git commit: updated refs/heads/master to df452ba

Posted by mc...@apache.org.
CLOUDSTACK-3741:Object_Store_Refactor - [KVM] Creation of Template from
Snapshot Fails.


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

Branch: refs/heads/master
Commit: df452ba13a7307dc1e9dc41ede9335e22dc423c2
Parents: d22bea6
Author: Min Chen <mi...@citrix.com>
Authored: Wed Jul 24 09:25:20 2013 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Wed Jul 24 09:49:28 2013 -0700

----------------------------------------------------------------------
 .../resource/NfsSecondaryStorageResource.java       | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/df452ba1/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 5318e09..29c05d5 100755
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -417,15 +417,21 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         } else if (srcData.getHypervisorType() == HypervisorType.KVM) {
             File srcFile = getFile(srcData.getPath(), srcDataStore.getUrl());
             File destFile = getFile(destData.getPath(), destDataStore.getUrl());
-            s_logger.debug("copy snapshot to template");
-            Script.runSimpleBashScript("cp " + srcFile.getAbsolutePath() + " " + destFile.getAbsolutePath());
+            // get snapshot file name, add extension if it is missing
+            String templateName = srcFile.getName();
+            if (!templateName.endsWith(ImageFormat.QCOW2.getFileExtension())) {
+                templateName = templateName + ImageFormat.QCOW2.getFileExtension();
+            }
+            String destFileFullPath = destFile.getAbsolutePath() + File.separator + templateName;
+            s_logger.debug("copy snapshot " + srcFile.getAbsolutePath() + " to template " + destFileFullPath);
+            Script.runSimpleBashScript("cp " + srcFile.getAbsolutePath() + " " + destFileFullPath);
+            // template post processing
             QCOW2Processor processor = new QCOW2Processor();
             Map<String, Object> params = new HashMap<String, Object>();
             params.put(StorageLayer.InstanceConfigKey, _storage);
             try {
                 processor.configure("qcow2 processor", params);
                 String destPath = destFile.getAbsolutePath();
-                String templateName = srcFile.getName();
                 FormatInfo info = processor.process(destPath, null, templateName);
                 TemplateLocation loc = new TemplateLocation(_storage, destPath);
                 loc.create(1, true, srcFile.getName());
@@ -434,7 +440,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
                 TemplateProp prop = loc.getTemplateInfo();
                 TemplateObjectTO newTemplate = new TemplateObjectTO();
                 newTemplate.setPath(destData.getPath() + File.separator + templateName);
-                newTemplate.setFormat(ImageFormat.VHD);
+                newTemplate.setFormat(ImageFormat.QCOW2);
                 newTemplate.setSize(prop.getSize());
                 return new CopyCmdAnswer(newTemplate);
             } catch (ConfigurationException e) {
@@ -481,7 +487,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
                     return answer;
                 }
                 s_logger.debug("starting copy template to swift");
-                DataTO newTemplate = (DataTO)answer.getNewData();
+                DataTO newTemplate = answer.getNewData();
                 File templateFile = getFile(newTemplate.getPath(), ((NfsTO) srcDataStore).getUrl());
                 SwiftTO swift = (SwiftTO)destDataStore;
                 String containterName = SwiftUtil.getContainerName(destData.getObjectType().toString(), destData.getId());


[3/4] git commit: updated refs/heads/master to df452ba

Posted by mc...@apache.org.
CLOUDSTACK-2630: fix delta snashpt


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

Branch: refs/heads/master
Commit: d22bea603149e00e88303d99dc1dcd2581f7b3c7
Parents: fa358cf
Author: Edison Su <su...@gmail.com>
Authored: Sat Jul 20 18:21:03 2013 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Wed Jul 24 09:48:59 2013 -0700

----------------------------------------------------------------------
 .../storage/snapshot/SnapshotServiceImpl.java   | 23 +++++---
 .../SnapshotStateMachineManagerImpl.java        |  3 +-
 .../snapshot/XenserverSnapshotStrategy.java     | 61 ++++++++++++--------
 .../storage/image/BaseImageStoreDriverImpl.java |  3 +-
 .../xen/resource/XenServerStorageProcessor.java |  2 +-
 scripts/vm/hypervisor/xenserver/vmopsSnapshot   |  2 +-
 .../resource/NfsSecondaryStorageResource.java   | 21 +------
 utils/src/com/cloud/utils/SwiftUtil.java        | 35 +++++++++++
 8 files changed, 95 insertions(+), 55 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d22bea60/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
index 81036d0..f8d9cbc 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
@@ -334,18 +334,25 @@ public class SnapshotServiceImpl implements SnapshotService {
 
     protected Void deleteSnapshotCallback(AsyncCallbackDispatcher<SnapshotServiceImpl, CommandResult> callback,
             DeleteSnapshotContext<CommandResult> context) {
+
         CommandResult result = callback.getResult();
         AsyncCallFuture<SnapshotResult> future = context.future;
         SnapshotInfo snapshot = context.snapshot;
-        if (result.isFailed()) {
-            s_logger.debug("delete snapshot failed" + result.getResult());
-            snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
-            SnapshotResult res = new SnapshotResult(context.snapshot, null);
-            future.complete(res);
-            return null;
+        SnapshotResult res = null;
+        try {
+            if (result.isFailed()) {
+                s_logger.debug("delete snapshot failed" + result.getResult());
+                snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
+                res = new SnapshotResult(context.snapshot, null);
+                res.setResult(result.getResult());
+            } else {
+                snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
+                res = new SnapshotResult(context.snapshot, null);
+            }
+        } catch (Exception e) {
+            s_logger.debug("Failed to in deleteSnapshotCallback", e);
+            res.setResult(e.toString());
         }
-        snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
-        SnapshotResult res = new SnapshotResult(context.snapshot, null);
         future.complete(res);
         return null;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d22bea60/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java
index c756ddb..555dcb8 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java
@@ -42,6 +42,7 @@ public class SnapshotStateMachineManagerImpl implements SnapshotStateMachineMana
         stateMachine.addTransition(Snapshot.State.Creating, Event.OperationNotPerformed, Snapshot.State.BackedUp);
         stateMachine.addTransition(Snapshot.State.Creating, Event.OperationFailed, Snapshot.State.Error);
         stateMachine.addTransition(Snapshot.State.CreatedOnPrimary, Event.BackupToSecondary, Snapshot.State.BackingUp);
+        stateMachine.addTransition(State.CreatedOnPrimary, Event.OperationNotPerformed, State.BackedUp);
         stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationSucceeded, Snapshot.State.BackedUp);
         stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationFailed, Snapshot.State.CreatedOnPrimary);
         stateMachine.addTransition(Snapshot.State.BackedUp, Event.DestroyRequested, Snapshot.State.Destroying);
@@ -49,7 +50,7 @@ public class SnapshotStateMachineManagerImpl implements SnapshotStateMachineMana
         stateMachine.addTransition(Snapshot.State.Copying, Event.OperationSucceeded, Snapshot.State.BackedUp);
         stateMachine.addTransition(Snapshot.State.Copying, Event.OperationFailed, Snapshot.State.BackedUp);
         stateMachine.addTransition(Snapshot.State.Destroying, Event.OperationSucceeded, Snapshot.State.Destroyed);
-        stateMachine.addTransition(Snapshot.State.Destroying, Event.OperationFailed, Snapshot.State.Error);
+        stateMachine.addTransition(Snapshot.State.Destroying, Event.OperationFailed, State.BackedUp);
 
         stateMachine.registerListener(new SnapshotStateListener());
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d22bea60/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
index e30972d..79f7d65 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
@@ -127,21 +127,23 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
         return this.snapshotSvr.backupSnapshot(snapshot);
     }
 
-    protected void deleteSnapshotChain(SnapshotInfo snapshot) {
-        while (snapshot != null) {
+    protected boolean deleteSnapshotChain(SnapshotInfo snapshot) {
+        s_logger.debug("delete snapshot chain for snapshot: " + snapshot.getId());
+        boolean result = false;
+        while (snapshot != null && (snapshot.getState() == Snapshot.State.Destroying || snapshot.getState()
+                == Snapshot.State.Destroyed || snapshot.getState() == Snapshot.State.Error)) {
             SnapshotInfo child = snapshot.getChild();
-            SnapshotInfo parent = snapshot.getParent();
-            if (child == null) {
-                if (parent == null || !parent.getPath().equalsIgnoreCase(snapshot.getPath())) {
-                    this.snapshotSvr.deleteSnapshot(snapshot);
-                    snapshot = parent;
-                    continue;
-                }
-                break;
-            } else {
+
+            if (child != null) {
+                s_logger.debug("the snapshot has child, can't delete it on the storage");
                 break;
             }
+            s_logger.debug("Snapshot: " + snapshot.getId() + " doesn't have children, so it's ok to delete it and its parents");
+            SnapshotInfo parent = snapshot.getParent();
+            result = this.snapshotSvr.deleteSnapshot(snapshot);
+            snapshot = parent;
         }
+        return result;
     }
 
     @Override
@@ -151,36 +153,47 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
             return true;
         }
 
+
+        if (snapshotVO.getState() == Snapshot.State.CreatedOnPrimary) {
+            s_logger.debug("delete snapshot on primary storage:");
+            snapshotVO.setState(Snapshot.State.Destroyed);
+            snapshotDao.update(snapshotId, snapshotVO);
+            return true;
+        }
+
         if (!Snapshot.State.BackedUp.equals(snapshotVO.getState())) {
             throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId
                     + " due to it is not in BackedUp Status");
         }
 
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId);
-        }
-
         // firt mark the snapshot as destroyed, so that ui can't see it, but we
         // may not destroy the snapshot on the storage, as other snaphosts may
         // depend on it.
-        SnapshotInfo snapshotOnPrimary = this.snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Primary);
-        SnapshotObject obj = (SnapshotObject) snapshotOnPrimary;
+        SnapshotInfo snapshotOnImage = this.snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Image);
+        if (snapshotOnImage == null) {
+            s_logger.debug("Can't find snapshot on backup storage, delete it in db");
+            snapshotDao.remove(snapshotId);
+        }
+
+        SnapshotObject obj = (SnapshotObject) snapshotOnImage;
         try {
             obj.processEvent(Snapshot.Event.DestroyRequested);
         } catch (NoTransitionException e) {
-            s_logger.debug("Failed to destroy snapshot: " + e.toString());
+            s_logger.debug("Failed to set the state to destroying: ", e);
             return false;
         }
 
         try {
-            SnapshotInfo snapshotOnImage = this.snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Image);
-            if (snapshotOnImage != null) {
-                deleteSnapshotChain(snapshotOnImage);
-            }
-
+            boolean result = deleteSnapshotChain(snapshotOnImage);
             obj.processEvent(Snapshot.Event.OperationSucceeded);
+            if (result) {
+                //snapshot is deleted on backup storage, need to delete it on primary storage
+                SnapshotDataStoreVO snapshotOnPrimary = snapshotStoreDao.findBySnapshot(snapshotId, DataStoreRole.Primary);
+                snapshotOnPrimary.setState(State.Destroyed);
+                snapshotStoreDao.update(snapshotOnPrimary.getId(), snapshotOnPrimary);
+            }
         } catch (Exception e) {
-            s_logger.debug("Failed to delete snapshot: " + e.toString());
+            s_logger.debug("Failed to delete snapshot: ", e);
             try {
                 obj.processEvent(Snapshot.Event.OperationFailed);
             } catch (NoTransitionException e1) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d22bea60/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
index a415c9f..e2fc8b7 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
@@ -219,10 +219,9 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
 
     @Override
     public void deleteAsync(DataStore dataStore, DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        DeleteCommand cmd = new DeleteCommand(data.getTO());
-
         CommandResult result = new CommandResult();
         try {
+            DeleteCommand cmd = new DeleteCommand(data.getTO());
             EndPoint ep = _epSelector.select(data);
             Answer answer = ep.sendMessage(cmd);
             if (answer != null && !answer.getResult()) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d22bea60/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 17a4856..e88d6a5 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
@@ -1160,7 +1160,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
         String backupUuid = UUID.randomUUID().toString();
         String results = hypervisorResource.callHostPluginAsync(conn, "vmopsSnapshot", "backupSnapshot", wait,
                 "primaryStorageSRUuid", primaryStorageSRUuid, "path", path, "secondaryStorageMountPath", secondaryStorageMountPath,
-                "snapshotUuid", snapshotUuid, "prevBackupUuid", prevBackupUuid, "backupUuid", backupUuid, "isISCSI", isISCSI.toString(), "localMountPath", localMountPoint);
+                "snapshotUuid", snapshotUuid, "prevBackupUuid", prevBackupUuid, "backupUuid", backupUuid, "isISCSI", isISCSI.toString(), "localMountPoint", localMountPoint);
         String errMsg = null;
         if (results == null || results.isEmpty()) {
             errMsg = "Could not copy backupUuid: " + backupSnapshotUuid

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d22bea60/scripts/vm/hypervisor/xenserver/vmopsSnapshot
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/vmopsSnapshot b/scripts/vm/hypervisor/xenserver/vmopsSnapshot
index 9673986..a4b0662 100755
--- a/scripts/vm/hypervisor/xenserver/vmopsSnapshot
+++ b/scripts/vm/hypervisor/xenserver/vmopsSnapshot
@@ -504,7 +504,7 @@ def backupSnapshot(session, args):
     # on it.
     backupsDir = mountSnapshotsDir(secondaryStorageMountPath, localMountPoint, path)
     util.SMlog("Backups dir " + backupsDir)
-
+    prevBackupUuid = prevBackupUuid.split("/")[-1]
     # Check existence of snapshot on primary storage
     isfile(baseCopyPath, isISCSI)
     if prevBackupUuid:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d22bea60/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index a82714b..5318e09 100755
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -1429,25 +1429,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
                 return new Answer(cmd, false, errorMessage);
             }
         } else if (dstore instanceof SwiftTO) {
+            SwiftTO swiftTO = (SwiftTO)dstore;
             String path = obj.getPath();
-            String filename = StringUtils.substringAfterLast(path, "/"); // assuming
-            // that
-            // the
-            // filename
-            // is
-            // the
-            // last
-            // section
-            // in
-            // the
-            // path
-            String volumeId = StringUtils.substringAfterLast(StringUtils.substringBeforeLast(path, "/"), "/");
-            String result = swiftDelete((SwiftTO) dstore, "V-" + volumeId, filename);
-            if (result != null) {
-                String errMsg = "failed to delete snapshot " + filename + " , err=" + result;
-                s_logger.warn(errMsg);
-                return new Answer(cmd, false, errMsg);
-            }
+            SwiftUtil.deleteObject(swiftTO, path);
+
             return new Answer(cmd, true, "Deleted snapshot " + path + " from swift");
         } else {
             return new Answer(cmd, false, "Unsupported image data store: " + dstore);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d22bea60/utils/src/com/cloud/utils/SwiftUtil.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/SwiftUtil.java b/utils/src/com/cloud/utils/SwiftUtil.java
index 85da505..8b816b9 100644
--- a/utils/src/com/cloud/utils/SwiftUtil.java
+++ b/utils/src/com/cloud/utils/SwiftUtil.java
@@ -203,4 +203,39 @@ public class SwiftUtil {
         }
         return null;
     }
+
+    public static String[] splitSwiftPath(String path) {
+        int index = path.indexOf(File.separator);
+        if (index == -1) {
+            return null;
+        }
+        String[] paths = new String[2];
+        paths[0] = path.substring(0, index);
+        paths[1] = path.substring(index + 1);
+        return paths;
+    }
+
+    public static boolean deleteObject(SwiftClientCfg cfg, String path) {
+        Script command = new Script("/bin/bash", logger);
+        command.add("-c");
+
+        String[] paths = splitSwiftPath(path);
+        if (paths == null) {
+            return false;
+        }
+        String container = paths[0];
+        String objectName = paths[1];
+
+        StringBuilder swiftCmdBuilder = buildSwiftCmd(cfg);
+        swiftCmdBuilder.append(" delete ");
+        swiftCmdBuilder.append(container);
+        swiftCmdBuilder.append(" ");
+        swiftCmdBuilder.append(objectName);
+
+
+        command.add(swiftCmdBuilder.toString());
+        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+        String result = command.execute(parser);
+        return true;
+    }
 }