Skip to content

Commit 557b3ba

Browse files
committed
changes for attaching allocated vol to a stopped vm
Signed-off-by: Abhishek Kumar <[email protected]>
1 parent 8d95a51 commit 557b3ba

File tree

2 files changed

+50
-17
lines changed

2 files changed

+50
-17
lines changed

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2426,7 +2426,7 @@ protected VolumeVO getVmExistingVolumeForVolumeAttach(UserVmVO vm, VolumeInfo vo
24262426
return existingVolumeOfVm;
24272427
}
24282428

2429-
protected StoragePool getPoolForAllocatedOrUploadedVolumeForAttach(final VolumeInfo volumeToAttach, final UserVmVO vm) {
2429+
protected StoragePool getSuitablePoolForAllocatedOrUploadedVolumeForAttach(final VolumeInfo volumeToAttach, final UserVmVO vm) {
24302430
DataCenter zone = _dcDao.findById(vm.getDataCenterId());
24312431
Pair<Long, Long> clusterHostId = virtualMachineManager.findClusterAndHostIdForVm(vm, false);
24322432
Long podId = vm.getPodIdToDeployIn();
@@ -2441,12 +2441,8 @@ protected StoragePool getPoolForAllocatedOrUploadedVolumeForAttach(final VolumeI
24412441
offering.isUseLocalStorage(), offering.isRecreatable(),
24422442
volumeToAttach.getTemplateId());
24432443
diskProfile.setHyperType(vm.getHypervisorType());
2444-
StoragePool pool = _volumeMgr.findStoragePool(diskProfile, zone, pod, clusterHostId.first(),
2444+
return _volumeMgr.findStoragePool(diskProfile, zone, pod, clusterHostId.first(),
24452445
clusterHostId.second(), vm, Collections.emptySet());
2446-
if (pool == null) {
2447-
throw new CloudRuntimeException(String.format("Failed to find a primary storage for volume in state: %s", volumeToAttach.getState()));
2448-
}
2449-
return pool;
24502446
}
24512447

24522448
protected VolumeInfo createVolumeOnPrimaryForAttachIfNeeded(final VolumeInfo volumeToAttach, final UserVmVO vm, VolumeVO existingVolumeOfVm) {
@@ -2464,7 +2460,13 @@ protected VolumeInfo createVolumeOnPrimaryForAttachIfNeeded(final VolumeInfo vol
24642460
}
24652461
}
24662462
if (destPrimaryStorage == null) {
2467-
destPrimaryStorage = getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
2463+
destPrimaryStorage = getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
2464+
if (destPrimaryStorage == null) {
2465+
if (Volume.State.Allocated.equals(volumeToAttach.getState()) && State.Stopped.equals(vm.getState())) {
2466+
return newVolumeOnPrimaryStorage;
2467+
}
2468+
throw new CloudRuntimeException(String.format("Failed to find a primary storage for volume in state: %s", volumeToAttach.getState()));
2469+
}
24682470
}
24692471
try {
24702472
if (volumeOnSecondary && Storage.StoragePoolType.PowerFlex.equals(destPrimaryStorage.getPoolType())) {

server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1938,13 +1938,13 @@ public void testGetPoolForAllocatedOrUploadedVolumeForAttach_Success() {
19381938
when(volumeToAttach.getDiskOfferingId()).thenReturn(1L);
19391939
when(volumeOrchestrationService.findStoragePool(any(DiskProfile.class), eq(zone), eq(pod), eq(1L), eq(2L), eq(vm), eq(Collections.emptySet())))
19401940
.thenReturn(pool);
1941-
StoragePool result = volumeApiServiceImpl.getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
1941+
StoragePool result = volumeApiServiceImpl.getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
19421942
Assert.assertNotNull(result);
19431943
Assert.assertEquals(pool, result);
19441944
}
19451945

1946-
@Test(expected = CloudRuntimeException.class)
1947-
public void testGetPoolForAllocatedOrUploadedVolumeForAttach_NoPoolFound_ThrowsException() {
1946+
@Test
1947+
public void testGetPoolForAllocatedOrUploadedVolumeForAttach_NoSuitablePoolFound_ReturnsNull() {
19481948
VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
19491949
UserVmVO vm = Mockito.mock(UserVmVO.class);
19501950
DataCenterVO zone = mockZone();
@@ -1959,11 +1959,11 @@ public void testGetPoolForAllocatedOrUploadedVolumeForAttach_NoPoolFound_ThrowsE
19591959
when(volumeToAttach.getDiskOfferingId()).thenReturn(1L);
19601960
when(volumeOrchestrationService.findStoragePool(any(DiskProfile.class), eq(zone), eq(pod), eq(1L), eq(2L), eq(vm), eq(Collections.emptySet())))
19611961
.thenReturn(null);
1962-
volumeApiServiceImpl.getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
1962+
Assert.assertNull(volumeApiServiceImpl.getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm));
19631963
}
19641964

19651965
@Test
1966-
public void testGetPoolForAllocatedOrUploadedVolumeForAttach_NoCluster() {
1966+
public void testGetSuitablePoolForAllocatedOrUploadedVolumeForAttach_NoCluster() {
19671967
VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
19681968
UserVmVO vm = Mockito.mock(UserVmVO.class);
19691969
DataCenterVO zone = mockZone();
@@ -1977,7 +1977,7 @@ public void testGetPoolForAllocatedOrUploadedVolumeForAttach_NoCluster() {
19771977
when(volumeToAttach.getDiskOfferingId()).thenReturn(1L);
19781978
when(volumeOrchestrationService.findStoragePool(any(DiskProfile.class), eq(zone), eq(pod), eq(null), eq(2L), eq(vm), eq(Collections.emptySet())))
19791979
.thenReturn(pool);
1980-
StoragePool result = volumeApiServiceImpl.getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
1980+
StoragePool result = volumeApiServiceImpl.getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
19811981
Assert.assertNotNull(result);
19821982
Assert.assertEquals(pool, result);
19831983
}
@@ -2023,7 +2023,7 @@ public void testCreateVolumeOnPrimaryForAttachIfNeeded_UsesGetPoolForAttach() {
20232023
UserVmVO vm = Mockito.mock(UserVmVO.class);
20242024
StoragePool destPrimaryStorage = Mockito.mock(StoragePool.class);
20252025
Mockito.doReturn(destPrimaryStorage).when(volumeApiServiceImpl)
2026-
.getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
2026+
.getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
20272027
VolumeInfo newVolumeOnPrimaryStorage = Mockito.mock(VolumeInfo.class);
20282028
try {
20292029
Mockito.when(volumeOrchestrationService.createVolumeOnPrimaryStorage(
@@ -2034,7 +2034,7 @@ public void testCreateVolumeOnPrimaryForAttachIfNeeded_UsesGetPoolForAttach() {
20342034
}
20352035
VolumeInfo result = volumeApiServiceImpl.createVolumeOnPrimaryForAttachIfNeeded(volumeToAttach, vm, null);
20362036
Assert.assertSame(newVolumeOnPrimaryStorage, result);
2037-
verify(volumeApiServiceImpl).getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
2037+
verify(volumeApiServiceImpl).getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
20382038
}
20392039

20402040
@Test(expected = InvalidParameterValueException.class)
@@ -2045,7 +2045,7 @@ public void testCreateVolumeOnPrimaryForAttachIfNeeded_UnsupportedPoolType_Throw
20452045
StoragePool destPrimaryStorage = Mockito.mock(StoragePool.class);
20462046
when(destPrimaryStorage.getPoolType()).thenReturn(Storage.StoragePoolType.PowerFlex);
20472047
Mockito.doReturn(destPrimaryStorage).when(volumeApiServiceImpl)
2048-
.getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
2048+
.getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
20492049
volumeApiServiceImpl.createVolumeOnPrimaryForAttachIfNeeded(volumeToAttach, vm, null);
20502050
}
20512051

@@ -2057,7 +2057,7 @@ public void testCreateVolumeOnSecondaryForAttachIfNeeded_CreateVolumeFails_Throw
20572057
StoragePool destPrimaryStorage = Mockito.mock(StoragePool.class);
20582058
Mockito.when(destPrimaryStorage.getPoolType()).thenReturn(Storage.StoragePoolType.NetworkFilesystem);
20592059
Mockito.doReturn(destPrimaryStorage).when(volumeApiServiceImpl)
2060-
.getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
2060+
.getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
20612061
try {
20622062
Mockito.when(volumeOrchestrationService.createVolumeOnPrimaryStorage(vm, volumeToAttach, vm.getHypervisorType(), destPrimaryStorage))
20632063
.thenThrow(new NoTransitionException("Mocked exception"));
@@ -2069,4 +2069,35 @@ public void testCreateVolumeOnSecondaryForAttachIfNeeded_CreateVolumeFails_Throw
20692069
);
20702070
Assert.assertTrue(exception.getMessage().contains("Failed to create volume on primary storage"));
20712071
}
2072+
2073+
@Test
2074+
public void testCreateVolumeOnSecondaryForAttachIfNeeded_NoSuitablePool_ThrowsException() {
2075+
VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
2076+
Mockito.when(volumeToAttach.getState()).thenReturn(Volume.State.Uploaded);
2077+
UserVmVO vm = Mockito.mock(UserVmVO.class);
2078+
Mockito.doReturn(null).when(volumeApiServiceImpl)
2079+
.getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
2080+
CloudRuntimeException exception = Assert.assertThrows(CloudRuntimeException.class, () ->
2081+
volumeApiServiceImpl.createVolumeOnPrimaryForAttachIfNeeded(volumeToAttach, vm, null)
2082+
);
2083+
Assert.assertTrue(exception.getMessage().startsWith("Failed to find a primary storage for volume"));
2084+
}
2085+
2086+
@Test
2087+
public void testCreateVolumeOnSecondaryForAttachIfNeeded_NoSuitablePool_ReturnSameVolumeInfo() {
2088+
VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
2089+
Mockito.when(volumeToAttach.getState()).thenReturn(Volume.State.Allocated);
2090+
UserVmVO vm = Mockito.mock(UserVmVO.class);
2091+
Mockito.when(vm.getState()).thenReturn(State.Stopped);
2092+
Mockito.doReturn(null).when(volumeApiServiceImpl)
2093+
.getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
2094+
VolumeInfo result = volumeApiServiceImpl.createVolumeOnPrimaryForAttachIfNeeded(volumeToAttach, vm, null);
2095+
Assert.assertSame(volumeToAttach, result);
2096+
try {
2097+
Mockito.verify(volumeOrchestrationService, Mockito.never()).createVolumeOnPrimaryStorage(Mockito.any(),
2098+
Mockito.any(), Mockito.any(), Mockito.any());
2099+
} catch (NoTransitionException e) {
2100+
Assert.fail();
2101+
}
2102+
}
20722103
}

0 commit comments

Comments
 (0)