mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-8862: Introduced new state attaching for volume. This will make sure that other attach operation on same volume will fail gracefully without calling access calls for managed storage like SolidFire
Also, skipping test_upload_attach_volume as there is no implementation which supports this.
This commit is contained in:
parent
b8dd08c362
commit
b766bf7fc9
@ -51,7 +51,8 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba
|
|||||||
NotUploaded("The volume entry is just created in DB, not yet uploaded"),
|
NotUploaded("The volume entry is just created in DB, not yet uploaded"),
|
||||||
UploadInProgress("Volume upload is in progress"),
|
UploadInProgress("Volume upload is in progress"),
|
||||||
UploadError("Volume upload encountered some error"),
|
UploadError("Volume upload encountered some error"),
|
||||||
UploadAbandoned("Volume upload is abandoned since the upload was never initiated within a specificed time");
|
UploadAbandoned("Volume upload is abandoned since the upload was never initiated within a specificed time"),
|
||||||
|
Attaching("The volume is attaching to a VM");
|
||||||
|
|
||||||
String _description;
|
String _description;
|
||||||
|
|
||||||
@ -118,6 +119,9 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba
|
|||||||
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadInProgress, Event.OperationTimeout, UploadError, null));
|
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadInProgress, Event.OperationTimeout, UploadError, null));
|
||||||
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadError, Event.DestroyRequested, Destroy, null));
|
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadError, Event.DestroyRequested, Destroy, null));
|
||||||
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadAbandoned, Event.DestroyRequested, Destroy, null));
|
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadAbandoned, Event.DestroyRequested, Destroy, null));
|
||||||
|
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Ready, Event.AttachRequested, Attaching, null));
|
||||||
|
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Attaching, Event.OperationSucceeded, Ready, null));
|
||||||
|
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Attaching, Event.OperationFailed, Ready, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,6 +143,7 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba
|
|||||||
DestroyRequested,
|
DestroyRequested,
|
||||||
ExpungingRequested,
|
ExpungingRequested,
|
||||||
ResizeRequested,
|
ResizeRequested,
|
||||||
|
AttachRequested,
|
||||||
OperationTimeout;
|
OperationTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1459,7 +1459,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanupVolumeDuringAttachFailure(Long volumeId) {
|
private void cleanupVolumeDuringAttachFailure(Long volumeId, Long vmId) {
|
||||||
VolumeVO volume = _volsDao.findById(volumeId);
|
VolumeVO volume = _volsDao.findById(volumeId);
|
||||||
if (volume == null) {
|
if (volume == null) {
|
||||||
return;
|
return;
|
||||||
@ -1469,6 +1469,13 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
s_logger.debug("Remove volume: " + volume.getId() + ", as it's leftover from last mgt server stop");
|
s_logger.debug("Remove volume: " + volume.getId() + ", as it's leftover from last mgt server stop");
|
||||||
_volsDao.remove(volume.getId());
|
_volsDao.remove(volume.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(volume.getState().equals(Volume.State.Attaching)) {
|
||||||
|
s_logger.warn("Vol: " + volume.getName() + " failed to attach to VM: " + _userVmDao.findById(vmId).getHostName() +
|
||||||
|
" on last mgt server stop, changing state back to Ready");
|
||||||
|
volume.setState(Volume.State.Ready);
|
||||||
|
_volsDao.update(volumeId, volume);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanupVolumeDuringMigrationFailure(Long volumeId, Long destPoolId) {
|
private void cleanupVolumeDuringMigrationFailure(Long volumeId, Long destPoolId) {
|
||||||
@ -1512,7 +1519,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
try {
|
try {
|
||||||
if (job.getCmd().equalsIgnoreCase(VmWorkAttachVolume.class.getName())) {
|
if (job.getCmd().equalsIgnoreCase(VmWorkAttachVolume.class.getName())) {
|
||||||
VmWorkAttachVolume work = VmWorkSerializer.deserialize(VmWorkAttachVolume.class, job.getCmdInfo());
|
VmWorkAttachVolume work = VmWorkSerializer.deserialize(VmWorkAttachVolume.class, job.getCmdInfo());
|
||||||
cleanupVolumeDuringAttachFailure(work.getVolumeId());
|
cleanupVolumeDuringAttachFailure(work.getVolumeId(), work.getVmId());
|
||||||
} else if (job.getCmd().equalsIgnoreCase(VmWorkMigrateVolume.class.getName())) {
|
} else if (job.getCmd().equalsIgnoreCase(VmWorkMigrateVolume.class.getName())) {
|
||||||
VmWorkMigrateVolume work = VmWorkSerializer.deserialize(VmWorkMigrateVolume.class, job.getCmdInfo());
|
VmWorkMigrateVolume work = VmWorkSerializer.deserialize(VmWorkMigrateVolume.class, job.getCmdInfo());
|
||||||
cleanupVolumeDuringMigrationFailure(work.getVolumeId(), work.getDestPoolId());
|
cleanupVolumeDuringMigrationFailure(work.getVolumeId(), work.getDestPoolId());
|
||||||
|
|||||||
@ -2474,6 +2474,26 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
return !storeForExistingStoreScope.isSameScope(storeForNewStoreScope);
|
return !storeForExistingStoreScope.isSameScope(storeForNewStoreScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private synchronized void checkAndSetAttaching(Long volumeId, Long hostId) {
|
||||||
|
VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
|
||||||
|
|
||||||
|
if (volumeToAttach.isAttachedVM()) {
|
||||||
|
throw new CloudRuntimeException("volume: " + volumeToAttach.getName() + " is already attached to a VM: " + volumeToAttach.getAttachedVmName());
|
||||||
|
}
|
||||||
|
if (volumeToAttach.getState().equals(Volume.State.Ready)) {
|
||||||
|
volumeToAttach.stateTransit(Volume.Event.AttachRequested);
|
||||||
|
} else {
|
||||||
|
String error = null;
|
||||||
|
if (hostId == null) {
|
||||||
|
error = "Please try attach operation after starting VM once";
|
||||||
|
} else {
|
||||||
|
error = "Volume: " + volumeToAttach.getName() + " is in " + volumeToAttach.getState() + ". It should be in Ready state";
|
||||||
|
}
|
||||||
|
s_logger.error(error);
|
||||||
|
throw new CloudRuntimeException(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private VolumeVO sendAttachVolumeCommand(UserVmVO vm, VolumeVO volumeToAttach, Long deviceId) {
|
private VolumeVO sendAttachVolumeCommand(UserVmVO vm, VolumeVO volumeToAttach, Long deviceId) {
|
||||||
String errorMsg = "Failed to attach volume " + volumeToAttach.getName() + " to VM " + vm.getHostName();
|
String errorMsg = "Failed to attach volume " + volumeToAttach.getName() + " to VM " + vm.getHostName();
|
||||||
boolean sendCommand = vm.getState() == State.Running;
|
boolean sendCommand = vm.getState() == State.Running;
|
||||||
@ -2504,112 +2524,128 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
// volumeToAttachStoragePool should be null if the VM we are attaching the disk to has never been started before
|
// volumeToAttachStoragePool should be null if the VM we are attaching the disk to has never been started before
|
||||||
DataStore dataStore = volumeToAttachStoragePool != null ? dataStoreMgr.getDataStore(volumeToAttachStoragePool.getId(), DataStoreRole.Primary) : null;
|
DataStore dataStore = volumeToAttachStoragePool != null ? dataStoreMgr.getDataStore(volumeToAttachStoragePool.getId(), DataStoreRole.Primary) : null;
|
||||||
|
|
||||||
// if we don't have a host, the VM we are attaching the disk to has never been started before
|
checkAndSetAttaching(volumeToAttach.getId(), hostId);
|
||||||
if (host != null) {
|
|
||||||
try {
|
|
||||||
volService.grantAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
volService.revokeAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
|
|
||||||
|
|
||||||
throw new CloudRuntimeException(e.getMessage());
|
boolean attached = false;
|
||||||
}
|
try {
|
||||||
}
|
// if we don't have a host, the VM we are attaching the disk to has never been started before
|
||||||
|
if (host != null) {
|
||||||
if (sendCommand) {
|
try {
|
||||||
if (host != null && host.getHypervisorType() == HypervisorType.KVM &&
|
volService.grantAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
|
||||||
volumeToAttachStoragePool.isManaged() &&
|
}
|
||||||
volumeToAttach.getPath() == null) {
|
catch (Exception e) {
|
||||||
volumeToAttach.setPath(volumeToAttach.get_iScsiName());
|
volService.revokeAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
|
||||||
|
|
||||||
_volsDao.update(volumeToAttach.getId(), volumeToAttach);
|
throw new CloudRuntimeException(e.getMessage());
|
||||||
}
|
|
||||||
|
|
||||||
DataTO volTO = volFactory.getVolume(volumeToAttach.getId()).getTO();
|
|
||||||
|
|
||||||
deviceId = getDeviceId(vm, deviceId);
|
|
||||||
|
|
||||||
DiskTO disk = storageMgr.getDiskWithThrottling(volTO, volumeToAttach.getVolumeType(), deviceId, volumeToAttach.getPath(),
|
|
||||||
vm.getServiceOfferingId(), volumeToAttach.getDiskOfferingId());
|
|
||||||
|
|
||||||
AttachCommand cmd = new AttachCommand(disk, vm.getInstanceName());
|
|
||||||
|
|
||||||
ChapInfo chapInfo = volService.getChapInfo(volFactory.getVolume(volumeToAttach.getId()), dataStore);
|
|
||||||
|
|
||||||
Map<String, String> details = new HashMap<String, String>();
|
|
||||||
|
|
||||||
disk.setDetails(details);
|
|
||||||
|
|
||||||
details.put(DiskTO.MANAGED, String.valueOf(volumeToAttachStoragePool.isManaged()));
|
|
||||||
details.put(DiskTO.STORAGE_HOST, volumeToAttachStoragePool.getHostAddress());
|
|
||||||
details.put(DiskTO.STORAGE_PORT, String.valueOf(volumeToAttachStoragePool.getPort()));
|
|
||||||
details.put(DiskTO.VOLUME_SIZE, String.valueOf(volumeToAttach.getSize()));
|
|
||||||
details.put(DiskTO.IQN, volumeToAttach.get_iScsiName());
|
|
||||||
details.put(DiskTO.MOUNT_POINT, volumeToAttach.get_iScsiName());
|
|
||||||
details.put(DiskTO.PROTOCOL_TYPE, (volumeToAttach.getPoolType() != null) ? volumeToAttach.getPoolType().toString() : null);
|
|
||||||
|
|
||||||
if (chapInfo != null) {
|
|
||||||
details.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
|
|
||||||
details.put(DiskTO.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
|
|
||||||
details.put(DiskTO.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
|
|
||||||
details.put(DiskTO.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
|
|
||||||
}
|
|
||||||
_userVmDao.loadDetails(vm);
|
|
||||||
Map<String, String> controllerInfo = new HashMap<String, String>();
|
|
||||||
controllerInfo.put(VmDetailConstants.ROOT_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER));
|
|
||||||
controllerInfo.put(VmDetailConstants.DATA_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.DATA_DISK_CONTROLLER));
|
|
||||||
cmd.setControllerInfo(controllerInfo);
|
|
||||||
s_logger.debug("Attach volume id:" + volumeToAttach.getId() + " on VM id:" + vm.getId() + " has controller info:" + controllerInfo);
|
|
||||||
|
|
||||||
try {
|
|
||||||
answer = (AttachAnswer)_agentMgr.send(hostId, cmd);
|
|
||||||
} catch (Exception e) {
|
|
||||||
if(host!=null) {
|
|
||||||
volService.revokeAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
|
|
||||||
}
|
}
|
||||||
throw new CloudRuntimeException(errorMsg + " due to: " + e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!sendCommand || (answer != null && answer.getResult())) {
|
|
||||||
// Mark the volume as attached
|
|
||||||
if (sendCommand) {
|
if (sendCommand) {
|
||||||
DiskTO disk = answer.getDisk();
|
if (host != null && host.getHypervisorType() == HypervisorType.KVM &&
|
||||||
_volsDao.attachVolume(volumeToAttach.getId(), vm.getId(), disk.getDiskSeq());
|
volumeToAttachStoragePool.isManaged() &&
|
||||||
|
volumeToAttach.getPath() == null) {
|
||||||
volumeToAttach = _volsDao.findById(volumeToAttach.getId());
|
volumeToAttach.setPath(volumeToAttach.get_iScsiName());
|
||||||
|
|
||||||
if (volumeToAttachStoragePool.isManaged() && volumeToAttach.getPath() == null) {
|
|
||||||
volumeToAttach.setPath(answer.getDisk().getPath());
|
|
||||||
|
|
||||||
_volsDao.update(volumeToAttach.getId(), volumeToAttach);
|
_volsDao.update(volumeToAttach.getId(), volumeToAttach);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
DataTO volTO = volFactory.getVolume(volumeToAttach.getId()).getTO();
|
||||||
|
|
||||||
deviceId = getDeviceId(vm, deviceId);
|
deviceId = getDeviceId(vm, deviceId);
|
||||||
|
|
||||||
_volsDao.attachVolume(volumeToAttach.getId(), vm.getId(), deviceId);
|
DiskTO disk = storageMgr.getDiskWithThrottling(volTO, volumeToAttach.getVolumeType(), deviceId, volumeToAttach.getPath(),
|
||||||
}
|
vm.getServiceOfferingId(), volumeToAttach.getDiskOfferingId());
|
||||||
|
|
||||||
// insert record for disk I/O statistics
|
AttachCommand cmd = new AttachCommand(disk, vm.getInstanceName());
|
||||||
VmDiskStatisticsVO diskstats = _vmDiskStatsDao.findBy(vm.getAccountId(), vm.getDataCenterId(), vm.getId(), volumeToAttach.getId());
|
|
||||||
if (diskstats == null) {
|
|
||||||
diskstats = new VmDiskStatisticsVO(vm.getAccountId(), vm.getDataCenterId(), vm.getId(), volumeToAttach.getId());
|
|
||||||
_vmDiskStatsDao.persist(diskstats);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _volsDao.findById(volumeToAttach.getId());
|
ChapInfo chapInfo = volService.getChapInfo(volFactory.getVolume(volumeToAttach.getId()), dataStore);
|
||||||
} else {
|
|
||||||
if (answer != null) {
|
Map<String, String> details = new HashMap<String, String>();
|
||||||
String details = answer.getDetails();
|
|
||||||
if (details != null && !details.isEmpty()) {
|
disk.setDetails(details);
|
||||||
errorMsg += "; " + details;
|
|
||||||
|
details.put(DiskTO.MANAGED, String.valueOf(volumeToAttachStoragePool.isManaged()));
|
||||||
|
details.put(DiskTO.STORAGE_HOST, volumeToAttachStoragePool.getHostAddress());
|
||||||
|
details.put(DiskTO.STORAGE_PORT, String.valueOf(volumeToAttachStoragePool.getPort()));
|
||||||
|
details.put(DiskTO.VOLUME_SIZE, String.valueOf(volumeToAttach.getSize()));
|
||||||
|
details.put(DiskTO.IQN, volumeToAttach.get_iScsiName());
|
||||||
|
details.put(DiskTO.MOUNT_POINT, volumeToAttach.get_iScsiName());
|
||||||
|
details.put(DiskTO.PROTOCOL_TYPE, (volumeToAttach.getPoolType() != null) ? volumeToAttach.getPoolType().toString() : null);
|
||||||
|
|
||||||
|
if (chapInfo != null) {
|
||||||
|
details.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
|
||||||
|
details.put(DiskTO.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
|
||||||
|
details.put(DiskTO.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
|
||||||
|
details.put(DiskTO.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
|
||||||
|
}
|
||||||
|
_userVmDao.loadDetails(vm);
|
||||||
|
Map<String, String> controllerInfo = new HashMap<String, String>();
|
||||||
|
controllerInfo.put(VmDetailConstants.ROOT_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER));
|
||||||
|
controllerInfo.put(VmDetailConstants.DATA_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.DATA_DISK_CONTROLLER));
|
||||||
|
cmd.setControllerInfo(controllerInfo);
|
||||||
|
s_logger.debug("Attach volume id:" + volumeToAttach.getId() + " on VM id:" + vm.getId() + " has controller info:" + controllerInfo);
|
||||||
|
|
||||||
|
try {
|
||||||
|
answer = (AttachAnswer)_agentMgr.send(hostId, cmd);
|
||||||
|
} catch (Exception e) {
|
||||||
|
if(host!=null) {
|
||||||
|
volService.revokeAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
|
||||||
|
}
|
||||||
|
throw new CloudRuntimeException(errorMsg + " due to: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(host!= null) {
|
|
||||||
volService.revokeAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
|
if (!sendCommand || (answer != null && answer.getResult())) {
|
||||||
|
// Mark the volume as attached
|
||||||
|
if (sendCommand) {
|
||||||
|
DiskTO disk = answer.getDisk();
|
||||||
|
_volsDao.attachVolume(volumeToAttach.getId(), vm.getId(), disk.getDiskSeq());
|
||||||
|
|
||||||
|
volumeToAttach = _volsDao.findById(volumeToAttach.getId());
|
||||||
|
|
||||||
|
if (volumeToAttachStoragePool.isManaged() && volumeToAttach.getPath() == null) {
|
||||||
|
volumeToAttach.setPath(answer.getDisk().getPath());
|
||||||
|
|
||||||
|
_volsDao.update(volumeToAttach.getId(), volumeToAttach);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
deviceId = getDeviceId(vm, deviceId);
|
||||||
|
|
||||||
|
_volsDao.attachVolume(volumeToAttach.getId(), vm.getId(), deviceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert record for disk I/O statistics
|
||||||
|
VmDiskStatisticsVO diskstats = _vmDiskStatsDao.findBy(vm.getAccountId(), vm.getDataCenterId(), vm.getId(), volumeToAttach.getId());
|
||||||
|
if (diskstats == null) {
|
||||||
|
diskstats = new VmDiskStatisticsVO(vm.getAccountId(), vm.getDataCenterId(), vm.getId(), volumeToAttach.getId());
|
||||||
|
_vmDiskStatsDao.persist(diskstats);
|
||||||
|
}
|
||||||
|
|
||||||
|
attached = true;
|
||||||
|
} else {
|
||||||
|
if (answer != null) {
|
||||||
|
String details = answer.getDetails();
|
||||||
|
if (details != null && !details.isEmpty()) {
|
||||||
|
errorMsg += "; " + details;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (host != null) {
|
||||||
|
volService.revokeAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
|
||||||
|
}
|
||||||
|
throw new CloudRuntimeException(errorMsg);
|
||||||
}
|
}
|
||||||
throw new CloudRuntimeException(errorMsg);
|
} finally {
|
||||||
|
Volume.Event ev = Volume.Event.OperationFailed;
|
||||||
|
VolumeInfo volInfo = volFactory.getVolume(volumeToAttach.getId());
|
||||||
|
if(attached) {
|
||||||
|
ev = Volume.Event.OperationSucceeded;
|
||||||
|
s_logger.debug("Volume: " + volInfo.getName() + " successfully attached to VM: " + volInfo.getAttachedVmName());
|
||||||
|
} else {
|
||||||
|
s_logger.debug("Volume: " + volInfo.getName() + " failed to attach to VM: " + volInfo.getAttachedVmName());
|
||||||
|
}
|
||||||
|
volInfo.stateTransit(ev);
|
||||||
}
|
}
|
||||||
|
return _volsDao.findById(volumeToAttach.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getMaxDataVolumesSupported(UserVmVO vm) {
|
private int getMaxDataVolumesSupported(UserVmVO vm) {
|
||||||
|
|||||||
@ -249,6 +249,9 @@ class TestDeployVM(cloudstackTestCase):
|
|||||||
# should be "Stopped".
|
# should be "Stopped".
|
||||||
# 3. Attach volume should be successful
|
# 3. Attach volume should be successful
|
||||||
|
|
||||||
|
# Skipping this test
|
||||||
|
self.skipTest("Skipping test as proper implementation seems to be missing")
|
||||||
|
|
||||||
self.debug("Deploying instance in the account: %s" %
|
self.debug("Deploying instance in the account: %s" %
|
||||||
self.account.name)
|
self.account.name)
|
||||||
self.virtual_machine = VirtualMachine.create(
|
self.virtual_machine = VirtualMachine.create(
|
||||||
@ -369,6 +372,9 @@ class TestDeployVM(cloudstackTestCase):
|
|||||||
# 3. Attach volume should be successful
|
# 3. Attach volume should be successful
|
||||||
# 4. Detach volume from instance. Detach should be successful
|
# 4. Detach volume from instance. Detach should be successful
|
||||||
|
|
||||||
|
# Skipping this test
|
||||||
|
self.skipTest("Skipping test as proper implementation seems to be missing")
|
||||||
|
|
||||||
self.debug("Deploying instance in the account: %s" %
|
self.debug("Deploying instance in the account: %s" %
|
||||||
self.account.name)
|
self.account.name)
|
||||||
self.virtual_machine = VirtualMachine.create(
|
self.virtual_machine = VirtualMachine.create(
|
||||||
@ -1474,7 +1480,7 @@ class TestUploadAttachVolume(cloudstackTestCase):
|
|||||||
|
|
||||||
cls.testdata = cls.testClient.getParsedTestDataConfig()
|
cls.testdata = cls.testClient.getParsedTestDataConfig()
|
||||||
cls.hypervisor = cls.testClient.getHypervisorInfo()
|
cls.hypervisor = cls.testClient.getHypervisorInfo()
|
||||||
cls.skip = False
|
cls.skip = True
|
||||||
|
|
||||||
if cls.hypervisor.lower() == 'lxc':
|
if cls.hypervisor.lower() == 'lxc':
|
||||||
if not find_storage_pool_type(cls.apiclient, storagetype='rbd'):
|
if not find_storage_pool_type(cls.apiclient, storagetype='rbd'):
|
||||||
@ -1519,7 +1525,8 @@ class TestUploadAttachVolume(cloudstackTestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
if self.skip:
|
if self.skip:
|
||||||
self.skipTest("RBD storage type is required for data volumes for LXC")
|
self.skipTest("Attach operation for uploaded volume to VM which is not started once is not supported")
|
||||||
|
# self.skipTest("RBD storage type is required for data volumes for LXC")
|
||||||
|
|
||||||
self.apiclient = self.testClient.getApiClient()
|
self.apiclient = self.testClient.getApiClient()
|
||||||
self.dbclient = self.testClient.getDbConnection()
|
self.dbclient = self.testClient.getDbConnection()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user