Copy template to target KVM host if needed when migrating local <> local storage (#3154)

* Migrate template to target host if needed.

Fix KVM VM local storage live migration by migrating its template to the
target host if needed.

* Address reviewer and add method that updates the DB template reference

* Remove deprecated Config.PrimaryStorageDownloadWait

* Code formating of @Inject to follow checkstyle
This commit is contained in:
Gabriel Beims Bräscher 2019-02-05 00:18:29 -02:00 committed by GitHub
parent 3f17671449
commit 7c5eca9481
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 316 additions and 62 deletions

View File

@ -101,6 +101,9 @@ public interface StorageManager extends StorageService {
ConfigKey.Scope.Cluster, ConfigKey.Scope.Cluster,
null); null);
ConfigKey<Integer> PRIMARY_STORAGE_DOWNLOAD_WAIT = new ConfigKey<Integer>("Storage", Integer.class, "primary.storage.download.wait", "10800",
"In second, timeout for download template to primary storage", false);
/** /**
* Returns a comma separated list of tags for the specified storage pool * Returns a comma separated list of tags for the specified storage pool
* @param poolId * @param poolId

View File

@ -62,6 +62,7 @@ import com.cloud.configuration.Config;
import com.cloud.host.Host; import com.cloud.host.Host;
import com.cloud.hypervisor.Hypervisor; import com.cloud.hypervisor.Hypervisor;
import com.cloud.storage.DataStoreRole; import com.cloud.storage.DataStoreRole;
import com.cloud.storage.StorageManager;
import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePool;
import com.cloud.storage.VolumeVO; import com.cloud.storage.VolumeVO;
@ -145,8 +146,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
} }
protected Answer copyObject(DataObject srcData, DataObject destData, Host destHost) { protected Answer copyObject(DataObject srcData, DataObject destData, Host destHost) {
String value = configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
int _primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
Answer answer = null; Answer answer = null;
DataObject cacheData = null; DataObject cacheData = null;
DataObject srcForCopy = srcData; DataObject srcForCopy = srcData;
@ -156,7 +156,8 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
srcForCopy = cacheData = cacheMgr.createCacheObject(srcData, destScope); srcForCopy = cacheData = cacheMgr.createCacheObject(srcData, destScope);
} }
CopyCommand cmd = new CopyCommand(srcForCopy.getTO(), addFullCloneFlagOnVMwareDest(destData.getTO()), _primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value()); CopyCommand cmd = new CopyCommand(srcForCopy.getTO(), addFullCloneFlagOnVMwareDest(destData.getTO()), primaryStorageDownloadWait,
VirtualMachineManager.ExecuteInSequence.value());
EndPoint ep = destHost != null ? RemoteHostEndPoint.getHypervisorHostEndPoint(destHost) : selector.select(srcForCopy, destData); EndPoint ep = destHost != null ? RemoteHostEndPoint.getHypervisorHostEndPoint(destHost) : selector.select(srcForCopy, destData);
if (ep == null) { if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?"; String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";

View File

@ -29,7 +29,13 @@ import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
import org.apache.cloudstack.storage.command.CopyCommand;
import org.apache.cloudstack.storage.datastore.DataStoreManagerImpl;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.to.TemplateObjectTO;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.MigrateCommand;
@ -37,14 +43,22 @@ import com.cloud.agent.api.MigrateCommand.MigrateDiskInfo;
import com.cloud.agent.api.storage.CreateAnswer; import com.cloud.agent.api.storage.CreateAnswer;
import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.CreateCommand;
import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.host.Host; import com.cloud.host.Host;
import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.DataStoreRole; import com.cloud.storage.DataStoreRole;
import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePool;
import com.cloud.storage.VMTemplateStoragePoolVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VolumeVO; import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VMTemplatePoolDao;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.DiskProfile; import com.cloud.vm.DiskProfile;
import com.cloud.vm.VirtualMachineManager;
/** /**
* Extends {@link StorageSystemDataMotionStrategy}, allowing KVM hosts to migrate VMs with the ROOT volume on a non managed local storage pool. * Extends {@link StorageSystemDataMotionStrategy}, allowing KVM hosts to migrate VMs with the ROOT volume on a non managed local storage pool.
@ -54,6 +68,14 @@ public class KvmNonManagedStorageDataMotionStrategy extends StorageSystemDataMot
@Inject @Inject
private TemplateDataFactory templateDataFactory; private TemplateDataFactory templateDataFactory;
@Inject
private VMTemplatePoolDao vmTemplatePoolDao;
@Inject
private DataStoreManagerImpl dataStoreManagerImpl;
@Inject
private VirtualMachineManager virtualMachineManager;
private static final Logger LOGGER = Logger.getLogger(KvmNonManagedStorageDataMotionStrategy.class);
/** /**
* Uses the canHandle from the Super class {@link StorageSystemDataMotionStrategy}. If the storage pool is of file and the internalCanHandle from {@link StorageSystemDataMotionStrategy} CANT_HANDLE, returns the StrategyPriority.HYPERVISOR strategy priority. otherwise returns CANT_HANDLE. * Uses the canHandle from the Super class {@link StorageSystemDataMotionStrategy}. If the storage pool is of file and the internalCanHandle from {@link StorageSystemDataMotionStrategy} CANT_HANDLE, returns the StrategyPriority.HYPERVISOR strategy priority. otherwise returns CANT_HANDLE.
@ -95,7 +117,7 @@ public class KvmNonManagedStorageDataMotionStrategy extends StorageSystemDataMot
String templateUuid = getTemplateUuid(destVolumeInfo.getTemplateId()); String templateUuid = getTemplateUuid(destVolumeInfo.getTemplateId());
CreateCommand rootImageProvisioningCommand = new CreateCommand(diskProfile, templateUuid, destStoragePool, true); CreateCommand rootImageProvisioningCommand = new CreateCommand(diskProfile, templateUuid, destStoragePool, true);
Answer rootImageProvisioningAnswer = _agentMgr.easySend(destHost.getId(), rootImageProvisioningCommand); Answer rootImageProvisioningAnswer = agentManager.easySend(destHost.getId(), rootImageProvisioningCommand);
if (rootImageProvisioningAnswer == null) { if (rootImageProvisioningAnswer == null) {
throw new CloudRuntimeException(String.format("Migration with storage of vm [%s] failed while provisioning root image", vmTO.getName())); throw new CloudRuntimeException(String.format("Migration with storage of vm [%s] failed while provisioning root image", vmTO.getName()));
@ -140,4 +162,77 @@ public class KvmNonManagedStorageDataMotionStrategy extends StorageSystemDataMot
protected boolean shouldMigrateVolume(StoragePoolVO sourceStoragePool, Host destHost, StoragePoolVO destStoragePool) { protected boolean shouldMigrateVolume(StoragePoolVO sourceStoragePool, Host destHost, StoragePoolVO destStoragePool) {
return sourceStoragePool.getPoolType() == StoragePoolType.Filesystem; return sourceStoragePool.getPoolType() == StoragePoolType.Filesystem;
} }
/**
* If the template is not on the target primary storage then it copies the template.
*/
@Override
protected void copyTemplateToTargetFilesystemStorageIfNeeded(VolumeInfo srcVolumeInfo, StoragePool srcStoragePool, DataStore destDataStore, StoragePool destStoragePool,
Host destHost) {
VMTemplateStoragePoolVO sourceVolumeTemplateStoragePoolVO = vmTemplatePoolDao.findByPoolTemplate(destStoragePool.getId(), srcVolumeInfo.getTemplateId());
if (sourceVolumeTemplateStoragePoolVO == null && destStoragePool.getPoolType() == StoragePoolType.Filesystem) {
DataStore sourceTemplateDataStore = dataStoreManagerImpl.getImageStore(srcVolumeInfo.getDataCenterId());
TemplateInfo sourceTemplateInfo = templateDataFactory.getTemplate(srcVolumeInfo.getTemplateId(), sourceTemplateDataStore);
TemplateObjectTO sourceTemplate = new TemplateObjectTO(sourceTemplateInfo);
LOGGER.debug(String.format("Could not find template [id=%s, name=%s] on the storage pool [id=%s]; copying the template to the target storage pool.",
srcVolumeInfo.getTemplateId(), sourceTemplateInfo.getName(), destDataStore.getId()));
TemplateInfo destTemplateInfo = templateDataFactory.getTemplate(srcVolumeInfo.getTemplateId(), destDataStore);
final TemplateObjectTO destTemplate = new TemplateObjectTO(destTemplateInfo);
Answer copyCommandAnswer = sendCopyCommand(destHost, sourceTemplate, destTemplate, destDataStore);
if (copyCommandAnswer != null && copyCommandAnswer.getResult()) {
updateTemplateReferenceIfSuccessfulCopy(srcVolumeInfo, srcStoragePool, destTemplateInfo, destDataStore);
}
}
}
/**
* Update the template reference on table "template_spool_ref" (VMTemplateStoragePoolVO).
*/
protected void updateTemplateReferenceIfSuccessfulCopy(VolumeInfo srcVolumeInfo, StoragePool srcStoragePool, TemplateInfo destTemplateInfo, DataStore destDataStore) {
VMTemplateStoragePoolVO srcVolumeTemplateStoragePoolVO = vmTemplatePoolDao.findByPoolTemplate(srcStoragePool.getId(), srcVolumeInfo.getTemplateId());
VMTemplateStoragePoolVO destVolumeTemplateStoragePoolVO = new VMTemplateStoragePoolVO(destDataStore.getId(), srcVolumeInfo.getTemplateId());
destVolumeTemplateStoragePoolVO.setDownloadPercent(100);
destVolumeTemplateStoragePoolVO.setDownloadState(VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
destVolumeTemplateStoragePoolVO.setState(ObjectInDataStoreStateMachine.State.Ready);
destVolumeTemplateStoragePoolVO.setTemplateSize(srcVolumeTemplateStoragePoolVO.getTemplateSize());
destVolumeTemplateStoragePoolVO.setLocalDownloadPath(destTemplateInfo.getUuid());
destVolumeTemplateStoragePoolVO.setInstallPath(destTemplateInfo.getUuid());
vmTemplatePoolDao.persist(destVolumeTemplateStoragePoolVO);
}
/**
* 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);
}
}
private String generateFailToCopyTemplateMessage(TemplateObjectTO sourceTemplate, DataStore destDataStore) {
return String.format("Failed to copy template [id=%s, name=%s] to the primary storage pool [id=%s].", sourceTemplate.getId(),
sourceTemplate.getName(), destDataStore.getId());
}
/**
* Logs in debug mode the copy command failure if the CopyCommand Answer has result as false.
*/
protected void logInCaseOfTemplateCopyFailure(Answer copyCommandAnswer, TemplateObjectTO sourceTemplate, DataStore destDataStore) {
if (copyCommandAnswer != null && !copyCommandAnswer.getResult()) {
String failureDetails = StringUtils.EMPTY;
if (copyCommandAnswer.getDetails() != null) {
failureDetails = " Details: " + copyCommandAnswer.getDetails();
}
LOGGER.error(generateFailToCopyTemplateMessage(sourceTemplate, destDataStore) + failureDetails);
}
}
} }

View File

@ -112,7 +112,6 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.cloudstack.storage.to.VolumeObjectTO;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -138,28 +137,45 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
private static final String OPERATION_NOT_SUPPORTED = "This operation is not supported."; private static final String OPERATION_NOT_SUPPORTED = "This operation is not supported.";
@Inject @Inject
protected AgentManager _agentMgr; protected AgentManager agentManager;
@Inject private ConfigurationDao _configDao; @Inject
@Inject private DataStoreManager dataStoreMgr; private ConfigurationDao _configDao;
@Inject
private DataStoreManager dataStoreMgr;
@Inject @Inject
protected DiskOfferingDao _diskOfferingDao; protected DiskOfferingDao _diskOfferingDao;
@Inject private GuestOSCategoryDao _guestOsCategoryDao; @Inject
@Inject private GuestOSDao _guestOsDao; private GuestOSCategoryDao _guestOsCategoryDao;
@Inject private ClusterDao clusterDao; @Inject
@Inject private HostDao _hostDao; private GuestOSDao _guestOsDao;
@Inject
private ClusterDao clusterDao;
@Inject
private HostDao _hostDao;
@Inject @Inject
protected PrimaryDataStoreDao _storagePoolDao; protected PrimaryDataStoreDao _storagePoolDao;
@Inject private SnapshotDao _snapshotDao; @Inject
@Inject private SnapshotDataStoreDao _snapshotDataStoreDao; private SnapshotDao _snapshotDao;
@Inject private SnapshotDetailsDao _snapshotDetailsDao; @Inject
@Inject private VMInstanceDao _vmDao; private SnapshotDataStoreDao _snapshotDataStoreDao;
@Inject private VMTemplateDao _vmTemplateDao; @Inject
@Inject private VolumeDao _volumeDao; private SnapshotDetailsDao _snapshotDetailsDao;
@Inject private VolumeDataFactory _volumeDataFactory; @Inject
@Inject private VolumeDetailsDao volumeDetailsDao; private VMInstanceDao _vmDao;
@Inject private VolumeService _volumeService; @Inject
@Inject private StorageCacheManager cacheMgr; private VMTemplateDao _vmTemplateDao;
@Inject private EndPointSelector selector; @Inject
private VolumeDao _volumeDao;
@Inject
private VolumeDataFactory _volumeDataFactory;
@Inject
private VolumeDetailsDao volumeDetailsDao;
@Inject
private VolumeService _volumeService;
@Inject
private StorageCacheManager cacheMgr;
@Inject
private EndPointSelector selector;
@Override @Override
public StrategyPriority canHandle(DataObject srcData, DataObject destData) { public StrategyPriority canHandle(DataObject srcData, DataObject destData) {
@ -926,8 +942,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
} }
} }
String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
int primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
CopyCommand copyCommand = new CopyCommand(snapshotInfo.getTO(), destOnStore.getTO(), primaryStorageDownloadWait, CopyCommand copyCommand = new CopyCommand(snapshotInfo.getTO(), destOnStore.getTO(), primaryStorageDownloadWait,
VirtualMachineManager.ExecuteInSequence.value()); VirtualMachineManager.ExecuteInSequence.value());
@ -953,7 +968,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
copyCommand.setOptions(srcDetails); copyCommand.setOptions(srcDetails);
copyCmdAnswer = (CopyCmdAnswer)_agentMgr.send(hostVO.getId(), copyCommand); copyCmdAnswer = (CopyCmdAnswer)agentManager.send(hostVO.getId(), copyCommand);
if (!copyCmdAnswer.getResult()) { if (!copyCmdAnswer.getResult()) {
errMsg = copyCmdAnswer.getDetails(); errMsg = copyCmdAnswer.getDetails();
@ -1101,8 +1116,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
verifyCopyCmdAnswer(copyCmdAnswer, snapshotInfo); verifyCopyCmdAnswer(copyCmdAnswer, snapshotInfo);
} }
String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
int primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
CopyCommand copyCommand = new CopyCommand(snapshotInfo.getTO(), volumeInfo.getTO(), primaryStorageDownloadWait, CopyCommand copyCommand = new CopyCommand(snapshotInfo.getTO(), volumeInfo.getTO(), primaryStorageDownloadWait,
VirtualMachineManager.ExecuteInSequence.value()); VirtualMachineManager.ExecuteInSequence.value());
@ -1120,7 +1134,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
copyCommand.setOptions(srcDetails); copyCommand.setOptions(srcDetails);
copyCmdAnswer = (CopyCmdAnswer)_agentMgr.send(hostVO.getId(), copyCommand); copyCmdAnswer = (CopyCmdAnswer)agentManager.send(hostVO.getId(), copyCommand);
if (!copyCmdAnswer.getResult()) { if (!copyCmdAnswer.getResult()) {
errMsg = copyCmdAnswer.getDetails(); errMsg = copyCmdAnswer.getDetails();
@ -1594,8 +1608,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
} }
private CopyCmdAnswer copyImageToVolume(DataObject srcDataObject, VolumeInfo destVolumeInfo, HostVO hostVO) { private CopyCmdAnswer copyImageToVolume(DataObject srcDataObject, VolumeInfo destVolumeInfo, HostVO hostVO) {
String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
int primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
CopyCommand copyCommand = new CopyCommand(srcDataObject.getTO(), destVolumeInfo.getTO(), primaryStorageDownloadWait, CopyCommand copyCommand = new CopyCommand(srcDataObject.getTO(), destVolumeInfo.getTO(), primaryStorageDownloadWait,
VirtualMachineManager.ExecuteInSequence.value()); VirtualMachineManager.ExecuteInSequence.value());
@ -1609,7 +1622,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
copyCommand.setOptions2(destDetails); copyCommand.setOptions2(destDetails);
copyCmdAnswer = (CopyCmdAnswer)_agentMgr.send(hostVO.getId(), copyCommand); copyCmdAnswer = (CopyCmdAnswer)agentManager.send(hostVO.getId(), copyCommand);
} }
catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) { catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
String msg = "Failed to copy image : "; String msg = "Failed to copy image : ";
@ -1724,6 +1737,8 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
continue; continue;
} }
copyTemplateToTargetFilesystemStorageIfNeeded(srcVolumeInfo, sourceStoragePool, destDataStore, destStoragePool, destHost);
VolumeVO destVolume = duplicateVolumeOnAnotherStorage(srcVolume, destStoragePool); VolumeVO destVolume = duplicateVolumeOnAnotherStorage(srcVolume, destStoragePool);
VolumeInfo destVolumeInfo = _volumeDataFactory.getVolume(destVolume.getId(), destDataStore); VolumeInfo destVolumeInfo = _volumeDataFactory.getVolume(destVolume.getId(), destDataStore);
@ -1763,7 +1778,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(vmTO); PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(vmTO);
try { try {
Answer pfma = _agentMgr.send(destHost.getId(), pfmc); Answer pfma = agentManager.send(destHost.getId(), pfmc);
if (pfma == null || !pfma.getResult()) { if (pfma == null || !pfma.getResult()) {
String details = pfma != null ? pfma.getDetails() : "null answer returned"; String details = pfma != null ? pfma.getDetails() : "null answer returned";
@ -1791,7 +1806,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
migrateCommand.setAutoConvergence(kvmAutoConvergence); migrateCommand.setAutoConvergence(kvmAutoConvergence);
MigrateAnswer migrateAnswer = (MigrateAnswer)_agentMgr.send(srcHost.getId(), migrateCommand); MigrateAnswer migrateAnswer = (MigrateAnswer)agentManager.send(srcHost.getId(), migrateCommand);
boolean success = migrateAnswer != null && migrateAnswer.getResult(); boolean success = migrateAnswer != null && migrateAnswer.getResult();
@ -1859,6 +1874,15 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
volume.setPath(volume.get_iScsiName()); volume.setPath(volume.get_iScsiName());
} }
/**
* For this strategy it is not necessary to copy the template before migrating the VM.
* However, classes that extend this one may need to copy the template to the target storage pool before migrating the VM.
*/
protected void copyTemplateToTargetFilesystemStorageIfNeeded(VolumeInfo srcVolumeInfo, StoragePool srcStoragePool, DataStore destDataStore, StoragePool destStoragePool,
Host destHost) {
// This method is used by classes that extend this one
}
private void handlePostMigration(boolean success, Map<VolumeInfo, VolumeInfo> srcVolumeInfoToDestVolumeInfo, VirtualMachineTO vmTO, Host destHost) { private void handlePostMigration(boolean success, Map<VolumeInfo, VolumeInfo> srcVolumeInfoToDestVolumeInfo, VirtualMachineTO vmTO, Host destHost) {
if (!success) { if (!success) {
try { try {
@ -1866,7 +1890,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
pfmc.setRollback(true); pfmc.setRollback(true);
Answer pfma = _agentMgr.send(destHost.getId(), pfmc); Answer pfma = agentManager.send(destHost.getId(), pfmc);
if (pfma == null || !pfma.getResult()) { if (pfma == null || !pfma.getResult()) {
String details = pfma != null ? pfma.getDetails() : "null answer returned"; String details = pfma != null ? pfma.getDetails() : "null answer returned";
@ -2007,7 +2031,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
} }
private List<String> sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) { private List<String> sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
ModifyTargetsAnswer modifyTargetsAnswer = (ModifyTargetsAnswer)_agentMgr.easySend(hostId, cmd); ModifyTargetsAnswer modifyTargetsAnswer = (ModifyTargetsAnswer)agentManager.easySend(hostId, cmd);
if (modifyTargetsAnswer == null) { if (modifyTargetsAnswer == null) {
throw new CloudRuntimeException("Unable to get an answer to the modify targets command"); throw new CloudRuntimeException("Unable to get an answer to the modify targets command");
@ -2109,8 +2133,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
HostVO hostVO = getHost(volumeInfo.getDataCenterId(), HypervisorType.KVM, false); HostVO hostVO = getHost(volumeInfo.getDataCenterId(), HypervisorType.KVM, false);
DataStore srcDataStore = volumeInfo.getDataStore(); DataStore srcDataStore = volumeInfo.getDataStore();
String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
int primaryStorageDownloadWait = NumberUtils.toInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
CopyCommand copyCommand = new CopyCommand(volumeInfo.getTO(), templateInfo.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value()); CopyCommand copyCommand = new CopyCommand(volumeInfo.getTO(), templateInfo.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
@ -2125,7 +2148,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
copyCommand.setOptions(srcDetails); copyCommand.setOptions(srcDetails);
copyCmdAnswer = (CopyCmdAnswer)_agentMgr.send(hostVO.getId(), copyCommand); copyCmdAnswer = (CopyCmdAnswer)agentManager.send(hostVO.getId(), copyCommand);
if (!copyCmdAnswer.getResult()) { if (!copyCmdAnswer.getResult()) {
errMsg = copyCmdAnswer.getDetails(); errMsg = copyCmdAnswer.getDetails();
@ -2389,7 +2412,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
try { try {
_volumeService.grantAccess(dataObj, hostVO, dataStore); _volumeService.grantAccess(dataObj, hostVO, dataStore);
answer = (ResignatureAnswer)_agentMgr.send(hostVO.getId(), command); answer = (ResignatureAnswer)agentManager.send(hostVO.getId(), command);
} }
catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) { catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
keepGrantedAccess = false; keepGrantedAccess = false;
@ -2466,7 +2489,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
_volumeService.grantAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore()); _volumeService.grantAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore());
MigrateVolumeAnswer migrateVolumeAnswer = (MigrateVolumeAnswer)_agentMgr.send(hostVO.getId(), migrateVolumeCommand); MigrateVolumeAnswer migrateVolumeAnswer = (MigrateVolumeAnswer)agentManager.send(hostVO.getId(), migrateVolumeCommand);
if (migrateVolumeAnswer == null || !migrateVolumeAnswer.getResult()) { if (migrateVolumeAnswer == null || !migrateVolumeAnswer.getResult()) {
if (migrateVolumeAnswer != null && !StringUtils.isEmpty(migrateVolumeAnswer.getDetails())) { if (migrateVolumeAnswer != null && !StringUtils.isEmpty(migrateVolumeAnswer.getDetails())) {
@ -2534,7 +2557,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
_volumeService.grantAccess(srcVolumeInfo, hostVO, srcVolumeInfo.getDataStore()); _volumeService.grantAccess(srcVolumeInfo, hostVO, srcVolumeInfo.getDataStore());
} }
CopyVolumeAnswer copyVolumeAnswer = (CopyVolumeAnswer)_agentMgr.send(hostVO.getId(), copyVolumeCommand); CopyVolumeAnswer copyVolumeAnswer = (CopyVolumeAnswer)agentManager.send(hostVO.getId(), copyVolumeCommand);
if (copyVolumeAnswer == null || !copyVolumeAnswer.getResult()) { if (copyVolumeAnswer == null || !copyVolumeAnswer.getResult()) {
if (copyVolumeAnswer != null && !StringUtils.isEmpty(copyVolumeAnswer.getDetails())) { if (copyVolumeAnswer != null && !StringUtils.isEmpty(copyVolumeAnswer.getDetails())) {
@ -2592,8 +2615,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
private CopyCmdAnswer performCopyOfVdi(VolumeInfo volumeInfo, SnapshotInfo snapshotInfo, HostVO hostVO) { private CopyCmdAnswer performCopyOfVdi(VolumeInfo volumeInfo, SnapshotInfo snapshotInfo, HostVO hostVO) {
Snapshot.LocationType locationType = snapshotInfo.getLocationType(); Snapshot.LocationType locationType = snapshotInfo.getLocationType();
String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
int primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
DataObject srcData = snapshotInfo; DataObject srcData = snapshotInfo;
CopyCmdAnswer copyCmdAnswer = null; CopyCmdAnswer copyCmdAnswer = null;
@ -2623,7 +2645,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
copyCommand.setOptions2(destDetails); copyCommand.setOptions2(destDetails);
copyCmdAnswer = (CopyCmdAnswer)_agentMgr.send(hostVO.getId(), copyCommand); copyCmdAnswer = (CopyCmdAnswer)agentManager.send(hostVO.getId(), copyCommand);
} }
catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) { catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
String msg = "Failed to perform VDI copy : "; String msg = "Failed to perform VDI copy : ";

View File

@ -25,14 +25,22 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.storage.command.CopyCommand;
import org.apache.cloudstack.storage.datastore.DataStoreManagerImpl;
import org.apache.cloudstack.storage.datastore.PrimaryDataStoreImpl; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreImpl;
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
import org.apache.cloudstack.storage.image.store.ImageStoreImpl;
import org.apache.cloudstack.storage.to.TemplateObjectTO;
import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.cloudstack.storage.volume.VolumeObject;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito; import org.mockito.Mockito;
@ -40,37 +48,52 @@ import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.runners.MockitoJUnitRunner;
import com.cloud.agent.AgentManager; import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.MigrateCommand;
import com.cloud.agent.api.storage.CreateAnswer; import com.cloud.agent.api.storage.CreateAnswer;
import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.CreateCommand;
import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.api.to.VolumeTO; import com.cloud.agent.api.to.VolumeTO;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.CloudException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.host.Host;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.DataStoreRole; import com.cloud.storage.DataStoreRole;
import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.Storage; import com.cloud.storage.Storage;
import com.cloud.storage.StoragePool;
import com.cloud.storage.VMTemplateStoragePoolVO;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.Volume; import com.cloud.storage.Volume;
import com.cloud.storage.VolumeVO; import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.VMTemplatePoolDao;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.DiskProfile; import com.cloud.vm.DiskProfile;
import com.cloud.vm.VirtualMachineManager;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class KvmNonManagedStorageSystemDataMotionTest { public class KvmNonManagedStorageSystemDataMotionTest {
@Mock @Mock
private PrimaryDataStoreDao primaryDataStoreDao; private PrimaryDataStoreDao primaryDataStoreDao;
@Mock @Mock
private TemplateDataFactory templateDataFactory; private TemplateDataFactory templateDataFactory;
@Mock @Mock
private AgentManager agentManager; private AgentManager agentManager;
@Mock @Mock
private DiskOfferingDao diskOfferingDao; private DiskOfferingDao diskOfferingDao;
@Mock
private VirtualMachineManager virtualMachineManager;
@Mock
private VMTemplatePoolDao vmTemplatePoolDao;
@Mock
private DataStoreManagerImpl dataStoreManagerImpl;
@Mock
private VolumeDataFactory volumeDataFactory;
@Spy @Spy
@InjectMocks @InjectMocks
@ -253,4 +276,125 @@ public class KvmNonManagedStorageSystemDataMotionTest {
} }
} }
} }
@Test
public void sendCopyCommandTest() throws AgentUnavailableException, OperationTimedoutException {
configureAndTestSendCommandTest(null);
}
@Test(expected = CloudRuntimeException.class)
public void sendCopyCommandTestThrowAgentUnavailableException() throws AgentUnavailableException, OperationTimedoutException {
configureAndTestSendCommandTest(AgentUnavailableException.class);
}
@Test(expected = CloudRuntimeException.class)
public void sendCopyCommandTestThrowOperationTimedoutException() throws AgentUnavailableException, OperationTimedoutException {
configureAndTestSendCommandTest(OperationTimedoutException.class);
}
private void configureAndTestSendCommandTest(Class<? extends CloudException> exception) throws AgentUnavailableException, OperationTimedoutException {
Host destHost = new HostVO("guid");
TemplateObjectTO sourceTemplate = new TemplateObjectTO();
sourceTemplate.setName("name");
sourceTemplate.setId(0l);
TemplateObjectTO destTemplate = new TemplateObjectTO();
ImageStoreVO dataStoreVO = Mockito.mock(ImageStoreVO.class);
Mockito.when(dataStoreVO.getId()).thenReturn(0l);
ImageStoreEntity destDataStore = Mockito.mock(ImageStoreImpl.class);
Mockito.doReturn(0l).when(destDataStore).getId();
Answer copyCommandAnswer = Mockito.mock(Answer.class);
if (exception == null) {
Mockito.doReturn(copyCommandAnswer).when(agentManager).send(Mockito.anyLong(), Mockito.any(CopyCommand.class));
} else {
Mockito.doThrow(exception).when(agentManager).send(Mockito.anyLong(), Mockito.any(CopyCommand.class));
}
Mockito.doNothing().when(kvmNonManagedStorageDataMotionStrategy).logInCaseOfTemplateCopyFailure(Mockito.any(Answer.class), Mockito.any(TemplateObjectTO.class),
Mockito.any(DataStore.class));
kvmNonManagedStorageDataMotionStrategy.sendCopyCommand(destHost, sourceTemplate, destTemplate, destDataStore);
InOrder verifyInOrder = Mockito.inOrder(virtualMachineManager, agentManager, kvmNonManagedStorageDataMotionStrategy);
verifyInOrder.verify(virtualMachineManager).getExecuteInSequence(HypervisorType.KVM);
verifyInOrder.verify(agentManager).send(Mockito.anyLong(), Mockito.any(CopyCommand.class));
verifyInOrder.verify(kvmNonManagedStorageDataMotionStrategy).logInCaseOfTemplateCopyFailure(Mockito.any(Answer.class), Mockito.any(TemplateObjectTO.class),
Mockito.any(DataStore.class));
}
@Test
public void copyTemplateToTargetStorageIfNeededTestTemplateAlreadyOnTargetHost() throws AgentUnavailableException, OperationTimedoutException {
Answer copyCommandAnswer = Mockito.mock(Answer.class);
Mockito.when(copyCommandAnswer.getResult()).thenReturn(true);
configureAndTestcopyTemplateToTargetStorageIfNeeded(new VMTemplateStoragePoolVO(0l, 0l), StoragePoolType.Filesystem, 0);
}
@Test
public void migrateTemplateToTargetStorageIfNeededTestTemplateNotOnTargetHost() throws AgentUnavailableException, OperationTimedoutException {
configureAndTestcopyTemplateToTargetStorageIfNeeded(null, StoragePoolType.Filesystem, 1);
}
@Test
public void migrateTemplateToTargetStorageIfNeededTestNonDesiredStoragePoolType() throws AgentUnavailableException, OperationTimedoutException {
StoragePoolType[] storagePoolTypeArray = StoragePoolType.values();
for (int i = 0; i < storagePoolTypeArray.length; i++) {
if (storagePoolTypeArray[i] == StoragePoolType.Filesystem) {
continue;
}
configureAndTestcopyTemplateToTargetStorageIfNeeded(new VMTemplateStoragePoolVO(0l, 0l), storagePoolTypeArray[i], 0);
}
}
private void configureAndTestcopyTemplateToTargetStorageIfNeeded(VMTemplateStoragePoolVO vmTemplateStoragePoolVO, StoragePoolType storagePoolType, int times) {
DataStore destDataStore = Mockito.mock(DataStore.class);
Host destHost = Mockito.mock(Host.class);
VolumeInfo srcVolumeInfo = Mockito.mock(VolumeInfo.class);
Mockito.when(srcVolumeInfo.getTemplateId()).thenReturn(0l);
StoragePool srcStoragePool = Mockito.mock(StoragePool.class);
VolumeInfo destVolumeInfo = Mockito.mock(VolumeInfo.class);
Mockito.when(volumeDataFactory.getVolume(Mockito.anyLong(), Mockito.any(DataStore.class))).thenReturn(destVolumeInfo);
StoragePool destStoragePool = Mockito.mock(StoragePool.class);
Mockito.when(destStoragePool.getId()).thenReturn(0l);
Mockito.when(destStoragePool.getPoolType()).thenReturn(storagePoolType);
DataStore sourceTemplateDataStore = Mockito.mock(DataStore.class);
Mockito.when(sourceTemplateDataStore.getName()).thenReturn("sourceTemplateName");
TemplateInfo sourceTemplateInfo = Mockito.mock(TemplateInfo.class);
Mockito.when(sourceTemplateInfo.getInstallPath()).thenReturn("installPath");
Mockito.when(sourceTemplateInfo.getUuid()).thenReturn("uuid");
Mockito.when(sourceTemplateInfo.getId()).thenReturn(0l);
Mockito.when(sourceTemplateInfo.getUrl()).thenReturn("url");
Mockito.when(sourceTemplateInfo.getDisplayText()).thenReturn("display text");
Mockito.when(sourceTemplateInfo.getChecksum()).thenReturn("checksum");
Mockito.when(sourceTemplateInfo.isRequiresHvm()).thenReturn(true);
Mockito.when(sourceTemplateInfo.getAccountId()).thenReturn(0l);
Mockito.when(sourceTemplateInfo.getUniqueName()).thenReturn("unique name");
Mockito.when(sourceTemplateInfo.getFormat()).thenReturn(ImageFormat.QCOW2);
Mockito.when(sourceTemplateInfo.getSize()).thenReturn(0l);
Mockito.when(sourceTemplateInfo.getHypervisorType()).thenReturn(HypervisorType.KVM);
Mockito.when(vmTemplatePoolDao.findByPoolTemplate(Mockito.anyLong(), Mockito.anyLong())).thenReturn(vmTemplateStoragePoolVO);
Mockito.when(dataStoreManagerImpl.getImageStore(Mockito.anyLong())).thenReturn(sourceTemplateDataStore);
Mockito.when(templateDataFactory.getTemplate(Mockito.anyLong(), Mockito.eq(sourceTemplateDataStore))).thenReturn(sourceTemplateInfo);
Mockito.when(templateDataFactory.getTemplate(Mockito.anyLong(), Mockito.eq(destDataStore))).thenReturn(sourceTemplateInfo);
kvmNonManagedStorageDataMotionStrategy.copyTemplateToTargetFilesystemStorageIfNeeded(srcVolumeInfo, srcStoragePool, destDataStore, destStoragePool, destHost);
Mockito.doNothing().when(kvmNonManagedStorageDataMotionStrategy).updateTemplateReferenceIfSuccessfulCopy(Mockito.any(VolumeInfo.class), Mockito.any(StoragePool.class),
Mockito.any(TemplateInfo.class), Mockito.any(DataStore.class));
InOrder verifyInOrder = Mockito.inOrder(vmTemplatePoolDao, dataStoreManagerImpl, templateDataFactory, kvmNonManagedStorageDataMotionStrategy);
verifyInOrder.verify(vmTemplatePoolDao, Mockito.times(1)).findByPoolTemplate(Mockito.anyLong(), Mockito.anyLong());
verifyInOrder.verify(dataStoreManagerImpl, Mockito.times(times)).getImageStore(Mockito.anyLong());
verifyInOrder.verify(templateDataFactory, Mockito.times(times)).getTemplate(Mockito.anyLong(), Mockito.eq(sourceTemplateDataStore));
verifyInOrder.verify(templateDataFactory, Mockito.times(times)).getTemplate(Mockito.anyLong(), Mockito.eq(destDataStore));
verifyInOrder.verify(kvmNonManagedStorageDataMotionStrategy, Mockito.times(times)).sendCopyCommand(Mockito.eq(destHost), Mockito.any(TemplateObjectTO.class),
Mockito.any(TemplateObjectTO.class), Mockito.eq(destDataStore));
}
} }

View File

@ -61,7 +61,6 @@ import com.cloud.agent.api.to.DataObjectType;
import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.DataTO;
import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.configuration.Config;
import com.cloud.exception.StorageUnavailableException; import com.cloud.exception.StorageUnavailableException;
import com.cloud.host.Host; import com.cloud.host.Host;
import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDao;
@ -77,7 +76,6 @@ import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.template.TemplateManager; import com.cloud.template.TemplateManager;
import com.cloud.utils.NumbersUtil;
import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.dao.VMInstanceDao;
public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver { public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver {
@ -256,13 +254,12 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri
callback.complete(result); callback.complete(result);
} else if (srcdata.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.VOLUME) { } else if (srcdata.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.VOLUME) {
//For CLVM, we need to pass template on secondary storage to hypervisor //For CLVM, we need to pass template on secondary storage to hypervisor
String value = configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
int _primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
StoragePoolVO storagePoolVO = primaryStoreDao.findById(store.getId()); StoragePoolVO storagePoolVO = primaryStoreDao.findById(store.getId());
DataStore imageStore = templateManager.getImageStore(storagePoolVO.getDataCenterId(), srcdata.getId()); DataStore imageStore = templateManager.getImageStore(storagePoolVO.getDataCenterId(), srcdata.getId());
DataObject srcData = templateDataFactory.getTemplate(srcdata.getId(), imageStore); DataObject srcData = templateDataFactory.getTemplate(srcdata.getId(), imageStore);
CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _primaryStorageDownloadWait, true); CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), primaryStorageDownloadWait, true);
EndPoint ep = epSelector.select(srcData, destData); EndPoint ep = epSelector.select(srcData, destData);
Answer answer = null; Answer answer = null;
if (ep == null) { if (ep == null) {

View File

@ -187,14 +187,6 @@ public enum Config {
"3600", "3600",
"Timeout (in seconds) to synchronize storage pool operations.", "Timeout (in seconds) to synchronize storage pool operations.",
null), null),
PrimaryStorageDownloadWait(
"Storage",
TemplateManager.class,
Integer.class,
"primary.storage.download.wait",
"10800",
"In second, timeout for download template to primary storage",
null),
CreateVolumeFromSnapshotWait( CreateVolumeFromSnapshotWait(
"Storage", "Storage",
StorageManager.class, StorageManager.class,

View File

@ -2489,7 +2489,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
@Override @Override
public ConfigKey<?>[] getConfigKeys() { public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] { StorageCleanupInterval, StorageCleanupDelay, StorageCleanupEnabled, TemplateCleanupEnabled, return new ConfigKey<?>[] { StorageCleanupInterval, StorageCleanupDelay, StorageCleanupEnabled, TemplateCleanupEnabled,
KvmStorageOfflineMigrationWait, KvmStorageOnlineMigrationWait, MaxNumberOfManagedClusteredFileSystems }; KvmStorageOfflineMigrationWait, KvmStorageOnlineMigrationWait, MaxNumberOfManagedClusteredFileSystems, PRIMARY_STORAGE_DOWNLOAD_WAIT};
} }
@Override @Override