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;
+ }
}