Swift : upload template to Swift and sync between Swift and secondary storage

This commit is contained in:
anthony 2011-10-24 18:48:16 -07:00
parent 0df249172d
commit 510d1dbef7
22 changed files with 761 additions and 154 deletions

View File

@ -1216,7 +1216,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
Long dcId = cmd.getDataCenterId();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
String secondaryStoragePoolURL = cmd.getSecondaryStoragePoolURL();
String secondaryStoragePoolUrl = cmd.getSecondaryStorageUrl();
String snapshotName = cmd.getSnapshotName();
String snapshotPath = cmd.getVolumePath();
String snapshotDestPath = null;
@ -1224,7 +1224,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
try {
Connect conn = LibvirtConnection.getConnection();
StoragePool secondaryStoragePool = _storageResource.getStoragePoolbyURI(conn, new URI(secondaryStoragePoolURL));
StoragePool secondaryStoragePool = _storageResource.getStoragePoolbyURI(conn, new URI(secondaryStoragePoolUrl));
LibvirtStoragePoolDef spd = _storageResource.getStoragePoolDef(conn, secondaryStoragePool);
String ssPmountPath = spd.getTargetPath();
snapshotDestPath = ssPmountPath + File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId;
@ -1288,7 +1288,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
try {
Connect conn = LibvirtConnection.getConnection();
/*Make sure secondary storage is mounted*/
_storageResource.getStoragePoolbyURI(conn, new URI(cmd.getSecondaryStoragePoolURL()));
_storageResource.getStoragePoolbyURI(conn, new URI(cmd.getSecondaryStorageUrl()));
String snapshotPath = cmd.getSnapshotUuid();
String primaryUuid = cmd.getPrimaryStoragePoolNameLabel();
@ -1326,7 +1326,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
StoragePool secondaryPool;
try {
Connect conn = LibvirtConnection.getConnection();
secondaryPool = _storageResource.getStoragePoolbyURI(conn, new URI(cmd.getSecondaryStoragePoolURL()));
secondaryPool = _storageResource.getStoragePoolbyURI(conn, new URI(cmd.getSecondaryStorageUrl()));
LibvirtStoragePoolDef spd = _storageResource.getStoragePoolDef(conn, secondaryPool);
String templatePath = spd.getTargetPath() + File.separator + templateInstallFolder;
_storage.mkdirs(templatePath);
@ -1396,7 +1396,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
protected CreatePrivateTemplateAnswer execute(CreatePrivateTemplateFromVolumeCommand cmd) {
String secondaryStorageURL = cmd.getSecondaryStorageURL();
String secondaryStorageURL = cmd.getSecondaryStorageUrl();
StoragePool secondaryStorage = null;
try {

View File

@ -16,57 +16,57 @@
*
*/
package com.cloud.agent.api;
package com.cloud.agent.api;
public class CreatePrivateTemplateFromVolumeCommand extends SnapshotCommand {
private String _vmName;
private String _volumePath;
private String _userSpecifiedName;
private String _uniqueName;
private String _vmName;
private String _volumePath;
private String _userSpecifiedName;
private String _uniqueName;
private long _templateId;
private long _accountId;
// For XenServer
private String _secondaryStorageURL;
public CreatePrivateTemplateFromVolumeCommand() {}
public CreatePrivateTemplateFromVolumeCommand(String secondaryStorageURL, long templateId, long accountId, String userSpecifiedName, String uniqueName, String volumePath, String vmName, int wait) {
_secondaryStorageURL = secondaryStorageURL;
_templateId = templateId;
_accountId = accountId;
_userSpecifiedName = userSpecifiedName;
_uniqueName = uniqueName;
private long _accountId;
// For XenServer
private String _secondaryStorageUrl;
public CreatePrivateTemplateFromVolumeCommand() {
}
public CreatePrivateTemplateFromVolumeCommand(String secondaryStorageUrl, long templateId, long accountId, String userSpecifiedName, String uniqueName, String volumePath, String vmName, int wait) {
_secondaryStorageUrl = secondaryStorageUrl;
_templateId = templateId;
_accountId = accountId;
_userSpecifiedName = userSpecifiedName;
_uniqueName = uniqueName;
_volumePath = volumePath;
_vmName = vmName;
setWait(wait);
}
@Override
public boolean executeInSequence() {
return false;
}
public String getSecondaryStorageURL() {
return _secondaryStorageURL;
}
public String getTemplateName() {
return _userSpecifiedName;
}
public String getUniqueName() {
return _uniqueName;
}
public long getTemplateId() {
return _templateId;
setWait(wait);
}
@Override
public boolean executeInSequence() {
return false;
}
public String getSecondaryStorageUrl() {
return _secondaryStorageUrl;
}
public String getTemplateName() {
return _userSpecifiedName;
}
public String getUniqueName() {
return _uniqueName;
}
public long getTemplateId() {
return _templateId;
}
public String getVmName() {
return _vmName;
return _vmName;
}
public void setVolumePath(String _volumePath) {
this._volumePath = _volumePath;
}
@ -76,10 +76,10 @@ public class CreatePrivateTemplateFromVolumeCommand extends SnapshotCommand {
}
public Long getAccountId() {
return _accountId;
}
public void setTemplateId(long templateId) {
_templateId = templateId;
}
}
return _accountId;
}
public void setTemplateId(long templateId) {
_templateId = templateId;
}
}

View File

@ -22,7 +22,7 @@ package com.cloud.agent.api;
* This currently assumes that the secondary storage are mounted on the XenServer.
*/
public class DeleteSnapshotsDirCommand extends Command {
String secondaryStoragePoolURL;
String secondaryStorageUrl;
Long dcId;
Long accountId;
Long volumeId;
@ -31,10 +31,10 @@ public class DeleteSnapshotsDirCommand extends Command {
}
public DeleteSnapshotsDirCommand(String secondaryStoragePoolURL,
public DeleteSnapshotsDirCommand(String secondaryStorageUrl,
Long dcId, Long accountId, Long volumeId)
{
this.secondaryStoragePoolURL = secondaryStoragePoolURL;
this.secondaryStorageUrl = secondaryStorageUrl;
this.dcId = dcId;
this.accountId = accountId;
this.volumeId = volumeId;
@ -45,8 +45,8 @@ public class DeleteSnapshotsDirCommand extends Command {
return true;
}
public String getSecondaryStoragePoolURL() {
return secondaryStoragePoolURL;
public String getSecondaryStorageUrl() {
return secondaryStorageUrl;
}
public Long getDcId() {

View File

@ -28,7 +28,7 @@ public class SnapshotCommand extends Command {
private String primaryStoragePoolNameLabel;
private String snapshotUuid;
private String snapshotName;
private String secondaryStoragePoolURL;
private String secondaryStorageUrl;
private Long dcId;
private Long accountId;
private Long volumeId;
@ -46,7 +46,7 @@ public class SnapshotCommand extends Command {
* If you have better ideas on how to get it, you are welcome.
*/
public SnapshotCommand(String primaryStoragePoolNameLabel,
String secondaryStoragePoolURL,
String secondaryStorageUrl,
String snapshotUuid,
String snapshotName,
Long dcId,
@ -55,7 +55,7 @@ public class SnapshotCommand extends Command {
{
this.primaryStoragePoolNameLabel = primaryStoragePoolNameLabel;
this.snapshotUuid = snapshotUuid;
this.secondaryStoragePoolURL = secondaryStoragePoolURL;
this.secondaryStorageUrl = secondaryStorageUrl;
this.dcId = dcId;
this.accountId = accountId;
this.volumeId = volumeId;
@ -83,8 +83,8 @@ public class SnapshotCommand extends Command {
/**
* @return the secondaryStoragePoolURL
*/
public String getSecondaryStoragePoolURL() {
return secondaryStoragePoolURL;
public String getSecondaryStorageUrl() {
return secondaryStorageUrl;
}

View File

@ -35,9 +35,9 @@ public class downloadSnapshotFromSwiftCommand extends SnapshotCommand {
}
public downloadSnapshotFromSwiftCommand(SwiftTO swift, String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId, String parent, String BackupUuid, int wait) {
public downloadSnapshotFromSwiftCommand(SwiftTO swift, String secondaryStorageUrl, Long dcId, Long accountId, Long volumeId, String parent, String BackupUuid, int wait) {
super("", secondaryStoragePoolUrl, BackupUuid, "", dcId, accountId, volumeId);
super("", secondaryStorageUrl, BackupUuid, "", dcId, accountId, volumeId);
setParent(parent);
setSwift(swift);
setWait(wait);

View File

@ -0,0 +1,80 @@
/**
* Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.agent.api;
import com.cloud.agent.api.to.SwiftTO;
/**
*
* @author Anthony Xu
*
*/
public class downloadTemplateFromSwiftToSecondaryStorageCommand extends Command {
private SwiftTO swift;
private String secondaryStorageUrl;
private Long dcId;
private Long accountId;
private Long templateId;
protected downloadTemplateFromSwiftToSecondaryStorageCommand() {
}
public downloadTemplateFromSwiftToSecondaryStorageCommand(SwiftTO swift, String secondaryStorageUrl, Long dcId, Long accountId, Long templateId, int wait) {
this.swift = swift;
this.secondaryStorageUrl = secondaryStorageUrl;
this.dcId = dcId;
this.accountId = accountId;
this.templateId = templateId;
setWait(wait);
}
public SwiftTO getSwift() {
return this.swift;
}
public void setSwift(SwiftTO swift) {
this.swift = swift;
}
public String getSecondaryStorageUrl() {
return secondaryStorageUrl;
}
public Long getDcId() {
return dcId;
}
public Long getAccountId() {
return accountId;
}
public Long getTemplateId() {
return templateId;
}
@Override
public boolean executeInSequence() {
// TODO Auto-generated method stub
return true;
}
}

View File

@ -18,7 +18,7 @@
package com.cloud.agent.api.to;
public class SwiftTO {
Long id;
String url;
String account;
@ -27,13 +27,18 @@ public class SwiftTO {
public SwiftTO() { }
public SwiftTO(String url, String account, String userName, String key) {
public SwiftTO(Long id, String url, String account, String userName, String key) {
this.id = id;
this.url = url;
this.account = account;
this.userName = userName;
this.key = key;
}
public Long getId() {
return id;
}
public String getUrl() {
return url;
}

View File

@ -0,0 +1,80 @@
/**
* Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.agent.api;
import com.cloud.agent.api.to.SwiftTO;
/**
*
* @author Anthony Xu
*
*/
public class uploadTemplateToSwiftFromSecondaryStorageCommand extends Command {
private SwiftTO swift;
private String secondaryStorageUrl;
private Long dcId;
private Long accountId;
private Long templateId;
protected uploadTemplateToSwiftFromSecondaryStorageCommand() {
}
public uploadTemplateToSwiftFromSecondaryStorageCommand(SwiftTO swift, String secondaryStorageUrl, Long dcId, Long accountId, Long templateId, int wait) {
this.swift = swift;
this.secondaryStorageUrl = secondaryStorageUrl;
this.dcId = dcId;
this.accountId = accountId;
this.templateId = templateId;
setWait(wait);
}
public SwiftTO getSwift() {
return this.swift;
}
public void setSwift(SwiftTO swift) {
this.swift = swift;
}
public String getSecondaryStorageUrl() {
return secondaryStorageUrl;
}
public Long getDcId() {
return dcId;
}
public Long getAccountId() {
return accountId;
}
public Long getTemplateId() {
return templateId;
}
@Override
public boolean executeInSequence() {
// TODO Auto-generated method stub
return true;
}
}

View File

@ -141,8 +141,8 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
public Answer execute(VmwareHostService hostService, BackupSnapshotCommand cmd) {
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
String secondaryStoragePoolURL = cmd.getSecondaryStoragePoolURL();
String snapshotUuid = cmd.getSnapshotUuid(); // not null: Precondition.
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
String snapshotUuid = cmd.getSnapshotUuid(); // not null: Precondition.
String prevSnapshotUuid = cmd.getPrevSnapshotUuid();
String prevBackupUuid = cmd.getPrevBackupUuid();
VirtualMachineMO workerVm=null;
@ -214,11 +214,8 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
}
}
snapshotBackupUuid = backupSnapshotToSecondaryStorage(vmMo, accountId,
volumeId, cmd.getVolumePath(), snapshotUuid,
secondaryStoragePoolURL, prevSnapshotUuid,
prevBackupUuid,
hostService.getWorkerName(context, cmd));
snapshotBackupUuid = backupSnapshotToSecondaryStorage(vmMo, accountId, volumeId, cmd.getVolumePath(), snapshotUuid, secondaryStorageUrl, prevSnapshotUuid, prevBackupUuid,
hostService.getWorkerName(context, cmd));
success = (snapshotBackupUuid != null);
@ -244,7 +241,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
@Override
public Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromVolumeCommand cmd) {
String secondaryStoragePoolURL = cmd.getSecondaryStorageURL();
String secondaryStoragePoolURL = cmd.getSecondaryStorageUrl();
String volumePath = cmd.getVolumePath();
Long accountId = cmd.getAccountId();
Long templateId = cmd.getTemplateId();
@ -292,7 +289,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
public Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromSnapshotCommand cmd) {
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
String secondaryStoragePoolURL = cmd.getSecondaryStoragePoolURL();
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
String backedUpSnapshotUuid = cmd.getSnapshotUuid();
Long newTemplateId = cmd.getNewTemplateId();
String details;
@ -301,8 +298,8 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
VmwareContext context = hostService.getServiceContext(cmd);
try {
Ternary<String, Long, Long> result = createTemplateFromSnapshot(accountId,
newTemplateId, uniqeName,
secondaryStoragePoolURL, volumeId,
newTemplateId, uniqeName,
secondaryStorageUrl, volumeId,
backedUpSnapshotUuid);
return new CreatePrivateTemplateAnswer(cmd, true, null,
@ -375,7 +372,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
String primaryStorageNameLabel = cmd.getPrimaryStoragePoolNameLabel();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
String secondaryStoragePoolURL = cmd.getSecondaryStoragePoolURL();
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
String backedUpSnapshotUuid = cmd.getSnapshotUuid();
String details = null;
@ -396,7 +393,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs);
details = createVolumeFromSnapshot(hyperHost, primaryDsMo,
newVolumeName, accountId, volumeId,
secondaryStoragePoolURL, backedUpSnapshotUuid);
secondaryStorageUrl, backedUpSnapshotUuid);
if (details == null) {
success = true;
}

View File

@ -131,7 +131,6 @@ 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;
@ -3018,36 +3017,6 @@ 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) {
@ -5758,7 +5727,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
protected CreatePrivateTemplateAnswer execute(final CreatePrivateTemplateFromVolumeCommand cmd) {
Connection conn = getConnection();
String secondaryStoragePoolURL = cmd.getSecondaryStorageURL();
String secondaryStoragePoolURL = cmd.getSecondaryStorageUrl();
String volumeUUID = cmd.getVolumePath();
Long accountId = cmd.getAccountId();
String userSpecifiedName = cmd.getTemplateName();
@ -5818,7 +5787,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
protected Answer execute(final UpgradeSnapshotCommand cmd) {
String secondaryStoragePoolURL = cmd.getSecondaryStoragePoolURL();
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
String backedUpSnapshotUuid = cmd.getSnapshotUuid();
Long volumeId = cmd.getVolumeId();
Long accountId = cmd.getAccountId();
@ -5831,7 +5800,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
try {
Connection conn = getConnection();
URI uri = new URI(secondaryStoragePoolURL);
URI uri = new URI(secondaryStorageUrl);
String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
String snapshotPath = secondaryStorageMountPath + "/snapshots/" + accountId + "/" + volumeId + "/" + backedUpSnapshotUuid + ".vhd";
String templatePath = secondaryStorageMountPath + "/template/tmpl/" + tmpltAcountId + "/" + templateId;
@ -5849,7 +5818,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
Connection conn = getConnection();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
String secondaryStoragePoolURL = cmd.getSecondaryStoragePoolURL();
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
String backedUpSnapshotUuid = cmd.getSnapshotUuid();
Long newTemplateId = cmd.getNewTemplateId();
String userSpecifiedName = cmd.getTemplateName();
@ -5858,7 +5827,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
String details = null;
boolean result = false;
try {
URI uri = new URI(secondaryStoragePoolURL);
URI uri = new URI(secondaryStorageUrl);
String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
String installPath = "template/tmpl/" + accountId + "/" + newTemplateId;
if( !createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath)) {
@ -5930,7 +5899,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
Long dcId = cmd.getDataCenterId();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
String secondaryStoragePoolURL = cmd.getSecondaryStoragePoolURL();
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
String snapshotUuid = cmd.getSnapshotUuid(); // not null: Precondition.
String prevBackupUuid = cmd.getPrevBackupUuid();
String prevSnapshotUuid = cmd.getPrevSnapshotUuid();
@ -5947,7 +5916,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
String psUuid = primaryStorageSR.getUuid(conn);
Boolean isISCSI = IsISCSI(primaryStorageSR.getType(conn));
URI uri = new URI(secondaryStoragePoolURL);
URI uri = new URI(secondaryStorageUrl);
String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid);
String snapshotPaUuid = null;
@ -5973,7 +5942,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
s_logger.warn(details);
return new BackupSnapshotAnswer(cmd, false, details, null, false);
}
String snapshotMountpoint = secondaryStoragePoolURL + "/" + folder;
String snapshotMountpoint = secondaryStorageUrl + "/" + folder;
SR snapshotSr = null;
try {
snapshotSr = createNfsSRbyURI(conn, new URI(snapshotMountpoint), false);
@ -5981,7 +5950,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
snapshotBackupUuid = backedVdi.getUuid(conn);
if( cmd.getSwift() != null ) {
try {
swiftBackupSnapshot(conn, cmd.getSwift(), snapshotSr.getUuid(conn), snapshotBackupUuid, volumeId.toString(), false, wait);
swiftBackupSnapshot(conn, cmd.getSwift(), snapshotSr.getUuid(conn), snapshotBackupUuid, "S-" + volumeId.toString(), false, wait);
} finally {
deleteSnapshotBackup(conn, dcId, accountId, volumeId, secondaryStorageMountPath, snapshotBackupUuid);
}
@ -5996,7 +5965,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
} else {
String primaryStorageSRUuid = primaryStorageSR.getUuid(conn);
if( cmd.getSwift() != null ) {
swiftBackupSnapshot(conn, cmd.getSwift(), primaryStorageSRUuid, snapshotPaUuid, volumeId.toString(), isISCSI, wait);
swiftBackupSnapshot(conn, cmd.getSwift(), primaryStorageSRUuid, snapshotPaUuid, "S-" + volumeId.toString(), isISCSI, wait);
if ( isISCSI ) {
snapshotBackupUuid = "VHD-" + snapshotPaUuid;
} else {
@ -6030,7 +5999,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
String primaryStorageNameLabel = cmd.getPrimaryStoragePoolNameLabel();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
String secondaryStoragePoolURL = cmd.getSecondaryStoragePoolURL();
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
String backedUpSnapshotUuid = cmd.getSnapshotUuid();
int wait = cmd.getWait();
boolean result = false;
@ -6039,8 +6008,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
String volumeUUID = null;
SR snapshotSR = null;
if (secondaryStoragePoolURL == null) {
details += " because the URL passed: " + secondaryStoragePoolURL + " is invalid.";
if (secondaryStorageUrl == null) {
details += " because the URL passed: " + secondaryStorageUrl + " is invalid.";
return new CreateVolumeFromSnapshotAnswer(cmd, result, details, volumeUUID);
}
try {
@ -6050,7 +6019,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
+ primaryStorageNameLabel);
}
// Get the absolute path of the snapshot on the secondary storage.
URI snapshotURI = new URI(secondaryStoragePoolURL + "/snapshots/" + accountId + "/" + volumeId );
URI snapshotURI = new URI(secondaryStorageUrl + "/snapshots/" + accountId + "/" + volumeId);
String filename = backedUpSnapshotUuid;
if ( !filename.startsWith("VHD-") && !filename.endsWith(".vhd")) {
filename = backedUpSnapshotUuid + ".vhd";

View File

@ -0,0 +1,101 @@
/**
* Copyright (C) 2011 Citrix Systems, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.storage;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import com.cloud.utils.db.GenericDaoBase;
/**
* Join table for swift and templates
*
* @author Anthony Xu
*
*/
@Entity
@Table(name = "template_swift_ref")
public class VMTemplateSwiftVO {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@Column(name = "swift_id")
private long swiftId;
@Column(name = "template_id")
private long templateId;
@Column(name = GenericDaoBase.CREATED_COLUMN)
private Date created = null;
@Column(name = "size")
private long size;
@Column(name = "physical_size")
private long physicalSize;
public VMTemplateSwiftVO(long swiftId, long templateId, Date created, long size, long physicalSize) {
this.swiftId = swiftId;
this.templateId = templateId;
this.created = created;
this.size = size;
this.physicalSize = physicalSize;
}
protected VMTemplateSwiftVO() {
}
public long getTemplateId() {
return templateId;
}
public long getId() {
return id;
}
public Date getCreated() {
return created;
}
public long getSwiftId() {
return swiftId;
}
public long getSize() {
return size;
}
public long getPhysicalSize() {
return physicalSize;
}
@Override
public String toString() {
return new StringBuilder("TmplSwift[").append(id).append("-").append(templateId).append("-").append(swiftId).append("]").toString();
}
}

View File

@ -57,6 +57,8 @@ 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.downloadTemplateFromSwiftToSecondaryStorageCommand;
import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand;
import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
import com.cloud.agent.api.storage.DeleteTemplateCommand;
@ -148,11 +150,60 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
return execute((downloadSnapshotFromSwiftCommand)cmd);
} else if (cmd instanceof DeleteSnapshotsDirCommand){
return execute((DeleteSnapshotsDirCommand)cmd);
} else if (cmd instanceof downloadTemplateFromSwiftToSecondaryStorageCommand) {
return execute((downloadTemplateFromSwiftToSecondaryStorageCommand) cmd);
} else if (cmd instanceof uploadTemplateToSwiftFromSecondaryStorageCommand) {
return execute((uploadTemplateToSwiftFromSecondaryStorageCommand) cmd);
} else {
return Answer.createUnsupportedCommandAnswer(cmd);
}
}
private Answer execute(downloadTemplateFromSwiftToSecondaryStorageCommand cmd) {
SwiftTO swift = cmd.getSwift();
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
Long accountId = cmd.getAccountId();
Long templateId = cmd.getTemplateId();
try {
String parent = getRootDir(secondaryStorageUrl);
String lPath = parent + "/template/tmpl/" + accountId.toString() + "/" + templateId.toString();
String result = swiftDownload(swift, "T-" + templateId.toString(), "", lPath);
if (result != null) {
String errMsg = "failed to download template from Swift to secondary storage " + 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);
}
}
private Answer execute(uploadTemplateToSwiftFromSecondaryStorageCommand cmd) {
SwiftTO swift = cmd.getSwift();
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
Long accountId = cmd.getAccountId();
Long templateId = cmd.getTemplateId();
try {
String parent = getRootDir(secondaryStorageUrl);
String lPath = parent + "/template/tmpl/" + accountId.toString() + "/" + templateId.toString();
String result = swiftUpload(swift, "T-" + templateId.toString(), lPath, "*");
if (result != null) {
String errMsg = "failed to download template from Swift to secondary storage " + 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);
}
}
String swiftDownload(SwiftTO swift, String container, String rfilename, String lFullPath) {
Script command = new Script("/bin/bash", s_logger);
command.add("-c");
@ -201,11 +252,11 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
public Answer execute(DeleteSnapshotsDirCommand cmd){
String secondaryStorageURL = cmd.getSecondaryStoragePoolURL();
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
try {
String parent = getRootDir(secondaryStorageURL);
String parent = getRootDir(secondaryStorageUrl);
String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId) + "/*";
String result = deleteLocalFile(lPath);
if (result != null) {
@ -223,14 +274,14 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
public Answer execute(downloadSnapshotFromSwiftCommand cmd){
SwiftTO swift = cmd.getSwift();
String secondaryStorageURL = cmd.getSecondaryStoragePoolURL();
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
String rFilename = cmd.getSnapshotUuid();
String sParent = cmd.getParent();
String errMsg = "";
try {
String parent = getRootDir(secondaryStorageURL);
String parent = getRootDir(secondaryStorageUrl);
String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId);
String result = createLocalDir(lPath);
@ -244,7 +295,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
lFilename = rFilename.replace("VHD-", "") + ".vhd";
}
String lFullPath = lPath + "/" + lFilename;
result = swiftDownload(swift, volumeId.toString(), rFilename, lFullPath);
result = swiftDownload(swift, "S-" + volumeId.toString(), rFilename, lFullPath);
if (result != null) {
return new Answer(cmd, false, result);
}
@ -356,14 +407,14 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
}
protected Answer execute(final DeleteSnapshotBackupCommand cmd) {
String secondaryStorageURL = cmd.getSecondaryStoragePoolURL();
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
String name = cmd.getSnapshotUuid();
try {
SwiftTO swift = cmd.getSwift();
if (swift == null) {
String parent = getRootDir(secondaryStorageURL);
String parent = getRootDir(secondaryStorageUrl);
String filename;
if (cmd.isAll()) {
filename = "*";

View File

@ -1,5 +1,5 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
* Copyright (C) 2011 Citrix Systems, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
@ -16,12 +16,16 @@
*
*/
package com.cloud.storage.dao;
import java.util.List;
package com.cloud.storage.dao;
import com.cloud.storage.SwiftVO;
import com.cloud.utils.db.GenericDao;
/**
*
* @author Anthony Xu
*
*/
public interface SwiftDao extends GenericDao<SwiftVO, Long> {
}
}

View File

@ -1,5 +1,5 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
* Copyright (C) 2011 Citrix Systems, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
@ -17,13 +17,20 @@
*/
package com.cloud.storage.dao;
import javax.ejb.Local;
import com.cloud.storage.SwiftVO;
import javax.ejb.Local;
import org.apache.log4j.Logger;
import com.cloud.storage.SwiftVO;
import com.cloud.utils.db.GenericDaoBase;
/**
*
* @author Anthony Xu
*
*/
@Local (value={SwiftDao.class})
public class SwiftDaoImpl extends GenericDaoBase<SwiftVO, Long> implements SwiftDao {
public static final Logger s_logger = Logger.getLogger(SwiftDaoImpl.class.getName());
}
}

View File

@ -58,4 +58,6 @@ public interface VMTemplateHostDao extends GenericDao<VMTemplateHostVO, Long> {
VMTemplateHostVO findLocalSecondaryStorageByHostTemplate(long hostId, long templateId);
List<VMTemplateHostVO> listByTemplateHostStatus(long templateId, long hostId, Status... states);
List<VMTemplateHostVO> listByState(Status state);
}

View File

@ -287,7 +287,14 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase<VMTemplateHostVO, Long
sc.setParameters("template_id", templateId);
return search(sc, null);
}
}
@Override
public List<VMTemplateHostVO> listByState(VMTemplateHostVO.Status state) {
SearchCriteria<VMTemplateHostVO> sc = createSearchCriteria();
sc.addAnd("download_state", SearchCriteria.Op.EQ, state);
return search(sc, null);
}
@Override
public List<VMTemplateHostVO> listByHostTemplate(long hostId, long templateId) {

View File

@ -0,0 +1,40 @@
/**
* Copyright (C) 2011 Citrix Systems, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.storage.dao;
import java.util.List;
import com.cloud.storage.VMTemplateSwiftVO;
import com.cloud.utils.db.GenericDao;
/**
*
* @author Anthony Xu
*
*/
public interface VMTemplateSwiftDao extends GenericDao<VMTemplateSwiftVO, Long> {
List<VMTemplateSwiftVO> listBySwiftId(long id);
List<VMTemplateSwiftVO> listByTemplateId(long templateId);
VMTemplateSwiftVO findBySwiftTemplate(long swiftId, long templateId);
VMTemplateSwiftVO findOneByTemplateId(long templateId);
}

View File

@ -0,0 +1,88 @@
/**
* Copyright (C) 2011 Citrix Systems, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.storage.dao;
import java.util.Collections;
import java.util.List;
import javax.ejb.Local;
import org.apache.log4j.Logger;
import com.cloud.storage.VMTemplateSwiftVO;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
/**
*
* @author Anthony Xu
*
*/
@Local(value = { VMTemplateSwiftDao.class })
public class VMTemplateSwiftDaoImpl extends GenericDaoBase<VMTemplateSwiftVO, Long> implements VMTemplateSwiftDao {
public static final Logger s_logger = Logger.getLogger(VMTemplateSwiftDaoImpl.class.getName());
protected final SearchBuilder<VMTemplateSwiftVO> AllFieldSearch;
public VMTemplateSwiftDaoImpl() {
AllFieldSearch = createSearchBuilder();
AllFieldSearch.and("swift_id", AllFieldSearch.entity().getSwiftId(), SearchCriteria.Op.EQ);
AllFieldSearch.and("template_id", AllFieldSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
AllFieldSearch.done();
}
@Override
public List<VMTemplateSwiftVO> listBySwiftId(long id) {
SearchCriteria<VMTemplateSwiftVO> sc = AllFieldSearch.create();
sc.setParameters("swift_id", id);
return listBy(sc);
}
@Override
public List<VMTemplateSwiftVO> listByTemplateId(long templateId) {
SearchCriteria<VMTemplateSwiftVO> sc = AllFieldSearch.create();
sc.setParameters("template_id", templateId);
return listBy(sc);
}
@Override
public VMTemplateSwiftVO findOneByTemplateId(long templateId) {
SearchCriteria<VMTemplateSwiftVO> sc = AllFieldSearch.create();
sc.setParameters("template_id", templateId);
List<VMTemplateSwiftVO> list = listBy(sc);
if (list == null || list.size() < 1) {
return null;
} else {
Collections.shuffle(list);
return list.get(0);
}
}
@Override
public VMTemplateSwiftVO findBySwiftTemplate(long swiftId, long templateId) {
SearchCriteria<VMTemplateSwiftVO> sc = AllFieldSearch.create();
sc.setParameters("swift_id", swiftId);
sc.setParameters("template_id", templateId);
return findOneBy(sc);
}
}

View File

@ -19,6 +19,7 @@ package com.cloud.storage.snapshot;
import java.util.List;
import com.cloud.agent.api.to.SwiftTO;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.host.HostVO;
import com.cloud.storage.SnapshotPolicyVO;
@ -139,4 +140,6 @@ public interface SnapshotManager {
void deleteSnapshotsForVolume (String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId );
void deleteSnapshotsDirForVolume(String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId);
SwiftTO getSwiftTO(Long id);
}

View File

@ -578,7 +578,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
}
private SwiftTO toSwiftTO(SwiftVO swift) {
return new SwiftTO(swift.getUrl(), swift.getAccount(), swift.getUserName(), swift.getKey());
return new SwiftTO(swift.getId(), swift.getUrl(), swift.getAccount(), swift.getUserName(), swift.getKey());
}
@Override
@ -870,7 +870,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
if (backupOfSnapshot == null) {
return true;
}
SwiftTO swift = getSwiftTO();
SwiftTO swift = getSwiftTO(null);
DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand(swift, secondaryStoragePoolUrl, dcId, accountId, volumeId, backupOfSnapshot, false);
Answer answer = _agentMgr.sendToSSVM(dcId, cmd);
@ -1036,8 +1036,10 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
return _snapshotDao.search(sc, searchFilter);
}
private SwiftTO getSwiftTO() {
SwiftVO swiftVO = _swiftDao.findById(1l);
@Override
public SwiftTO getSwiftTO(Long swiftId) {
long id = swiftId == null ? 1 : swiftId;
SwiftVO swiftVO = _swiftDao.findById(id);
if (swiftVO != null) {
return toSwiftTO(swiftVO);
}
@ -1062,7 +1064,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
continue;
}
List<HostVO> ssHosts = _hostDao.listSecondaryStorageHosts(dcId);
SwiftTO swift = getSwiftTO();
SwiftTO swift = getSwiftTO(null);
if (swift == null) {
for (HostVO ssHost : ssHosts) {
DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand(null, ssHost.getStorageUrl(), dcId, accountId, volumeId, "", true);

View File

@ -23,10 +23,13 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
@ -36,9 +39,12 @@ import org.apache.log4j.Logger;
import com.cloud.acl.SecurityChecker.AccessType;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.downloadTemplateFromSwiftToSecondaryStorageCommand;
import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand;
import com.cloud.agent.api.storage.DestroyCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.api.to.SwiftTO;
import com.cloud.api.commands.CopyTemplateCmd;
import com.cloud.api.commands.DeleteIsoCmd;
import com.cloud.api.commands.DeleteTemplateCmd;
@ -85,18 +91,22 @@ import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateStoragePoolVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateSwiftVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.StoragePoolDao;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.SwiftDao;
import com.cloud.storage.dao.UploadDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateHostDao;
import com.cloud.storage.dao.VMTemplatePoolDao;
import com.cloud.storage.dao.VMTemplateSwiftDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.download.DownloadMonitor;
import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.storage.upload.UploadMonitor;
import com.cloud.template.TemplateAdapter.TemplateAdapterType;
import com.cloud.user.Account;
@ -116,6 +126,7 @@ import com.cloud.utils.component.Inject;
import com.cloud.utils.component.Manager;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
@ -153,6 +164,12 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe
@Inject UserVmDao _userVmDao;
@Inject VolumeDao _volumeDao;
@Inject SnapshotDao _snapshotDao;
@Inject
SnapshotManager _snapshotMgr;
@Inject
SwiftDao _swiftDao;
@Inject
VMTemplateSwiftDao _tmpltSwiftDao;
@Inject DomainDao _domainDao;
@Inject UploadDao _uploadDao;
long _routerTemplateId = -1;
@ -168,7 +185,9 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe
int _storagePoolMaxWaitSeconds = 3600;
ExecutorService _preloadExecutor;
ScheduledExecutorService _swiftTemplateSyncExecutor;
@Inject (adapter=TemplateAdapter.class)
protected Adapters<TemplateAdapter> _adapters;
@ -380,12 +399,95 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe
}
}
String downloadTemplateFromSwiftToSecondaryStorage(long dcId, long templateId){
VMTemplateVO template = _tmpltDao.findById(templateId);
if ( template == null ) {
String errMsg = " Can not find template " + templateId;
s_logger.warn(errMsg);
return errMsg;
}
VMTemplateSwiftVO tmpltSwift = _tmpltSwiftDao.findOneByTemplateId(templateId);
if ( tmpltSwift == null ) {
String errMsg = " Template " + templateId + " doesn't exist in swift";
s_logger.warn(errMsg);
return errMsg;
}
SwiftTO swift = _snapshotMgr.getSwiftTO(tmpltSwift.getSwiftId());
if ( swift == null ) {
String errMsg = " Swift " + tmpltSwift.getSwiftId() + " doesn't exit ?";
s_logger.warn(errMsg);
return errMsg;
}
HostVO secHost = _hostDao.findSecondaryStorageHost(dcId);
if ( secHost == null ) {
String errMsg = "Can not find secondary storage in data center " + dcId;
s_logger.warn(errMsg);
return errMsg;
}
downloadTemplateFromSwiftToSecondaryStorageCommand cmd = new downloadTemplateFromSwiftToSecondaryStorageCommand(swift, secHost.getName(), dcId, template.getAccountId(), templateId,
_primaryStorageDownloadWait);
try {
_agentMgr.sendToSSVM(dcId, cmd);
} catch (Exception e) {
String errMsg = "Failed to download template from Swift to secondary storage due to " + e.toString();
s_logger.warn(errMsg);
throw new CloudRuntimeException(errMsg);
}
return null;
}
String uploadTemplateToSwiftFromSecondaryStorage(VMTemplateHostVO templateHostRef) {
Long templateId = templateHostRef.getTemplateId();
VMTemplateVO template = _tmpltDao.findById(templateId);
if (template == null) {
String errMsg = " Can not find template " + templateId;
s_logger.warn(errMsg);
return errMsg;
}
SwiftTO swift = _snapshotMgr.getSwiftTO(null);
if (swift == null) {
String errMsg = " There is no Swift in this setup ";
s_logger.warn(errMsg);
return errMsg;
}
HostVO secHost = _hostDao.findById(templateHostRef.getHostId());
if (secHost == null) {
String errMsg = "Can not find secondary storage " + templateHostRef.getHostId();
s_logger.warn(errMsg);
return errMsg;
}
uploadTemplateToSwiftFromSecondaryStorageCommand cmd = new uploadTemplateToSwiftFromSecondaryStorageCommand(swift, secHost.getName(), secHost.getDataCenterId(), template.getAccountId(),
templateId, _primaryStorageDownloadWait);
Answer answer = null;
try {
answer = _agentMgr.sendToSSVM(secHost.getDataCenterId(), cmd);
if (answer == null || !answer.getResult()) {
String errMsg = "Failed to upload template to Swift from secondary storage due to " + ((answer == null) ? "null" : answer.getDetails());
s_logger.warn(errMsg);
throw new CloudRuntimeException(errMsg);
}
VMTemplateSwiftVO tmpltSwift = new VMTemplateSwiftVO(swift.getId(), secHost.getId(), new Date(), templateHostRef.getSize(), templateHostRef.getPhysicalSize());
_tmpltSwiftDao.persist(tmpltSwift);
} catch (Exception e) {
String errMsg = "Failed to upload template to Swift from secondary storage due to " + e.toString();
s_logger.warn(errMsg);
throw new CloudRuntimeException(errMsg);
}
return null;
}
@Override @DB
public VMTemplateStoragePoolVO prepareTemplateForCreate(VMTemplateVO template, StoragePool pool) {
template = _tmpltDao.findById(template.getId(), true);
long poolId = pool.getId();
long templateId = template.getId();
long dcId = pool.getDataCenterId();
VMTemplateStoragePoolVO templateStoragePoolRef = null;
VMTemplateHostVO templateHostRef = null;
long templateStoragePoolRefId;
@ -408,8 +510,11 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe
templateHostRef = _storageMgr.findVmTemplateHost(templateId, pool);
if (templateHostRef == null) {
s_logger.debug("Unable to find a secondary storage host who has completely downloaded the template.");
return null;
String result = downloadTemplateFromSwiftToSecondaryStorage(dcId, templateId);
if (result != null) {
s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
return null;
}
}
HostVO sh = _hostDao.findById(templateHostRef.getHostId());
@ -702,18 +807,69 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe
}
}
void swiftTemplateSync() {
GlobalLock swiftTemplateSyncLock = GlobalLock.getInternLock("templatemgr.swiftTemplateSync");
try {
if (swiftTemplateSyncLock.lock(3)) {
try {
List<VMTemplateHostVO> templtHostRefs = _tmpltHostDao.listByState(VMTemplateHostVO.Status.DOWNLOADED);
List<VMTemplateSwiftVO> templtSwiftRefs = _tmpltSwiftDao.listAll();
for (VMTemplateHostVO templtHostRef : templtHostRefs) {
boolean found = false;
for (VMTemplateSwiftVO templtSwiftRef : templtSwiftRefs) {
if (templtHostRef.getTemplateId() == templtSwiftRef.getTemplateId()) {
found = true;
break;
}
}
if (!found) {
try {
uploadTemplateToSwiftFromSecondaryStorage(templtHostRef);
} catch (Exception e) {
s_logger.debug("failed to upload template " + templtHostRef.getTemplateId() + " to Swift due to " + e.toString());
}
}
}
} catch (Throwable e) {
s_logger.error("Problem with sync swift template due to " + e.toString(), e);
} finally {
swiftTemplateSyncLock.unlock();
}
}
} finally {
swiftTemplateSyncLock.releaseRef();
}
}
@Override
public String getName() {
return _name;
}
private Runnable getSwiftTemplateSyncTask() {
return new Runnable() {
@Override
public void run() {
if (s_logger.isTraceEnabled()) {
s_logger.trace("Start Swift Template sync at" + (new Date()));
}
swiftTemplateSync();
if (s_logger.isTraceEnabled()) {
s_logger.trace("Finish Swift Template sync at" + (new Date()));
}
}
};
}
@Override
public boolean start() {
_swiftTemplateSyncExecutor.scheduleAtFixedRate(getSwiftTemplateSyncTask(), 120, 300, TimeUnit.SECONDS);
return true;
}
@Override
public boolean stop() {
_swiftTemplateSyncExecutor.shutdownNow();
return true;
}
@ -747,6 +903,7 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe
_storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
_preloadExecutor = Executors.newFixedThreadPool(8, new NamedThreadFactory("Template-Preloader"));
_swiftTemplateSyncExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("swift-template-sync-Executor"));
return false;
}

View File

@ -990,6 +990,20 @@ CREATE TABLE `cloud`.`template_host_ref` (
INDEX `i_template_host_ref__template_id`(`template_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`swift_host_ref` (
`id` bigint unsigned NOT NULL auto_increment,
`swift_id` bigint unsigned NOT NULL,
`template_id` bigint unsigned NOT NULL,
`created` DATETIME NOT NULL,
`size` bigint unsigned,
`physical_size` bigint unsigned DEFAULT 0,
PRIMARY KEY (`id`),
CONSTRAINT `fk_template_swift_ref__swift_id` FOREIGN KEY `fk_template_swift_ref__swift_id` (`swift_id`) REFERENCES `swift (`id`) ON DELETE CASCADE,
INDEX `i_template_swift_ref__host_id`(`swift_id`),
CONSTRAINT `fk_template_swift_ref__template_id` FOREIGN KEY `fk_template_swift_ref__template_id` (`template_id`) REFERENCES `vm_template` (`id`),
INDEX `i_template_swift_ref__template_id`(`template_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`template_zone_ref` (
`id` bigint unsigned NOT NULL auto_increment,
`zone_id` bigint unsigned NOT NULL,