swift: create volume from template works

This commit is contained in:
anthony 2011-10-21 12:53:58 -07:00
parent c97010a160
commit 6c5c24dd6b
10 changed files with 307 additions and 91 deletions

View File

@ -71,6 +71,8 @@ import com.cloud.agent.api.CheckRouterCommand;
import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.CleanupNetworkRulesCmd;
import com.cloud.agent.api.ClusterSyncAnswer;
import com.cloud.agent.api.ClusterSyncCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
@ -81,6 +83,8 @@ import com.cloud.agent.api.DeleteSnapshotBackupAnswer;
import com.cloud.agent.api.DeleteSnapshotBackupCommand;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.agent.api.DeleteStoragePoolCommand;
import com.cloud.agent.api.GetDomRVersionAnswer;
import com.cloud.agent.api.GetDomRVersionCmd;
import com.cloud.agent.api.GetHostStatsAnswer;
import com.cloud.agent.api.GetHostStatsCommand;
import com.cloud.agent.api.GetStorageStatsAnswer;
@ -89,11 +93,7 @@ import com.cloud.agent.api.GetVmStatsAnswer;
import com.cloud.agent.api.GetVmStatsCommand;
import com.cloud.agent.api.GetVncPortAnswer;
import com.cloud.agent.api.GetVncPortCommand;
import com.cloud.agent.api.GetDomRVersionCmd;
import com.cloud.agent.api.GetDomRVersionAnswer;
import com.cloud.agent.api.HostStatsEntry;
import com.cloud.agent.api.ClusterSyncAnswer;
import com.cloud.agent.api.ClusterSyncCommand;
import com.cloud.agent.api.MaintainAnswer;
import com.cloud.agent.api.MaintainCommand;
import com.cloud.agent.api.ManageSnapshotAnswer;
@ -105,7 +105,6 @@ import com.cloud.agent.api.ModifyStoragePoolAnswer;
import com.cloud.agent.api.ModifyStoragePoolCommand;
import com.cloud.agent.api.NetworkRulesSystemVmCommand;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.PingRoutingCommand;
import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;
import com.cloud.agent.api.PingRoutingWithOvsCommand;
import com.cloud.agent.api.PingTestCommand;
@ -135,6 +134,7 @@ import com.cloud.agent.api.StoragePoolInfo;
import com.cloud.agent.api.UpdateHostPasswordCommand;
import com.cloud.agent.api.UpgradeSnapshotCommand;
import com.cloud.agent.api.VmStatsEntry;
import com.cloud.agent.api.downloadSnapshotFromSwiftCommand;
import com.cloud.agent.api.check.CheckSshAnswer;
import com.cloud.agent.api.check.CheckSshCommand;
import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
@ -2965,13 +2965,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
}
boolean swiftDownload(Connection conn, SwiftTO swift, String rfilename, String lfilename) {
boolean swiftDownload(Connection conn, SwiftTO swift, String container, String rfilename, String dir, String lfilename, Boolean remote) {
String result = null;
try {
result = callHostPluginAsync(conn, "swiftxen", "swift", 60 * 60,
"op", "download", "url", swift.getUrl(), "account", swift.getAccount(),
"username", swift.getUserName(), "key", swift.getKey(), "rfilename", rfilename,
"lfilename", lfilename);
"dir", dir, "lfilename", lfilename, "remote", remote.toString());
if( result != null && result.equals("true")) {
return true;
}
@ -3025,6 +3025,36 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
swiftUpload(conn, swift, container, ldir, lfilename, isISCSI, wait);
}
public Answer execute(downloadSnapshotFromSwiftCommand cmd){
SwiftTO swift = cmd.getSwift();
String secondaryStorageURL = cmd.getSecondaryStoragePoolURL();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
String rfilename = cmd.getSnapshotUuid();
try {
URI uri = new URI(secondaryStorageURL);
String remoteMountPath = uri.getHost() + ":" + uri.getPath();
String folder = "snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId) + "/";
String dir = remoteMountPath + "/" + folder;
Connection conn = getConnection();
if (!createSecondaryStorageFolder(conn, remoteMountPath, folder)) {
throw new InternalErrorException("Failed to create the volume folder.");
}
String lfilename = rfilename;
if ( rfilename.startsWith("VHD-") ) {
lfilename = rfilename.replace("VHD-", "") + ".vhd";
}
if(swiftDownload(conn, swift, volumeId.toString(), rfilename, dir, lfilename, true)) {
return new Answer(cmd, true, "success");
}
return new Answer(cmd, false, "failure");
} catch (Exception e) {
String msg = cmd + " Command failed due to " + e.toString();
s_logger.warn(msg, e);
throw new CloudRuntimeException(msg);
}
}
protected String backupSnapshot(Connection conn, String primaryStorageSRUuid, Long dcId, Long accountId,
Long volumeId, String secondaryStorageMountPath, String snapshotUuid, String prevBackupUuid, Boolean isISCSI, int wait) {
@ -5845,7 +5875,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
String templatePath = secondaryStorageMountPath + "/" + installPath;
// create snapshot SR
String snapshotPath = secondaryStorageMountPath + "/snapshots/" + accountId + "/" + volumeId + "/" + backedUpSnapshotUuid + ".vhd";
String filename = backedUpSnapshotUuid;
if ( !filename.startsWith("VHD-") && !filename.endsWith(".vhd")) {
filename = backedUpSnapshotUuid + ".vhd";
}
String snapshotPath = secondaryStorageMountPath + "/snapshots/" + accountId + "/" + volumeId + "/" + filename;
String results = createTemplateFromSnapshot(conn, templatePath, snapshotPath, wait);
String[] tmp = results.split("#");
String tmpltUuid = tmp[1];
@ -5981,10 +6015,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
success = (snapshotBackupUuid != null);
}
}
String volumeUuid = cmd.getVolumePath();
destroySnapshotOnPrimaryStorageExceptThis(conn, volumeUuid, snapshotUuid);
if (success) {
details = "Successfully backedUp the snapshotUuid: " + snapshotUuid + " to secondary storage.";
String volumeUuid = cmd.getVolumePath();
destroySnapshotOnPrimaryStorageExceptThis(conn, volumeUuid, snapshotUuid);
}
} catch (XenAPIException e) {
details = "BackupSnapshot Failed due to " + e.toString();
@ -6023,7 +6058,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
// Get the absolute path of the snapshot on the secondary storage.
URI snapshotURI = new URI(secondaryStoragePoolURL + "/snapshots/" + accountId + "/" + volumeId );
String snapshotPath = snapshotURI.getHost() + ":" + snapshotURI.getPath() + "/" + backedUpSnapshotUuid + ".vhd";
String filename = backedUpSnapshotUuid;
if ( !filename.startsWith("VHD-") && !filename.endsWith(".vhd")) {
filename = backedUpSnapshotUuid + ".vhd";
}
String snapshotPath = snapshotURI.getHost() + ":" + snapshotURI.getPath() + "/" + filename;
String srUuid = primaryStorageSR.getUuid(conn);
volumeUUID = copy_vhd_from_secondarystorage(conn, snapshotPath, srUuid, wait);
result = true;

View File

@ -89,14 +89,11 @@ public class SnapshotVO implements Snapshot {
String backupSnapshotId;
@Column(name="swift_id")
long swiftId;
Long swiftId;
@Column(name="sechost_id")
Long secHostId;
@Column(name="swift_name")
String swiftName;
@Column(name="prev_snap_id")
long prevSnapshotId;
@ -185,11 +182,11 @@ public class SnapshotVO implements Snapshot {
return Type.values()[snapshotType];
}
public long getSwiftId() {
public Long getSwiftId() {
return swiftId;
}
public void setSwiftId(long swiftId) {
public void setSwiftId(Long swiftId) {
this.swiftId = swiftId;
}
@ -201,14 +198,6 @@ public class SnapshotVO implements Snapshot {
this.secHostId = secHostId;
}
public String getSwiftName() {
return swiftName;
}
public void setSwiftName(String swiftName) {
this.swiftName = swiftName;
}
@Override
public HypervisorType getHypervisorType() {
return hypervisorType;

View File

@ -23,14 +23,13 @@ import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.URI;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.naming.ConfigurationException;
@ -42,6 +41,7 @@ import com.cloud.agent.api.CheckHealthAnswer;
import com.cloud.agent.api.CheckHealthCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.ComputeChecksumCommand;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.agent.api.GetStorageStatsAnswer;
import com.cloud.agent.api.GetStorageStatsCommand;
import com.cloud.agent.api.PingCommand;
@ -49,36 +49,38 @@ import com.cloud.agent.api.PingStorageCommand;
import com.cloud.agent.api.ReadyAnswer;
import com.cloud.agent.api.ReadyCommand;
import com.cloud.agent.api.SecStorageFirewallCfgCommand;
import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig;
import com.cloud.agent.api.SecStorageSetupAnswer;
import com.cloud.agent.api.SecStorageSetupCommand;
import com.cloud.agent.api.StartupSecondaryStorageCommand;
import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig;
import com.cloud.agent.api.SecStorageVMSetupCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupSecondaryStorageCommand;
import com.cloud.agent.api.downloadSnapshotFromSwiftCommand;
import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
import com.cloud.agent.api.storage.DeleteTemplateCommand;
import com.cloud.agent.api.storage.ListTemplateAnswer;
import com.cloud.agent.api.storage.ListTemplateCommand;
import com.cloud.agent.api.storage.ssCommand;
import com.cloud.agent.api.storage.DownloadCommand;
import com.cloud.agent.api.storage.DownloadProgressCommand;
import com.cloud.agent.api.storage.ListTemplateAnswer;
import com.cloud.agent.api.storage.ListTemplateCommand;
import com.cloud.agent.api.storage.UploadCommand;
import com.cloud.agent.api.storage.ssCommand;
import com.cloud.agent.api.to.SwiftTO;
import com.cloud.exception.InternalErrorException;
import com.cloud.host.Host;
import com.cloud.host.Host.Type;
import com.cloud.resource.ServerResourceBase;
import com.cloud.storage.StorageLayer;
import com.cloud.storage.template.DownloadManager;
import com.cloud.storage.template.DownloadManagerImpl;
import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser;
import com.cloud.storage.template.TemplateInfo;
import com.cloud.storage.template.UploadManager;
import com.cloud.storage.template.UploadManagerImpl;
import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils;
import com.cloud.utils.net.NfsUtils;
import com.cloud.utils.script.Script;
import com.cloud.vm.SecondaryStorageVm;
@ -140,12 +142,135 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
} else if (cmd instanceof ComputeChecksumCommand){
return execute((ComputeChecksumCommand)cmd);
} else if (cmd instanceof ListTemplateCommand){
return execute((ListTemplateCommand)cmd);
return execute((ListTemplateCommand)cmd);
} else if (cmd instanceof downloadSnapshotFromSwiftCommand){
return execute((downloadSnapshotFromSwiftCommand)cmd);
} else if (cmd instanceof DeleteSnapshotsDirCommand){
return execute((DeleteSnapshotsDirCommand)cmd);
} else {
return Answer.createUnsupportedCommandAnswer(cmd);
}
}
String swiftDownload(SwiftTO swift, String container, String rfilename, String lFullPath) {
Script command = new Script("/bin/bash", s_logger);
command.add("-c");
command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A "
+ swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey()
+ " download " + container + " " + rfilename + " -o " + lFullPath);
String result = command.execute();
if (result != null) {
String errMsg = "swiftDownload failed , err=" + result;
s_logger.warn(errMsg);
return errMsg;
}
return null;
}
String swiftUpload(SwiftTO swift, String container, String lDir, String lFilename) {
Script command = new Script("/bin/bash", s_logger);
command.add("-c");
command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A "
+ swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey()
+ " upload " + container + " " + lFilename);
String result = command.execute();
if (result != null) {
String errMsg = "swiftUpload failed , err=" + result;
s_logger.warn(errMsg);
return errMsg;
}
return null;
}
String swiftDelete(SwiftTO swift, String container, String rFilename) {
Script command = new Script("/bin/bash", s_logger);
command.add("-c");
command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A "
+ swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey()
+ " delete " + container + " " + rFilename);
String result = command.execute();
if (result != null) {
String errMsg = "swiftDelete failed , err=" + result;
s_logger.warn(errMsg);
return errMsg;
}
return null;
}
public Answer execute(DeleteSnapshotsDirCommand cmd){
String secondaryStorageURL = cmd.getSecondaryStoragePoolURL();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
try {
String parent = getRootDir(secondaryStorageURL);
String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId);
Script command = new Script("/bin/bash", s_logger);
command.add("-c");
command.add("rm -f " + lPath + "/*");
String result = command.execute();
if (result != null) {
String errMsg = "failed to delete all snapshots " + lPath + " , err=" + result;
s_logger.warn(errMsg);
return new Answer(cmd, false, errMsg);
}
return new Answer(cmd, true, "success");
} catch (Exception e) {
String errMsg = cmd + " Command failed due to " + e.toString();
s_logger.warn(errMsg, e);
return new Answer(cmd, false, errMsg);
}
}
public Answer execute(downloadSnapshotFromSwiftCommand cmd){
SwiftTO swift = cmd.getSwift();
String secondaryStorageURL = cmd.getSecondaryStoragePoolURL();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
String rFilename = cmd.getSnapshotUuid();
String sParent = cmd.getParent();
String errMsg = "";
try {
String parent = getRootDir(secondaryStorageURL);
String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId);
String result = createLocalDir(lPath);
if ( result != null ) {
errMsg = "downloadSnapshotFromSwiftCommand failed due to Create local path failed";
s_logger.warn(errMsg);
throw new InternalErrorException(errMsg);
}
String lFilename = rFilename;
if ( rFilename.startsWith("VHD-") ) {
lFilename = rFilename.replace("VHD-", "") + ".vhd";
}
String lFullPath = lPath + "/" + lFilename;
result = swiftDownload(swift, volumeId.toString(), rFilename, lFullPath);
if (result != null) {
return new Answer(cmd, false, result);
}
if (sParent != null) {
if (sParent.startsWith("VHD-") || sParent.endsWith(".vhd")) {
String pFilename = sParent;
if (sParent.startsWith("VHD-")) {
pFilename = pFilename.replace("VHD-", "") + ".vhd";
}
String pFullPath = lPath + "/" + pFilename;
result = setVhdParent(lFullPath, pFullPath);
if (result != null) {
return new Answer(cmd, false, result);
}
}
}
return new Answer(cmd, true, "success");
} catch (Exception e) {
String msg = cmd + " Command failed due to " + e.toString();
s_logger.warn(msg, e);
throw new CloudRuntimeException(msg);
}
}
private Answer execute(ComputeChecksumCommand cmd) {
String relativeTemplatePath = cmd.getTemplatePath();
@ -267,7 +392,33 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
return new Answer(cmd, success, result.toString());
}
private String setVhdParent(String lFullPath, String pFullPath) {
Script command = new Script("/bin/bash", s_logger);
command.add("-c");
command.add("/bin/vhd-util modify -n " + lFullPath + " -p " + pFullPath);
String result = command.execute();
if (result != null) {
String errMsg = "failed to set vhd parent, child " + lFullPath + " parent " + pFullPath + ", err=" + result;
s_logger.warn(errMsg);
return errMsg;
}
return null;
}
private String createLocalDir(String folder) {
Script command = new Script("/bin/bash", s_logger);
command.add("-c");
command.add("mkdir -p " + folder);
String result = command.execute();
if (result != null) {
String errMsg = "Create local path " + folder + " failed , err=" + result;
s_logger.warn(errMsg);
return errMsg;
}
return null;
}
public String allowOutgoingOnPrivate(String destCidr) {
Script command = new Script("/bin/bash", s_logger);

View File

@ -258,6 +258,8 @@ public interface AgentManager extends Manager {
Answer sendToSecStorage(HostVO ssHost, Command cmd);
Answer sendToSSVM(final long dcId, final Command cmd);
HostVO getSSAgent(HostVO ssHost);
void updateStatus(HostVO host, Event event);

View File

@ -549,7 +549,8 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
}
}
private Answer sendToSSVM(final long dcId, final Command cmd) {
@Override
public Answer sendToSSVM(final long dcId, final Command cmd) {
List<HostVO> ssAHosts = _hostDao.listSecondaryStorageVM(dcId);
if (ssAHosts == null || ssAHosts.isEmpty() ) {
return new Answer(cmd, false, "can not find secondary storage VM agent for data center " + dcId);

View File

@ -633,20 +633,17 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
return new Pair<String, String>(null, "Unable to upgrade snapshot from 2.1 to 2.2 for " + snapshot.getId());
}
}
if( snapshot.getSwiftName() != null ) {
_snapshotMgr.downloadSnapshotsFromSwift(snapshot);
}
CreateVolumeFromSnapshotCommand createVolumeFromSnapshotCommand = new CreateVolumeFromSnapshotCommand(primaryStoragePoolNameLabel, secondaryStoragePoolUrl, dcId, accountId, volumeId,
backedUpSnapshotUuid, snapshot.getName(), _createVolumeFromSnapshotWait);
CreateVolumeFromSnapshotAnswer answer;
if (!_snapshotDao.lockInLockTable(snapshotId.toString(), 10)) {
throw new CloudRuntimeException("failed to create volume from " + snapshotId + " due to this snapshot is being used, try it later ");
}
String basicErrMsg = "Failed to create volume from " + snapshot.getName() + " on pool " + pool;
try {
if (snapshot.getSwiftId() != null) {
_snapshotMgr.downloadSnapshotsFromSwift(snapshot);
}
CreateVolumeFromSnapshotCommand createVolumeFromSnapshotCommand = new CreateVolumeFromSnapshotCommand(primaryStoragePoolNameLabel, secondaryStoragePoolUrl, dcId, accountId, volumeId,
backedUpSnapshotUuid, snapshot.getName(), _createVolumeFromSnapshotWait);
CreateVolumeFromSnapshotAnswer answer;
if (!_snapshotDao.lockInLockTable(snapshotId.toString(), 10)) {
throw new CloudRuntimeException("failed to create volume from " + snapshotId + " due to this snapshot is being used, try it later ");
}
answer = (CreateVolumeFromSnapshotAnswer) sendToPool(pool, createVolumeFromSnapshotCommand);
if (answer != null && answer.getResult()) {
vdiUUID = answer.getVdi();
@ -657,9 +654,11 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
} catch (StorageUnavailableException e) {
s_logger.error(basicErrMsg);
} finally {
if (snapshot.getSwiftId() != null) {
_snapshotMgr.deleteSnapshotsForVolume (secondaryStoragePoolUrl, dcId, accountId, volumeId);
}
_snapshotDao.unlockFromLockTable(snapshotId.toString());
}
return new Pair<String, String>(vdiUUID, basicErrMsg);
}

View File

@ -132,4 +132,6 @@ public interface SnapshotManager {
void downloadSnapshotsFromSwift(SnapshotVO ss);
String getSecondaryStorageURL(SnapshotVO snapshot);
void deleteSnapshotsForVolume (String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId );
}

View File

@ -38,6 +38,7 @@ import com.cloud.agent.api.DeleteSnapshotBackupCommand;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.agent.api.ManageSnapshotAnswer;
import com.cloud.agent.api.ManageSnapshotCommand;
import com.cloud.agent.api.downloadSnapshotFromSwiftCommand;
import com.cloud.agent.api.to.SwiftTO;
import com.cloud.api.commands.CreateSnapshotPolicyCmd;
import com.cloud.api.commands.DeleteSnapshotPoliciesCmd;
@ -504,41 +505,60 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
// No need to do anything as snapshot has already been backed up.
}
}
void setupSnapshotChain(SnapshotVO ss, List<String> snapshots){
}
void downloadSnapshotFromSwift(SnapshotVO ss) {
@Override
public void deleteSnapshotsForVolume (String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId ){
DeleteSnapshotsDirCommand cmd = new DeleteSnapshotsDirCommand("", secondaryStoragePoolUrl, dcId, accountId, volumeId, "");
try {
Answer ans = _agentMgr.sendToSSVM(dcId, cmd);
if ( ans == null || !ans.getResult() ) {
s_logger.warn("DeleteSnapshotsDirCommand failed due to " + ans.getDetails() + " volume id: " + volumeId );
}
} catch (Exception e) {
s_logger.warn("DeleteSnapshotsDirCommand failed due to" + e.toString() + " volume id: " + volumeId );
}
}
@Override
public void downloadSnapshotsFromSwift(SnapshotVO ss) {
List<String> snapshots = new ArrayList<String>(20);
long volumeId = ss.getVolumeId();
VolumeVO volume = _volsDao.findById(volumeId);
Long dcId = volume.getDataCenterId();
Long accountId = volume.getAccountId();
HostVO secHost = _storageMgr.getSecondaryStorageHost(dcId);
String secondaryStoragePoolUrl = secHost.getStorageUrl();
Long swiftId = ss.getSwiftId();
SwiftVO swift = _swiftDao.findById(swiftId);
SwiftTO swiftTO = toSwiftTO(swift);
SnapshotVO tss = ss;
List<String> BackupUuids = new ArrayList<String>(30);
while (true) {
BackupUuids.add(0, tss.getBackupSnapshotId());
if (tss.getPrevSnapshotId() == 0)
break;
Long id = tss.getPrevSnapshotId();
tss = _snapshotDao.findById(id);
assert tss != null : " can not find snapshot " + id;
}
String parent = null;
try {
while(true) {
assert tss.getSwiftName() != null : " SwiftName is null";
downloadSnapshotFromSwift(tss);
snapshots.add(tss.getSwiftName().split("_")[0]);
if( tss.getPrevSnapshotId() == 0)
break;
Long id = tss.getPrevSnapshotId();
tss = _snapshotDao.findById(id);
assert tss != null : " can not find snapshot " + id;
for (String backupUuid : BackupUuids) {
downloadSnapshotFromSwiftCommand cmd = new downloadSnapshotFromSwiftCommand(swiftTO, secondaryStoragePoolUrl, dcId, accountId, volumeId, parent, backupUuid, _backupsnapshotwait);
Answer answer = _agentMgr.sendToSSVM(dcId, cmd);
if ((answer == null) || !answer.getResult()) {
throw new CloudRuntimeException("downloadSnapshotsFromSwift failed ");
}
parent = backupUuid;
}
setupSnapshotChain(ss, snapshots);
} catch (Exception e) {
throw new CloudRuntimeException("downloadSnapshotsFromSwift failed due to " + e.toString());
}
}
private SwiftTO toSwiftTO(SwiftVO swift) {
return new SwiftTO(swift.getUrl(), swift.getAccount(), swift.getUserName(), swift.getKey());
}
@ -585,8 +605,8 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
prevBackupUuid = prevSnapshot.getBackupSnapshotId();
prevSnapshotUuid = prevSnapshot.getPath();
}
} else if ( prevSnapshot.getSwiftName() != null && swift != null ) {
prevBackupUuid = prevSnapshot.getSwiftName();
} else if ( prevSnapshot.getSwiftId() != null && swift != null ) {
prevBackupUuid = prevSnapshot.getBackupSnapshotId();
prevSnapshotUuid = prevSnapshot.getPath();
}
}
@ -619,7 +639,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
if (backedUp) {
if (backupSnapshotCommand.getSwift() != null ) {
snapshot.setSwiftId(1L);
snapshot.setSwiftName(backedUpSnapshotUuid);
snapshot.setBackupSnapshotId(backedUpSnapshotUuid);
} else {
snapshot.setSecHostId(secHost.getId());
snapshot.setBackupSnapshotId(backedUpSnapshotUuid);
@ -726,7 +746,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
if (snapshot.getBackupSnapshotId() != null) {
List<SnapshotVO> snaps = _snapshotDao.listByBackupUuid(snapshot.getVolumeId(), snapshot.getBackupSnapshotId());
if (!snaps.isEmpty()) {
if (snaps != null && snaps.size() > 1) {
snapshot.setBackupSnapshotId(null);
_snapshotDao.update(snapshot.getId(), snapshot);
}
@ -763,7 +783,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
String BackupSnapshotId = lastSnapshot.getBackupSnapshotId();
if (BackupSnapshotId != null) {
List<SnapshotVO> snaps = _snapshotDao.listByBackupUuid(lastSnapshot.getVolumeId(), BackupSnapshotId);
if (snaps != null && !snaps.isEmpty()) {
if (snaps != null && snaps.size() > 1) {
lastSnapshot.setBackupSnapshotId(null);
_snapshotDao.update(lastSnapshot.getId(), lastSnapshot);
} else {
@ -793,11 +813,21 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
@Override
public String getSecondaryStorageURL(SnapshotVO snapshot) {
HostVO secHost = _hostDao.findById(snapshot.getSecHostId());
return secHost.getStorageUrl();
HostVO secHost = null;
if( snapshot.getSwiftId() == null ) {
secHost = _hostDao.findById(snapshot.getSecHostId());
} else {
Long dcId = snapshot.getDataCenterId();
secHost = _storageMgr.getSecondaryStorageHost(dcId);
}
if (secHost != null) {
return secHost.getStorageUrl();
}
throw new CloudRuntimeException("Can not find secondary storage");
}
@Override
@DB
public boolean destroySnapshotBackUp(long snapshotId) {

View File

@ -1426,12 +1426,13 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
StoragePoolVO pool = null;
HostVO secondaryStorageHost = null;
long zoneId;
Long zoneId = null;
Long accountId = null;
SnapshotVO snapshot = null;
String secondaryStorageURL = null;
try {
if (snapshotId != null) { // create template from snapshot
SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
snapshot = _snapshotDao.findById(snapshotId);
if (snapshot == null) {
throw new CloudRuntimeException("Unable to find Snapshot for Id " + snapshotId);
}
@ -1440,7 +1441,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
if (secondaryStorageHost == null) {
throw new CloudRuntimeException("Secondary storage " + snapshot.getSecHostId() + " doesn't exist");
}
String secondaryStorageURL = secondaryStorageHost.getStorageUrl();
secondaryStorageURL = secondaryStorageHost.getStorageUrl();
String name = command.getTemplateName();
String backupSnapshotUUID = snapshot.getBackupSnapshotId();
@ -1495,7 +1496,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
}
}
}
if( snapshot.getSwiftName() != null ) {
if( snapshot.getSwiftId() != null ) {
_snapshotMgr.downloadSnapshotsFromSwift(snapshot);
}
cmd = new CreatePrivateTemplateFromSnapshotCommand(pool.getUuid(), secondaryStorageURL, dcId, accountId, snapshot.getVolumeId(), backupSnapshotUUID, snapshot.getName(),
@ -1517,7 +1518,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
if (secondaryStorageHost == null) {
throw new CloudRuntimeException("Can not find the secondary storage for zoneId " + zoneId);
}
String secondaryStorageURL = secondaryStorageHost.getStorageUrl();
secondaryStorageURL = secondaryStorageHost.getStorageUrl();
pool = _storagePoolDao.findById(volume.getPoolId());
cmd = new CreatePrivateTemplateFromVolumeCommand(secondaryStorageURL, templateId, accountId, command.getTemplateName(), uniqueName, volume.getPath(), vmName, _createprivatetemplatefromvolumewait);
@ -1592,6 +1593,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
txn.commit();
}
} finally {
if (snapshot != null && snapshot.getSwiftId() != null && secondaryStorageURL != null && zoneId != null && accountId != null && volumeId != null) {
_snapshotMgr.deleteSnapshotsForVolume (secondaryStorageURL, zoneId, accountId, volumeId);
}
if (privateTemplate == null) {
Transaction txn = Transaction.currentTxn();
txn.start();

View File

@ -434,7 +434,6 @@ CREATE TABLE `cloud`.`snapshots` (
`removed` datetime COMMENT 'Date removed. not null if removed',
`backup_snap_id` varchar(255) COMMENT 'Back up uuid of the snapshot',
`swift_id` bigint unsigned COMMENT 'which swift',
`swift_name` varchar(255) COMMENT 'Back up name in swift',
`sechost_id` bigint unsigned COMMENT 'secondary storage host id',
`prev_snap_id` bigint unsigned COMMENT 'Id of the most recent snapshot',
`hypervisor_type` varchar(32) NOT NULL COMMENT 'hypervisor that the snapshot was taken under',