use of org.apache.cloudstack.storage.command.CopyCommand in project cloudstack by apache.
the class KvmNonManagedStorageDataMotionStrategy method sendCopyCommand.
/**
* Sends the CopyCommand to migrate the template to the dest host.
*/
protected Answer sendCopyCommand(Host destHost, TemplateObjectTO sourceTemplate, TemplateObjectTO destTemplate, DataStore destDataStore) {
boolean executeInSequence = virtualMachineManager.getExecuteInSequence(HypervisorType.KVM);
CopyCommand copyCommand = new CopyCommand(sourceTemplate, destTemplate, StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value(), executeInSequence);
try {
Answer copyCommandAnswer = agentManager.send(destHost.getId(), copyCommand);
logInCaseOfTemplateCopyFailure(copyCommandAnswer, sourceTemplate, destDataStore);
return copyCommandAnswer;
} catch (AgentUnavailableException | OperationTimedoutException e) {
throw new CloudRuntimeException(generateFailToCopyTemplateMessage(sourceTemplate, destDataStore), e);
}
}
use of org.apache.cloudstack.storage.command.CopyCommand in project cloudstack by apache.
the class StorageSystemDataMotionStrategy method handleCopyAsyncToSecondaryStorage.
/**
* This function is responsible for copying a snapshot from managed storage to secondary storage. This is used in the following two cases:
* 1) When creating a template from a snapshot
* 2) When createSnapshot is called with location=SECONDARY
*
* @param snapshotInfo source snapshot
* @param destData destination (can be template or snapshot)
* @param callback callback for async
*/
private void handleCopyAsyncToSecondaryStorage(SnapshotInfo snapshotInfo, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
String errMsg = null;
CopyCmdAnswer copyCmdAnswer = null;
boolean usingBackendSnapshot = false;
try {
snapshotInfo.processEvent(Event.CopyingRequested);
HostVO hostVO = getHost(snapshotInfo);
boolean needCache = needCacheStorage(snapshotInfo, destData);
DataObject destOnStore = destData;
if (needCache) {
// creates an object in the DB for data to be cached
Scope selectedScope = pickCacheScopeForCopy(snapshotInfo, destData);
destOnStore = cacheMgr.getCacheObject(snapshotInfo, selectedScope);
destOnStore.processEvent(Event.CreateOnlyRequested);
}
usingBackendSnapshot = usingBackendSnapshotFor(snapshotInfo);
if (usingBackendSnapshot) {
final boolean computeClusterSupportsVolumeClone;
// only XenServer, VMware, and KVM are currently supported
if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType())) {
computeClusterSupportsVolumeClone = clusterDao.getSupportsResigning(hostVO.getClusterId());
} else if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType()) || HypervisorType.KVM.equals(snapshotInfo.getHypervisorType())) {
computeClusterSupportsVolumeClone = true;
} else {
throw new CloudRuntimeException("Unsupported hypervisor type");
}
if (!computeClusterSupportsVolumeClone) {
String noSupportForResignErrMsg = "Unable to locate an applicable host with which to perform a resignature operation : Cluster ID = " + hostVO.getClusterId();
LOGGER.warn(noSupportForResignErrMsg);
throw new CloudRuntimeException(noSupportForResignErrMsg);
}
}
String vmdk = null;
String uuid = null;
boolean keepGrantedAccess = false;
DataStore srcDataStore = snapshotInfo.getDataStore();
StoragePoolVO storagePoolVO = _storagePoolDao.findById(srcDataStore.getId());
if (HypervisorType.KVM.equals(snapshotInfo.getHypervisorType()) && storagePoolVO.getPoolType() == StoragePoolType.PowerFlex) {
usingBackendSnapshot = false;
}
if (usingBackendSnapshot) {
createVolumeFromSnapshot(snapshotInfo);
if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType()) || HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
keepGrantedAccess = HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType());
Map<String, String> extraDetails = null;
if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
extraDetails = new HashMap<>();
String extraDetailsVmdk = getSnapshotProperty(snapshotInfo.getId(), DiskTO.VMDK);
extraDetails.put(DiskTO.VMDK, extraDetailsVmdk);
extraDetails.put(DiskTO.TEMPLATE_RESIGN, Boolean.TRUE.toString());
}
copyCmdAnswer = performResignature(snapshotInfo, hostVO, extraDetails, keepGrantedAccess);
// If using VMware, have the host rescan its software HBA if dynamic discovery is in use.
if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
String iqn = getSnapshotProperty(snapshotInfo.getId(), DiskTO.IQN);
disconnectHostFromVolume(hostVO, srcDataStore.getId(), iqn);
}
verifyCopyCmdAnswer(copyCmdAnswer, snapshotInfo);
vmdk = copyCmdAnswer.getNewData().getPath();
uuid = UUID.randomUUID().toString();
}
}
int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
CopyCommand copyCommand = new CopyCommand(snapshotInfo.getTO(), destOnStore.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
try {
if (!keepGrantedAccess) {
_volumeService.grantAccess(snapshotInfo, hostVO, srcDataStore);
}
Map<String, String> srcDetails = getSnapshotDetails(snapshotInfo);
if (isForVMware(destData)) {
srcDetails.put(DiskTO.VMDK, vmdk);
srcDetails.put(DiskTO.UUID, uuid);
if (destData instanceof TemplateInfo) {
VMTemplateVO templateDataStoreVO = _vmTemplateDao.findById(destData.getId());
templateDataStoreVO.setUniqueName(uuid);
_vmTemplateDao.update(destData.getId(), templateDataStoreVO);
}
}
copyCommand.setOptions(srcDetails);
copyCmdAnswer = (CopyCmdAnswer) agentManager.send(hostVO.getId(), copyCommand);
if (!copyCmdAnswer.getResult()) {
errMsg = copyCmdAnswer.getDetails();
LOGGER.warn(errMsg);
throw new CloudRuntimeException(errMsg);
}
if (needCache) {
// If cached storage was needed (in case of object store as secondary
// storage), at this point, the data has been copied from the primary
// to the NFS cache by the hypervisor. We now invoke another copy
// command to copy this data from cache to secondary storage. We
// then clean up the cache.
destOnStore.processEvent(Event.OperationSuccessed, copyCmdAnswer);
CopyCommand cmd = new CopyCommand(destOnStore.getTO(), destData.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
EndPoint ep = selector.select(destOnStore, destData);
if (ep == null) {
errMsg = "No remote endpoint to send command, check if host or SSVM is down";
LOGGER.error(errMsg);
copyCmdAnswer = new CopyCmdAnswer(errMsg);
} else {
copyCmdAnswer = (CopyCmdAnswer) ep.sendMessage(cmd);
}
// clean up snapshot copied to staging
cacheMgr.deleteCacheObject(destOnStore);
}
} catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
String msg = "Failed to create template from snapshot (Snapshot ID = " + snapshotInfo.getId() + ") : ";
LOGGER.warn(msg, ex);
throw new CloudRuntimeException(msg + ex.getMessage(), ex);
} finally {
_volumeService.revokeAccess(snapshotInfo, hostVO, srcDataStore);
// If using VMware, have the host rescan its software HBA if dynamic discovery is in use.
if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
String iqn = getSnapshotProperty(snapshotInfo.getId(), DiskTO.IQN);
disconnectHostFromVolume(hostVO, srcDataStore.getId(), iqn);
}
if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
if (copyCmdAnswer != null && StringUtils.isNotEmpty(copyCmdAnswer.getDetails())) {
errMsg = copyCmdAnswer.getDetails();
if (needCache) {
cacheMgr.deleteCacheObject(destOnStore);
}
} else {
errMsg = "Unable to create template from snapshot";
}
}
try {
if (StringUtils.isEmpty(errMsg)) {
snapshotInfo.processEvent(Event.OperationSuccessed);
} else {
snapshotInfo.processEvent(Event.OperationFailed);
}
} catch (Exception ex) {
LOGGER.warn("Error processing snapshot event: " + ex.getMessage(), ex);
}
}
} catch (Exception ex) {
errMsg = ex.getMessage();
throw new CloudRuntimeException(errMsg);
} finally {
if (usingBackendSnapshot) {
deleteVolumeFromSnapshot(snapshotInfo);
}
if (copyCmdAnswer == null) {
copyCmdAnswer = new CopyCmdAnswer(errMsg);
}
CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
result.setResult(errMsg);
callback.complete(result);
}
}
use of org.apache.cloudstack.storage.command.CopyCommand in project cloudstack by apache.
the class StorageSystemDataMotionStrategy method performCopyOfVdi.
/**
* Copies data from secondary storage to a primary volume
* @param volumeInfo The primary volume
* @param snapshotInfo destination of the copy
* @param hostVO the host used to copy the data
* @return result of the copy
*/
private CopyCmdAnswer performCopyOfVdi(VolumeInfo volumeInfo, SnapshotInfo snapshotInfo, HostVO hostVO) {
Snapshot.LocationType locationType = snapshotInfo.getLocationType();
int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
DataObject srcData = snapshotInfo;
CopyCmdAnswer copyCmdAnswer = null;
DataObject cacheData = null;
boolean needCacheStorage = needCacheStorage(snapshotInfo, volumeInfo);
if (needCacheStorage) {
cacheData = cacheSnapshotChain(snapshotInfo, new ZoneScope(volumeInfo.getDataCenterId()));
srcData = cacheData;
}
CopyCommand copyCommand = new CopyCommand(srcData.getTO(), volumeInfo.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
try {
if (Snapshot.LocationType.PRIMARY.equals(locationType)) {
_volumeService.grantAccess(snapshotInfo, hostVO, snapshotInfo.getDataStore());
Map<String, String> srcDetails = getSnapshotDetails(snapshotInfo);
copyCommand.setOptions(srcDetails);
}
_volumeService.grantAccess(volumeInfo, hostVO, volumeInfo.getDataStore());
Map<String, String> destDetails = getVolumeDetails(volumeInfo);
copyCommand.setOptions2(destDetails);
copyCmdAnswer = (CopyCmdAnswer) agentManager.send(hostVO.getId(), copyCommand);
} catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
String msg = "Failed to perform VDI copy : ";
LOGGER.warn(msg, ex);
throw new CloudRuntimeException(msg + ex.getMessage(), ex);
} finally {
if (Snapshot.LocationType.PRIMARY.equals(locationType)) {
_volumeService.revokeAccess(snapshotInfo, hostVO, snapshotInfo.getDataStore());
}
_volumeService.revokeAccess(volumeInfo, hostVO, volumeInfo.getDataStore());
if (needCacheStorage && copyCmdAnswer != null && copyCmdAnswer.getResult()) {
cacheMgr.deleteCacheObject(cacheData);
}
}
return copyCmdAnswer;
}
use of org.apache.cloudstack.storage.command.CopyCommand in project cloudstack by apache.
the class StorageSystemDataMotionStrategy method handleCreateTemplateFromManagedVolume.
private void handleCreateTemplateFromManagedVolume(VolumeInfo volumeInfo, TemplateInfo templateInfo, AsyncCompletionCallback<CopyCommandResult> callback) {
boolean srcVolumeDetached = volumeInfo.getAttachedVM() == null;
String errMsg = null;
CopyCmdAnswer copyCmdAnswer = null;
try {
StoragePoolVO storagePoolVO = _storagePoolDao.findById(volumeInfo.getPoolId());
if (!ImageFormat.QCOW2.equals(volumeInfo.getFormat()) && !(ImageFormat.RAW.equals(volumeInfo.getFormat()) && StoragePoolType.PowerFlex == storagePoolVO.getPoolType())) {
throw new CloudRuntimeException("When using managed storage, you can only create a template from a volume on KVM currently.");
}
volumeInfo.processEvent(Event.MigrationRequested);
HostVO hostVO = getHost(volumeInfo.getDataCenterId(), HypervisorType.KVM, false);
DataStore srcDataStore = volumeInfo.getDataStore();
int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
CopyCommand copyCommand = new CopyCommand(volumeInfo.getTO(), templateInfo.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
try {
handleQualityOfServiceForVolumeMigration(volumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.MIGRATION);
if (srcVolumeDetached || StoragePoolType.PowerFlex == storagePoolVO.getPoolType()) {
_volumeService.grantAccess(volumeInfo, hostVO, srcDataStore);
}
Map<String, String> srcDetails = getVolumeDetails(volumeInfo);
copyCommand.setOptions(srcDetails);
copyCmdAnswer = (CopyCmdAnswer) agentManager.send(hostVO.getId(), copyCommand);
if (!copyCmdAnswer.getResult()) {
errMsg = copyCmdAnswer.getDetails();
LOGGER.warn(errMsg);
throw new CloudRuntimeException(errMsg);
}
VMTemplateVO vmTemplateVO = _vmTemplateDao.findById(templateInfo.getId());
vmTemplateVO.setHypervisorType(HypervisorType.KVM);
_vmTemplateDao.update(vmTemplateVO.getId(), vmTemplateVO);
} catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
String msg = "Failed to create template from volume (Volume ID = " + volumeInfo.getId() + ") : ";
LOGGER.warn(msg, ex);
throw new CloudRuntimeException(msg + ex.getMessage(), ex);
} finally {
if (srcVolumeDetached || StoragePoolType.PowerFlex == storagePoolVO.getPoolType()) {
try {
_volumeService.revokeAccess(volumeInfo, hostVO, srcDataStore);
} catch (Exception ex) {
LOGGER.warn("Error revoking access to volume (Volume ID = " + volumeInfo.getId() + "): " + ex.getMessage(), ex);
}
}
handleQualityOfServiceForVolumeMigration(volumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.NO_MIGRATION);
if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
if (copyCmdAnswer != null && StringUtils.isNotEmpty(copyCmdAnswer.getDetails())) {
errMsg = copyCmdAnswer.getDetails();
} else {
errMsg = "Unable to create template from volume";
}
}
try {
if (StringUtils.isEmpty(errMsg)) {
volumeInfo.processEvent(Event.OperationSuccessed);
} else {
volumeInfo.processEvent(Event.OperationFailed);
}
} catch (Exception ex) {
LOGGER.warn("Error processing snapshot event: " + ex.getMessage(), ex);
}
}
} catch (Exception ex) {
errMsg = ex.getMessage();
throw new CloudRuntimeException(errMsg);
} finally {
if (copyCmdAnswer == null) {
copyCmdAnswer = new CopyCmdAnswer(errMsg);
}
CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
result.setResult(errMsg);
callback.complete(result);
}
}
Aggregations