mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-3681: fix bunch of bugs related to vmware, regarding to snapshot
This commit is contained in:
parent
29ee68821e
commit
7f200d966e
|
|
@ -18,9 +18,12 @@
|
|||
*/
|
||||
package com.cloud.agent.api.to;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
|
||||
public interface DataTO {
|
||||
public DataObjectType getObjectType();
|
||||
public DataStoreTO getDataStore();
|
||||
public Hypervisor.HypervisorType getHypervisorType();
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import com.cloud.agent.api.Command;
|
|||
import com.cloud.agent.api.to.NicTO;
|
||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.Adapter;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
|
@ -40,12 +41,13 @@ public interface HypervisorGuru extends Adapter {
|
|||
|
||||
/**
|
||||
* Give hypervisor guru opportunity to decide if certain command needs to be delegated to other host, mainly to secondary storage VM host
|
||||
*
|
||||
* @param hostId original hypervisor host
|
||||
* @param cmd command that is going to be sent, hypervisor guru usually needs to register various context objects into the command object
|
||||
*
|
||||
* @return delegated host id if the command will be delegated
|
||||
*/
|
||||
long getCommandHostDelegation(long hostId, Command cmd);
|
||||
Pair<Boolean, Long> getCommandHostDelegation(long hostId, Command cmd);
|
||||
|
||||
/**
|
||||
* @return true if VM can be migrated independently with CloudStack, and therefore CloudStack needs to track and reflect host change
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ public interface StorageProcessor {
|
|||
public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd);
|
||||
public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd);
|
||||
public Answer createTemplateFromVolume(CopyCommand cmd);
|
||||
public Answer createTemplateFromSnapshot(CopyCommand cmd);
|
||||
public Answer backupSnapshot(CopyCommand cmd);
|
||||
public Answer attachIso(AttachCommand cmd);
|
||||
public Answer attachVolume(AttachCommand cmd);
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@ public class StorageSubsystemCommandHandlerBase implements StorageSubsystemComma
|
|||
return processor.backupSnapshot(cmd);
|
||||
} else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.VOLUME) {
|
||||
return processor.createVolumeFromSnapshot(cmd);
|
||||
} else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.TEMPLATE) {
|
||||
return processor.createTemplateFromSnapshot(cmd);
|
||||
}
|
||||
|
||||
return new Answer(cmd, false, "not implemented yet");
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ public class SnapshotObjectTO implements DataTO {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HypervisorType getHypervisorType() {
|
||||
return hypervisorType;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.storage.to;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
||||
|
||||
import com.cloud.agent.api.to.DataObjectType;
|
||||
|
|
@ -38,6 +39,7 @@ public class TemplateObjectTO implements DataTO {
|
|||
private String name;
|
||||
private String guestOsType;
|
||||
private Long size;
|
||||
private Hypervisor.HypervisorType hypervisorType;
|
||||
|
||||
public TemplateObjectTO() {
|
||||
|
||||
|
|
@ -53,6 +55,7 @@ public class TemplateObjectTO implements DataTO {
|
|||
this.accountId = template.getAccountId();
|
||||
this.name = template.getUniqueName();
|
||||
this.format = template.getFormat();
|
||||
this.hypervisorType = template.getHypervisorType();
|
||||
}
|
||||
|
||||
public TemplateObjectTO(TemplateInfo template) {
|
||||
|
|
@ -69,6 +72,7 @@ public class TemplateObjectTO implements DataTO {
|
|||
if (template.getDataStore() != null) {
|
||||
this.imageDataStore = template.getDataStore().getTO();
|
||||
}
|
||||
this.hypervisorType = template.getHypervisorType();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -128,6 +132,11 @@ public class TemplateObjectTO implements DataTO {
|
|||
return this.imageDataStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hypervisor.HypervisorType getHypervisorType() {
|
||||
return this.hypervisorType;
|
||||
}
|
||||
|
||||
public void setDataStore(DataStoreTO store){
|
||||
this.imageDataStore = store;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.storage.to;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||
|
||||
import com.cloud.agent.api.to.DataObjectType;
|
||||
|
|
@ -41,6 +42,7 @@ public class VolumeObjectTO implements DataTO {
|
|||
private Long bytesWriteRate;
|
||||
private Long iopsReadRate;
|
||||
private Long iopsWriteRate;
|
||||
private Hypervisor.HypervisorType hypervisorType;
|
||||
|
||||
public VolumeObjectTO() {
|
||||
|
||||
|
|
@ -67,6 +69,7 @@ public class VolumeObjectTO implements DataTO {
|
|||
this.bytesWriteRate = volume.getBytesWriteRate();
|
||||
this.iopsReadRate = volume.getIopsReadRate();
|
||||
this.iopsWriteRate = volume.getIopsWriteRate();
|
||||
this.hypervisorType = volume.getHypervisorType();
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
|
|
@ -87,6 +90,11 @@ public class VolumeObjectTO implements DataTO {
|
|||
return this.dataStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hypervisor.HypervisorType getHypervisorType() {
|
||||
return this.hypervisorType;
|
||||
}
|
||||
|
||||
|
||||
public void setDataStore(DataStoreTO store){
|
||||
this.dataStore = store;
|
||||
|
|
|
|||
|
|
@ -403,6 +403,11 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Answer createTemplateFromSnapshot(CopyCommand cmd) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public Answer backupSnapshot(CopyCommand cmd) {
|
||||
DataTO srcData = cmd.getSrcTO();
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import java.util.UUID;
|
|||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.host.Host;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.storage.command.CopyCommand;
|
||||
|
|
@ -42,7 +43,6 @@ import com.cloud.agent.api.UnregisterVMCommand;
|
|||
import com.cloud.agent.api.storage.CopyVolumeCommand;
|
||||
import com.cloud.agent.api.storage.CreateVolumeOVACommand;
|
||||
import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||
import com.cloud.agent.api.to.DataObjectType;
|
||||
import com.cloud.agent.api.to.DataStoreTO;
|
||||
import com.cloud.agent.api.to.DataTO;
|
||||
|
|
@ -294,92 +294,82 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
|
|||
}
|
||||
|
||||
@Override @DB
|
||||
public long getCommandHostDelegation(long hostId, Command cmd) {
|
||||
public Pair<Boolean, Long> getCommandHostDelegation(long hostId, Command cmd) {
|
||||
boolean needDelegation = false;
|
||||
|
||||
if(cmd instanceof PrimaryStorageDownloadCommand ||
|
||||
cmd instanceof BackupSnapshotCommand ||
|
||||
cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
|
||||
cmd instanceof CreatePrivateTemplateFromSnapshotCommand ||
|
||||
cmd instanceof CopyVolumeCommand ||
|
||||
cmd instanceof CreateVolumeOVACommand ||
|
||||
cmd instanceof PrepareOVAPackingCommand ||
|
||||
cmd instanceof CreateVolumeFromSnapshotCommand ||
|
||||
cmd instanceof CopyCommand) {
|
||||
if (cmd instanceof CopyCommand) {
|
||||
CopyCommand cpyCommand = (CopyCommand)cmd;
|
||||
DataTO srcData = cpyCommand.getSrcTO();
|
||||
DataStoreTO srcStoreTO = srcData.getDataStore();
|
||||
DataTO destData = cpyCommand.getDestTO();
|
||||
DataStoreTO destStoreTO = destData.getDataStore();
|
||||
if (cmd instanceof CopyCommand) {
|
||||
CopyCommand cpyCommand = (CopyCommand)cmd;
|
||||
DataTO srcData = cpyCommand.getSrcTO();
|
||||
DataStoreTO srcStoreTO = srcData.getDataStore();
|
||||
DataTO destData = cpyCommand.getDestTO();
|
||||
DataStoreTO destStoreTO = destData.getDataStore();
|
||||
|
||||
if (destData.getObjectType() == DataObjectType.VOLUME && destStoreTO.getRole() == DataStoreRole.Primary &&
|
||||
srcData.getObjectType() == DataObjectType.TEMPLATE && srcStoreTO.getRole() == DataStoreRole.Primary) {
|
||||
needDelegation = false;
|
||||
} else {
|
||||
needDelegation = true;
|
||||
}
|
||||
if (!(HypervisorType.VMware == srcData.getHypervisorType() ||
|
||||
HypervisorType.VMware == destData.getHypervisorType()
|
||||
)) {
|
||||
return new Pair<Boolean, Long>(Boolean.FALSE, new Long(hostId));
|
||||
}
|
||||
|
||||
if (destData.getObjectType() == DataObjectType.VOLUME && destStoreTO.getRole() == DataStoreRole.Primary &&
|
||||
srcData.getObjectType() == DataObjectType.TEMPLATE && srcStoreTO.getRole() == DataStoreRole.Primary) {
|
||||
needDelegation = false;
|
||||
} else {
|
||||
needDelegation = true;
|
||||
}
|
||||
|
||||
}
|
||||
/* Fang: remove this before checking in */
|
||||
// needDelegation = false;
|
||||
|
||||
if (cmd instanceof PrepareOVAPackingCommand ||
|
||||
cmd instanceof CreateVolumeOVACommand ) {
|
||||
if(!needDelegation) {
|
||||
return new Pair<Boolean, Long>(Boolean.FALSE, new Long(hostId));
|
||||
}
|
||||
|
||||
HostVO host = _hostDao.findById(hostId);
|
||||
long dcId = host.getDataCenterId();
|
||||
|
||||
Pair<HostVO, SecondaryStorageVmVO> cmdTarget = _secStorageMgr.assignSecStorageVm(dcId, cmd);
|
||||
if(cmdTarget != null) {
|
||||
// TODO, we need to make sure agent is actually connected too
|
||||
|
||||
cmd.setContextParam("hypervisor", HypervisorType.VMware.toString());
|
||||
}
|
||||
if(needDelegation) {
|
||||
HostVO host = _hostDao.findById(hostId);
|
||||
assert(host != null);
|
||||
assert(host.getHypervisorType() == HypervisorType.VMware);
|
||||
long dcId = host.getDataCenterId();
|
||||
|
||||
Pair<HostVO, SecondaryStorageVmVO> cmdTarget = _secStorageMgr.assignSecStorageVm(dcId, cmd);
|
||||
if(cmdTarget != null) {
|
||||
// TODO, we need to make sure agent is actually connected too
|
||||
cmd.setContextParam("hypervisor", HypervisorType.VMware.toString());
|
||||
if (host.getType() == Host.Type.Routing) {
|
||||
Map<String, String> hostDetails = _hostDetailsDao.findDetails(hostId);
|
||||
cmd.setContextParam("guid", resolveNameInGuid(hostDetails.get("guid")));
|
||||
cmd.setContextParam("username", hostDetails.get("username"));
|
||||
cmd.setContextParam("password", hostDetails.get("password"));
|
||||
cmd.setContextParam("serviceconsole", _vmwareMgr.getServiceConsolePortGroupName());
|
||||
cmd.setContextParam("manageportgroup", _vmwareMgr.getManagementPortGroupName());
|
||||
|
||||
CommandExecLogVO execLog = new CommandExecLogVO(cmdTarget.first().getId(), cmdTarget.second().getId(), cmd.getClass().getSimpleName(), 1);
|
||||
_cmdExecLogDao.persist(execLog);
|
||||
cmd.setContextParam("execid", String.valueOf(execLog.getId()));
|
||||
|
||||
if(cmd instanceof BackupSnapshotCommand ||
|
||||
cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
|
||||
cmd instanceof CreatePrivateTemplateFromSnapshotCommand ||
|
||||
cmd instanceof CopyVolumeCommand ||
|
||||
cmd instanceof CopyCommand ||
|
||||
cmd instanceof CreateVolumeOVACommand ||
|
||||
cmd instanceof PrepareOVAPackingCommand ||
|
||||
cmd instanceof CreateVolumeFromSnapshotCommand) {
|
||||
|
||||
String workerName = _vmwareMgr.composeWorkerName();
|
||||
long checkPointId = 1;
|
||||
// FIXME: Fix long checkPointId = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName));
|
||||
cmd.setContextParam("worker", workerName);
|
||||
cmd.setContextParam("checkpoint", String.valueOf(checkPointId));
|
||||
|
||||
// some commands use 2 workers
|
||||
String workerName2 = _vmwareMgr.composeWorkerName();
|
||||
long checkPointId2 = 1;
|
||||
// FIXME: Fix long checkPointId2 = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName2));
|
||||
cmd.setContextParam("worker2", workerName2);
|
||||
cmd.setContextParam("checkpoint2", String.valueOf(checkPointId2));
|
||||
}
|
||||
|
||||
return cmdTarget.first().getId();
|
||||
}
|
||||
}
|
||||
|
||||
return hostId;
|
||||
CommandExecLogVO execLog = new CommandExecLogVO(cmdTarget.first().getId(), cmdTarget.second().getId(), cmd.getClass().getSimpleName(), 1);
|
||||
_cmdExecLogDao.persist(execLog);
|
||||
cmd.setContextParam("execid", String.valueOf(execLog.getId()));
|
||||
|
||||
if(cmd instanceof BackupSnapshotCommand ||
|
||||
cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
|
||||
cmd instanceof CreatePrivateTemplateFromSnapshotCommand ||
|
||||
cmd instanceof CopyVolumeCommand ||
|
||||
cmd instanceof CopyCommand ||
|
||||
cmd instanceof CreateVolumeOVACommand ||
|
||||
cmd instanceof PrepareOVAPackingCommand ||
|
||||
cmd instanceof CreateVolumeFromSnapshotCommand) {
|
||||
|
||||
String workerName = _vmwareMgr.composeWorkerName();
|
||||
long checkPointId = 1;
|
||||
// FIXME: Fix long checkPointId = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName));
|
||||
cmd.setContextParam("worker", workerName);
|
||||
cmd.setContextParam("checkpoint", String.valueOf(checkPointId));
|
||||
|
||||
// some commands use 2 workers
|
||||
String workerName2 = _vmwareMgr.composeWorkerName();
|
||||
long checkPointId2 = 1;
|
||||
// FIXME: Fix long checkPointId2 = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName2));
|
||||
cmd.setContextParam("worker2", workerName2);
|
||||
cmd.setContextParam("checkpoint2", String.valueOf(checkPointId2));
|
||||
}
|
||||
|
||||
return new Pair<Boolean, Long>(Boolean.TRUE,cmdTarget.first().getId());
|
||||
|
||||
}
|
||||
return new Pair<Boolean, Long>(Boolean.FALSE, new Long(hostId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
|
|||
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
|
||||
import org.apache.cloudstack.storage.to.TemplateObjectTO;
|
||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
|
|
@ -77,7 +78,6 @@ import com.cloud.storage.Volume;
|
|||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.template.VmdkProcessor;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.Ternary;
|
||||
import com.cloud.utils.script.Script;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
|
|
@ -543,7 +543,6 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||
@Override
|
||||
public Answer createTemplateFromVolume(CopyCommand cmd) {
|
||||
VolumeObjectTO volume = (VolumeObjectTO)cmd.getSrcTO();
|
||||
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore();
|
||||
TemplateObjectTO template = (TemplateObjectTO)cmd.getDestTO();
|
||||
DataStoreTO imageStore = template.getDataStore();
|
||||
|
||||
|
|
@ -579,7 +578,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||
hostService.getWorkerName(context, cmd, 0));
|
||||
|
||||
TemplateObjectTO newTemplate = new TemplateObjectTO();
|
||||
newTemplate.setPath(template.getName());
|
||||
newTemplate.setPath(result.first());
|
||||
newTemplate.setFormat(ImageFormat.OVA);
|
||||
newTemplate.setSize(result.third());
|
||||
return new CopyCmdAnswer(newTemplate);
|
||||
|
|
@ -591,12 +590,196 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||
|
||||
s_logger.error("Unexpecpted exception ", e);
|
||||
|
||||
details = "CreatePrivateTemplateFromVolumeCommand exception: " + StringUtils.getExceptionStackInfo(e);
|
||||
details = "CreatePrivateTemplateFromVolumeCommand exception: " + e.toString();
|
||||
return new CopyCmdAnswer(details);
|
||||
}
|
||||
}
|
||||
|
||||
private void exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath,
|
||||
|
||||
private void writeMetaOvaForTemplate(String installFullPath, String ovfFilename, String vmdkFilename,
|
||||
String templateName, long diskSize) throws Exception {
|
||||
|
||||
// TODO a bit ugly here
|
||||
BufferedWriter out = null;
|
||||
try {
|
||||
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installFullPath + "/" + templateName +".ova.meta")));
|
||||
out.write("ova.filename=" + templateName + ".ova");
|
||||
out.newLine();
|
||||
out.write("version=1.0");
|
||||
out.newLine();
|
||||
out.write("ovf=" + ovfFilename);
|
||||
out.newLine();
|
||||
out.write("numDisks=1");
|
||||
out.newLine();
|
||||
out.write("disk1.name=" + vmdkFilename);
|
||||
out.newLine();
|
||||
out.write("disk1.size=" + diskSize);
|
||||
out.newLine();
|
||||
} finally {
|
||||
if(out != null)
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
private Ternary<String, Long, Long> createTemplateFromSnapshot(String installPath, String templateUniqueName,
|
||||
String secStorageUrl, String snapshotPath, Long templateId) throws Exception {
|
||||
//Snapshot path is decoded in this form: /snapshots/account/volumeId/uuid/uuid
|
||||
String[] tokens = snapshotPath.split(File.separator);
|
||||
String backupSSUuid = tokens[tokens.length - 1];
|
||||
String snapshotFolder = StringUtils.join(tokens, File.separator, 0, tokens.length -1);
|
||||
|
||||
String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
|
||||
String installFullPath = secondaryMountPoint + "/" + installPath;
|
||||
String installFullOVAName = installFullPath + "/" + templateUniqueName + ".ova"; //Note: volss for tmpl
|
||||
String snapshotRoot = secondaryMountPoint + "/" + snapshotFolder;
|
||||
String snapshotFullOVAName = snapshotRoot + "/" + backupSSUuid + ".ova";
|
||||
String snapshotFullOvfName = snapshotRoot + "/" + backupSSUuid + ".ovf";
|
||||
String result;
|
||||
Script command;
|
||||
String templateVMDKName = "";
|
||||
String snapshotFullVMDKName = snapshotRoot + "/" + backupSSUuid + "/";
|
||||
|
||||
synchronized(installPath.intern()) {
|
||||
command = new Script(false, "mkdir", _timeout, s_logger);
|
||||
command.add("-p");
|
||||
command.add(installFullPath);
|
||||
|
||||
result = command.execute();
|
||||
if(result != null) {
|
||||
String msg = "unable to prepare template directory: "
|
||||
+ installPath + ", storage: " + secStorageUrl + ", error msg: " + result;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if(new File(snapshotFullOVAName).exists()) {
|
||||
command = new Script(false, "cp", _timeout, s_logger);
|
||||
command.add(snapshotFullOVAName);
|
||||
command.add(installFullOVAName);
|
||||
result = command.execute();
|
||||
if(result != null) {
|
||||
String msg = "unable to copy snapshot " + snapshotFullOVAName + " to " + installFullPath;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
// untar OVA file at template directory
|
||||
command = new Script("tar", 0, s_logger);
|
||||
command.add("--no-same-owner");
|
||||
command.add("-xf", installFullOVAName);
|
||||
command.setWorkDir(installFullPath);
|
||||
s_logger.info("Executing command: " + command.toString());
|
||||
result = command.execute();
|
||||
if(result != null) {
|
||||
String msg = "unable to untar snapshot " + snapshotFullOVAName + " to "
|
||||
+ installFullPath;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
} else { // there is no ova file, only ovf originally;
|
||||
if(new File(snapshotFullOvfName).exists()) {
|
||||
command = new Script(false, "cp", _timeout, s_logger);
|
||||
command.add(snapshotFullOvfName);
|
||||
//command.add(installFullOvfName);
|
||||
command.add(installFullPath);
|
||||
result = command.execute();
|
||||
if(result != null) {
|
||||
String msg = "unable to copy snapshot " + snapshotFullOvfName + " to " + installFullPath;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
s_logger.info("vmdkfile parent dir: " + snapshotFullVMDKName);
|
||||
File snapshotdir = new File(snapshotFullVMDKName);
|
||||
// File snapshotdir = new File(snapshotRoot);
|
||||
File[] ssfiles = snapshotdir.listFiles();
|
||||
// List<String> filenames = new ArrayList<String>();
|
||||
for (int i = 0; i < ssfiles.length; i++) {
|
||||
String vmdkfile = ssfiles[i].getName();
|
||||
s_logger.info("vmdk file name: " + vmdkfile);
|
||||
if(vmdkfile.toLowerCase().startsWith(backupSSUuid) && vmdkfile.toLowerCase().endsWith(".vmdk")) {
|
||||
snapshotFullVMDKName += vmdkfile;
|
||||
templateVMDKName += vmdkfile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (snapshotFullVMDKName != null) {
|
||||
command = new Script(false, "cp", _timeout, s_logger);
|
||||
command.add(snapshotFullVMDKName);
|
||||
command.add(installFullPath);
|
||||
result = command.execute();
|
||||
s_logger.info("Copy VMDK file: " + snapshotFullVMDKName);
|
||||
if(result != null) {
|
||||
String msg = "unable to copy snapshot vmdk file " + snapshotFullVMDKName + " to " + installFullPath;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String msg = "unable to find any snapshot ova/ovf files" + snapshotFullOVAName + " to " + installFullPath;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
|
||||
long physicalSize = new File(installFullPath + "/" + templateVMDKName).length();
|
||||
VmdkProcessor processor = new VmdkProcessor();
|
||||
// long physicalSize = new File(installFullPath + "/" + templateUniqueName + ".ova").length();
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put(StorageLayer.InstanceConfigKey, _storage);
|
||||
processor.configure("VMDK Processor", params);
|
||||
long virtualSize = processor.getTemplateVirtualSize(installFullPath, templateUniqueName);
|
||||
|
||||
postCreatePrivateTemplate(installFullPath, templateId, templateUniqueName, physicalSize, virtualSize);
|
||||
writeMetaOvaForTemplate(installFullPath, backupSSUuid + File.separator + backupSSUuid + ".ovf", templateVMDKName, templateUniqueName, physicalSize);
|
||||
return new Ternary<String, Long, Long>(installPath + "/" + templateUniqueName + ".ova", physicalSize, virtualSize);
|
||||
} catch(Exception e) {
|
||||
// TODO, clean up left over files
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Answer createTemplateFromSnapshot(CopyCommand cmd) {
|
||||
SnapshotObjectTO snapshot = (SnapshotObjectTO)cmd.getSrcTO();
|
||||
TemplateObjectTO template = (TemplateObjectTO)cmd.getDestTO();
|
||||
DataStoreTO imageStore = template.getDataStore();
|
||||
String details;
|
||||
String uniqeName = UUID.randomUUID().toString();
|
||||
|
||||
VmwareContext context = hostService.getServiceContext(cmd);
|
||||
try {
|
||||
if (!(imageStore instanceof NfsTO)) {
|
||||
return new CopyCmdAnswer("Only support create template from snapshot, when the dest store is nfs");
|
||||
}
|
||||
|
||||
NfsTO nfsSvr = (NfsTO)imageStore;
|
||||
Ternary<String, Long, Long> result = createTemplateFromSnapshot(template.getPath(),
|
||||
uniqeName,
|
||||
nfsSvr.getUrl(), snapshot.getPath(),
|
||||
template.getId()
|
||||
);
|
||||
|
||||
TemplateObjectTO newTemplate = new TemplateObjectTO();
|
||||
newTemplate.setPath(result.first());
|
||||
newTemplate.setSize(result.second());
|
||||
newTemplate.setFormat(ImageFormat.OVA);
|
||||
return new CopyCmdAnswer(newTemplate);
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof RemoteException) {
|
||||
hostService.invalidateServiceContext(context);
|
||||
}
|
||||
|
||||
s_logger.error("Unexpecpted exception ", e);
|
||||
|
||||
details = "CreatePrivateTemplateFromSnapshotCommand exception: " + e.toString();
|
||||
return new CopyCmdAnswer(details);
|
||||
}
|
||||
}
|
||||
|
||||
private void exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath,
|
||||
String secStorageUrl, String secStorageDir, String exportName,
|
||||
String workerVmName) throws Exception {
|
||||
|
||||
|
|
@ -760,7 +943,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||
|
||||
s_logger.error("Unexpecpted exception ", e);
|
||||
|
||||
details = "BackupSnapshotCommand exception: " + StringUtils.getExceptionStackInfo(e);
|
||||
details = "BackupSnapshotCommand exception: " + e.toString();
|
||||
return new CopyCmdAnswer(details);
|
||||
}
|
||||
}
|
||||
|
|
@ -1298,7 +1481,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||
}
|
||||
|
||||
s_logger.error("Unexpecpted exception ", e);
|
||||
details = "CreateVolumeFromSnapshotCommand exception: " + StringUtils.getExceptionStackInfo(e);
|
||||
details = "CreateVolumeFromSnapshotCommand exception: " + e.toString();
|
||||
}
|
||||
return new CopyCmdAnswer(details);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1438,7 +1438,12 @@ public class XenServerStorageProcessor implements StorageProcessor {
|
|||
return new CopyCmdAnswer(details);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public Answer createTemplateFromSnapshot(CopyCommand cmd) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public Answer createVolumeFromSnapshot(CopyCommand cmd) {
|
||||
Connection conn = this.hypervisorResource.getConnection();
|
||||
DataTO srcData = cmd.getSrcTO();
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import com.cloud.configuration.Config;
|
|||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.server.ConfigurationServer;
|
||||
import com.cloud.storage.dao.VMTemplateDetailsDao;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.NicVO;
|
||||
|
|
@ -135,8 +136,8 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
|
|||
}
|
||||
|
||||
@Override
|
||||
public long getCommandHostDelegation(long hostId, Command cmd) {
|
||||
return hostId;
|
||||
public Pair<Boolean, Long> getCommandHostDelegation(long hostId, Command cmd) {
|
||||
return new Pair<Boolean, Long>(Boolean.FALSE, new Long(hostId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import javax.ejb.Local;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
|
@ -59,15 +60,12 @@ public class HypervisorGuruManagerImpl extends ManagerBase implements Hypervisor
|
|||
|
||||
@Override
|
||||
public long getGuruProcessedCommandTargetHost(long hostId, Command cmd) {
|
||||
HostVO hostVo = _hostDao.findById(hostId);
|
||||
HypervisorGuru hvGuru = null;
|
||||
if(hostVo.getType() == Host.Type.Routing) {
|
||||
hvGuru = _hvGurus.get(hostVo.getHypervisorType());
|
||||
for(HypervisorGuru guru : _hvGuruList) {
|
||||
Pair<Boolean, Long> result = guru.getCommandHostDelegation(hostId, cmd);
|
||||
if (result.first()) {
|
||||
return result.second();
|
||||
}
|
||||
}
|
||||
|
||||
if(hvGuru != null)
|
||||
return hvGuru.getCommandHostDelegation(hostId, cmd);
|
||||
|
||||
return hostId;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue