You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2013/07/25 04:07:00 UTC
[1/2] git commit: updated refs/heads/master to 80ac885
Updated Branches:
refs/heads/master 29ee68821 -> 80ac885e2
CLOUDSTACK-3681: fix bunch of bugs related to vmware, regarding to snapshot
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/7f200d96
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/7f200d96
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/7f200d96
Branch: refs/heads/master
Commit: 7f200d966e1558286c41613a0ffa782963bbf4e0
Parents: 29ee688
Author: Edison Su <su...@gmail.com>
Authored: Wed Jul 24 15:36:39 2013 -0700
Committer: Edison Su <su...@gmail.com>
Committed: Wed Jul 24 19:06:30 2013 -0700
----------------------------------------------------------------------
api/src/com/cloud/agent/api/to/DataTO.java | 3 +
.../com/cloud/hypervisor/HypervisorGuru.java | 4 +-
.../storage/resource/StorageProcessor.java | 1 +
.../StorageSubsystemCommandHandlerBase.java | 2 +
.../cloudstack/storage/to/SnapshotObjectTO.java | 1 +
.../cloudstack/storage/to/TemplateObjectTO.java | 9 +
.../cloudstack/storage/to/VolumeObjectTO.java | 8 +
.../kvm/storage/KVMStorageProcessor.java | 5 +
.../com/cloud/hypervisor/guru/VMwareGuru.java | 128 ++++++------
.../resource/VmwareStorageProcessor.java | 199 ++++++++++++++++++-
.../xen/resource/XenServerStorageProcessor.java | 7 +-
.../cloud/hypervisor/HypervisorGuruBase.java | 5 +-
.../hypervisor/HypervisorGuruManagerImpl.java | 14 +-
13 files changed, 297 insertions(+), 89 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f200d96/api/src/com/cloud/agent/api/to/DataTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/DataTO.java b/api/src/com/cloud/agent/api/to/DataTO.java
index 21e802f..8d24a05 100644
--- a/api/src/com/cloud/agent/api/to/DataTO.java
+++ b/api/src/com/cloud/agent/api/to/DataTO.java
@@ -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
*/
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f200d96/api/src/com/cloud/hypervisor/HypervisorGuru.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/hypervisor/HypervisorGuru.java b/api/src/com/cloud/hypervisor/HypervisorGuru.java
index 182f06a..cc27680 100644
--- a/api/src/com/cloud/hypervisor/HypervisorGuru.java
+++ b/api/src/com/cloud/hypervisor/HypervisorGuru.java
@@ -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
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f200d96/core/src/com/cloud/storage/resource/StorageProcessor.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/StorageProcessor.java b/core/src/com/cloud/storage/resource/StorageProcessor.java
index f503fa3..5fa9f8a 100644
--- a/core/src/com/cloud/storage/resource/StorageProcessor.java
+++ b/core/src/com/cloud/storage/resource/StorageProcessor.java
@@ -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);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f200d96/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
index c0bbfbe..385a277 100644
--- a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
+++ b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
@@ -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");
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f200d96/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
index 4754dcf..d2cb72a 100644
--- a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
@@ -111,6 +111,7 @@ public class SnapshotObjectTO implements DataTO {
this.name = name;
}
+ @Override
public HypervisorType getHypervisorType() {
return hypervisorType;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f200d96/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java
index abe59eb..2347de3 100644
--- a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java
@@ -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;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f200d96/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java
index ab3d5ea..9f466ae 100644
--- a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java
@@ -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;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f200d96/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
index 3a5e803..2f87ad4 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
@@ -404,6 +404,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();
DataTO destData = cmd.getDestTO();
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f200d96/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
index 78a596e..f2cfbf7 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
@@ -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 (destData.getObjectType() == DataObjectType.VOLUME && destStoreTO.getRole() == DataStoreRole.Primary &&
- srcData.getObjectType() == DataObjectType.TEMPLATE && srcStoreTO.getRole() == DataStoreRole.Primary) {
- needDelegation = false;
- } else {
- needDelegation = true;
- }
+ 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 (!(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;
}
+ }
+ if(!needDelegation) {
+ return new Pair<Boolean, Long>(Boolean.FALSE, new Long(hostId));
}
- /* Fang: remove this before checking in */
- // needDelegation = false;
- if (cmd instanceof PrepareOVAPackingCommand ||
- cmd instanceof CreateVolumeOVACommand ) {
+ 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();
+ 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 hostId;
+ return new Pair<Boolean, Long>(Boolean.TRUE,cmdTarget.first().getId());
+
+ }
+ return new Pair<Boolean, Long>(Boolean.FALSE, new Long(hostId));
}
@Override
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f200d96/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
index 4760ac2..ccf4e43 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
@@ -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);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f200d96/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
index e88d6a5..b7fdcca 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
@@ -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();
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f200d96/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
index 34584ab..6d368bd 100644
--- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
+++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
@@ -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
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f200d96/server/src/com/cloud/hypervisor/HypervisorGuruManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruManagerImpl.java b/server/src/com/cloud/hypervisor/HypervisorGuruManagerImpl.java
index a8aad57..4d1e1b5 100644
--- a/server/src/com/cloud/hypervisor/HypervisorGuruManagerImpl.java
+++ b/server/src/com/cloud/hypervisor/HypervisorGuruManagerImpl.java
@@ -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;
}
}
[2/2] git commit: updated refs/heads/master to 80ac885
Posted by ed...@apache.org.
CLOUDSTACK-2304: fix migrate volume for vmware
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/80ac885e
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/80ac885e
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/80ac885e
Branch: refs/heads/master
Commit: 80ac885e22b19dc2f7a0a9ba8b02b0911f32a9f3
Parents: 7f200d9
Author: Edison Su <su...@gmail.com>
Authored: Wed Jul 24 18:59:18 2013 -0700
Committer: Edison Su <su...@gmail.com>
Committed: Wed Jul 24 19:06:42 2013 -0700
----------------------------------------------------------------------
.../resource/VmwareStorageProcessor.java | 189 +++++++++++++++++--
.../resource/NfsSecondaryStorageResource.java | 1 +
2 files changed, 179 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/80ac885e/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
index ccf4e43..d106889 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
@@ -27,6 +27,9 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
+import com.cloud.agent.api.storage.CopyVolumeAnswer;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.to.*;
import org.apache.cloudstack.storage.command.AttachAnswer;
import org.apache.cloudstack.storage.command.AttachCommand;
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
@@ -51,11 +54,6 @@ import com.cloud.agent.api.ManageSnapshotAnswer;
import com.cloud.agent.api.ManageSnapshotCommand;
import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.VolumeTO;
import com.cloud.hypervisor.vmware.manager.VmwareHostService;
import com.cloud.hypervisor.vmware.manager.VmwareStorageMount;
import com.cloud.hypervisor.vmware.mo.ClusterMO;
@@ -421,18 +419,187 @@ public class VmwareStorageProcessor implements StorageProcessor {
return new CopyCmdAnswer(e.toString());
}
}
-
+
+ private Pair<String, String> copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, String srcVolumePath,
+ DatastoreMO dsMo, String secStorageUrl) throws Exception {
+ //srcVolumePath has volumes/dc/id/uuid
+ int index = srcVolumePath.lastIndexOf(File.separator);
+ String volumeFolder = srcVolumePath;
+ String volumeName = srcVolumePath.substring(index + 1);
+
+ String newVolume = UUID.randomUUID().toString().replaceAll("-", "");
+ restoreVolumeFromSecStorage(hyperHost, dsMo, newVolume, secStorageUrl, volumeFolder, volumeName);
+
+ return new Pair<String, String>(volumeFolder, newVolume);
+ }
+
+ private String deleteVolumeDirOnSecondaryStorage(String volumeDir, String secStorageUrl) throws Exception {
+ String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
+ String volumeMountRoot = secondaryMountPoint + File.separator + volumeDir;
+
+ return deleteDir(volumeMountRoot);
+ }
+
+ private String deleteDir(String dir) {
+ synchronized(dir.intern()) {
+ Script command = new Script(false, "rm", _timeout, s_logger);
+ command.add("-rf");
+ command.add(dir);
+ return command.execute();
+ }
+ }
@Override
public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) {
- // TODO Auto-generated method stub
- return null;
- }
+ VolumeObjectTO srcVolume = (VolumeObjectTO)cmd.getSrcTO();
+ VolumeObjectTO destVolume = (VolumeObjectTO)cmd.getDestTO();
+ VmwareContext context = hostService.getServiceContext(cmd);
+ try {
+
+ NfsTO srcStore = (NfsTO)srcVolume.getDataStore();
+ PrimaryDataStoreTO destStore = (PrimaryDataStoreTO)destVolume.getDataStore();
+
+ VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
+ String uuid = destStore.getUuid();
+
+ ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, uuid);
+ if (morDatastore == null) {
+ morDatastore = hyperHost.mountDatastore(
+ false,
+ destStore.getHost(), 0, destStore.getPath(),
+ destStore.getUuid().replace("-", ""));
+
+ if (morDatastore == null) {
+ throw new Exception("Unable to mount storage pool on host. storeUrl: " + destStore.getHost() + ":/" + destStore.getPath());
+ }
+ }
+
+ Pair<String, String> result = copyVolumeFromSecStorage(
+ hyperHost, srcVolume.getPath(),
+ new DatastoreMO(context, morDatastore),
+ srcStore.getUrl());
+ deleteVolumeDirOnSecondaryStorage(result.first(), srcStore.getUrl());
+ VolumeObjectTO newVolume = new VolumeObjectTO();
+ newVolume.setPath(result.second());
+ return new CopyCmdAnswer(newVolume);
+ } catch (Throwable t) {
+ if (t instanceof RemoteException) {
+ hostService.invalidateServiceContext(context);
+ }
+
+ String msg = "Unable to execute CopyVolumeCommand due to exception";
+ s_logger.error(msg, t);
+ return new CopyCmdAnswer("CopyVolumeCommand failed due to exception: " + t.toString());
+ }
+
+ }
+
+ private String getVolumePathInDatastore(DatastoreMO dsMo, String volumeFileName) throws Exception {
+ String datastoreVolumePath = dsMo.searchFileInSubFolders(volumeFileName, true);
+ assert (datastoreVolumePath != null) : "Virtual disk file missing from datastore.";
+ return datastoreVolumePath;
+ }
+
+ private Pair<String, String> copyVolumeToSecStorage(VmwareHostService hostService, VmwareHypervisorHost hyperHost, CopyCommand cmd,
+ String vmName, String poolId, String volumePath, String destVolumePath,
+ String secStorageUrl, String workerVmName) throws Exception {
+ VirtualMachineMO workerVm=null;
+ VirtualMachineMO vmMo=null;
+ String exportName = UUID.randomUUID().toString();
+
+ try {
+ ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolId);
+
+ if (morDs == null) {
+ String msg = "Unable to find volumes's storage pool for copy volume operation";
+ s_logger.error(msg);
+ throw new Exception(msg);
+ }
+
+ vmMo = hyperHost.findVmOnHyperHost(vmName);
+ if (vmMo == null) {
+ // create a dummy worker vm for attaching the volume
+ DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
+ //restrict VM name to 32 chars, (else snapshot descriptor file name will be truncated to 32 chars of vm name)
+ VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
+ vmConfig.setName(workerVmName);
+ vmConfig.setMemoryMB((long) 4);
+ vmConfig.setNumCPUs(1);
+ vmConfig.setGuestId(VirtualMachineGuestOsIdentifier.OTHER_GUEST.value());
+ VirtualMachineFileInfo fileInfo = new VirtualMachineFileInfo();
+ fileInfo.setVmPathName(String.format("[%s]", dsMo.getName()));
+ vmConfig.setFiles(fileInfo);
+
+ // Scsi controller
+ VirtualLsiLogicController scsiController = new VirtualLsiLogicController();
+ scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
+ scsiController.setBusNumber(0);
+ scsiController.setKey(1);
+ VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
+ scsiControllerSpec.setDevice(scsiController);
+ scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+ vmConfig.getDeviceChange().add(scsiControllerSpec);
+
+ hyperHost.createVm(vmConfig);
+ workerVm = hyperHost.findVmOnHyperHost(workerVmName);
+ if (workerVm == null) {
+ String msg = "Unable to create worker VM to execute CopyVolumeCommand";
+ s_logger.error(msg);
+ throw new Exception(msg);
+ }
+
+ //attach volume to worker VM
+ String datastoreVolumePath = getVolumePathInDatastore(dsMo, volumePath + ".vmdk");
+ workerVm.attachDisk(new String[] { datastoreVolumePath }, morDs);
+ vmMo = workerVm;
+ }
+
+ vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false);
+
+ exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, destVolumePath, exportName,
+ hostService.getWorkerName(hyperHost.getContext(), cmd, 1));
+ return new Pair<String, String>(destVolumePath, exportName);
+
+ } finally {
+ vmMo.removeSnapshot(exportName, false);
+ if (workerVm != null) {
+ //detach volume and destroy worker vm
+ workerVm.detachAllDisks();
+ workerVm.destroy();
+ }
+ }
+ }
@Override
public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) {
- // TODO Auto-generated method stub
- return null;
+ VolumeObjectTO srcVolume = (VolumeObjectTO)cmd.getSrcTO();
+ VolumeObjectTO destVolume = (VolumeObjectTO)cmd.getDestTO();
+ String vmName = srcVolume.getVmName();
+
+ VmwareContext context = hostService.getServiceContext(cmd);
+ try {
+ PrimaryDataStoreTO primaryStorage = (PrimaryDataStoreTO)srcVolume.getDataStore();
+ NfsTO destStore = (NfsTO)destVolume.getDataStore();
+ VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
+
+ Pair<String, String> result;
+
+ result = copyVolumeToSecStorage(hostService,
+ hyperHost, cmd, vmName, primaryStorage.getUuid(), srcVolume.getPath(),destVolume.getPath(),
+ destStore.getUrl(),
+ hostService.getWorkerName(context, cmd, 0));
+ VolumeObjectTO newVolume = new VolumeObjectTO();
+ newVolume.setPath(result.first() + File.separator + result.second());
+ return new CopyCmdAnswer(newVolume);
+ } catch (Throwable e) {
+ if (e instanceof RemoteException) {
+ hostService.invalidateServiceContext(context);
+ }
+
+ String msg = "Unable to execute CopyVolumeCommand due to exception";
+ s_logger.error(msg, e);
+ return new CopyCmdAnswer("CopyVolumeCommand failed due to exception: " + e.toString());
+ }
}
private void postCreatePrivateTemplate(String installFullPath, long templateId,
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/80ac885e/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index e7dc62d..e6f3092 100755
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -445,6 +445,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
processor.configure("qcow2 processor", params);
String destPath = destFile.getAbsolutePath();
+
FormatInfo info = processor.process(destPath, null, templateName);
TemplateLocation loc = new TemplateLocation(_storage, destPath);
loc.create(1, true, srcFile.getName());