Skip to content

Commit

Permalink
Improve logs in primary storage removal process (#8649)
Browse files Browse the repository at this point in the history
* Improve delete storage pool logs

* Address Daniel's reviews

Co-authored-by: Daniel Augusto Veronezi Salvador <38945620+GutoVeronezi@users.noreply.github.com>

* Address Daniel's review

---------

Co-authored-by: Henrique Sato <henrique.sato@scclouds.com.br>
Co-authored-by: Daniel Augusto Veronezi Salvador <38945620+GutoVeronezi@users.noreply.github.com>
  • Loading branch information
3 people authored Aug 28, 2024
1 parent e6cb7f2 commit 2a1db67
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 6 deletions.
30 changes: 24 additions & 6 deletions server/src/main/java/com/cloud/storage/StorageManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -1411,7 +1411,8 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
}
});
} else {
throw new CloudRuntimeException("Cannot delete pool " + sPool.getName() + " as there are associated " + "non-destroyed vols for this pool");
logger.debug("Cannot delete storage pool {} as the following non-destroyed volumes are on it: {}.", sPool::getName, () -> getStoragePoolNonDestroyedVolumesLog(sPool.getId()));
throw new CloudRuntimeException(String.format("Cannot delete pool %s as there are non-destroyed volumes associated to this pool.", sPool.getName()));
}
}
return deleteDataStoreInternal(sPool, forced);
Expand Down Expand Up @@ -1472,17 +1473,16 @@ private boolean deleteDataStoreInternal(StoragePoolVO sPool, boolean forced) {
if (vlms.first() > 0) {
Pair<Long, Long> nonDstrdVlms = volumeDao.getNonDestroyedCountAndTotalByPool(sPool.getId());
if (nonDstrdVlms.first() > 0) {
throw new CloudRuntimeException("Cannot delete pool " + sPool.getName() + " as there are associated " + "non-destroyed vols for this pool");
logger.debug("Cannot delete storage pool {} as the following non-destroyed volumes are on it: {}.", sPool::getName, () -> getStoragePoolNonDestroyedVolumesLog(sPool.getId()));
throw new CloudRuntimeException(String.format("Cannot delete pool %s as there are non-destroyed volumes associated to this pool.", sPool.getName()));
}
// force expunge non-destroyed volumes
List<VolumeVO> vols = volumeDao.listVolumesToBeDestroyed();
for (VolumeVO vol : vols) {
AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volFactory.getVolume(vol.getId()));
try {
future.get();
} catch (InterruptedException e) {
logger.debug("expunge volume failed:" + vol.getId(), e);
} catch (ExecutionException e) {
} catch (InterruptedException | ExecutionException e) {
logger.debug("expunge volume failed:" + vol.getId(), e);
}
}
Expand All @@ -1491,7 +1491,8 @@ private boolean deleteDataStoreInternal(StoragePoolVO sPool, boolean forced) {
// Check if the pool has associated volumes in the volumes table
// If it does , then you cannot delete the pool
if (vlms.first() > 0) {
throw new CloudRuntimeException("Cannot delete pool " + sPool.getName() + " as there are associated volumes for this pool");
logger.debug("Cannot delete storage pool {} as the following non-destroyed volumes are on it: {}.", sPool::getName, () -> getStoragePoolNonDestroyedVolumesLog(sPool.getId()));
throw new CloudRuntimeException(String.format("Cannot delete pool %s as there are non-destroyed volumes associated to this pool.", sPool.getName()));
}
}

Expand All @@ -1514,6 +1515,23 @@ private boolean deleteDataStoreInternal(StoragePoolVO sPool, boolean forced) {
return lifeCycle.deleteDataStore(store);
}

protected String getStoragePoolNonDestroyedVolumesLog(long storagePoolId) {
StringBuilder sb = new StringBuilder();
List<VolumeVO> nonDestroyedVols = volumeDao.findByPoolId(storagePoolId, null).stream().filter(vol -> vol.getState() != Volume.State.Destroy).collect(Collectors.toList());
VMInstanceVO volInstance;
List<String> logMessageInfo = new ArrayList<>();

sb.append("[");
for (VolumeVO vol : nonDestroyedVols) {
volInstance = _vmInstanceDao.findById(vol.getInstanceId());
logMessageInfo.add(String.format("Volume [%s] (attached to VM [%s])", vol.getUuid(), volInstance.getUuid()));
}
sb.append(String.join(", ", logMessageInfo));
sb.append("]");

return sb.toString();
}

@Override
public boolean connectHostToSharedPool(long hostId, long poolId) throws StorageUnavailableException, StorageConflictException {
StoragePool pool = (StoragePool)_dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary);
Expand Down
30 changes: 30 additions & 0 deletions server/src/test/java/com/cloud/storage/StorageManagerImplTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,18 @@ public class StorageManagerImplTest {
@InjectMocks
private StorageManagerImpl storageManagerImpl;

@Mock
private StoragePoolVO storagePoolVOMock;

@Mock
private VolumeVO volume1VOMock;

@Mock
private VolumeVO volume2VOMock;

@Mock
private VMInstanceVO vmInstanceVOMock;

@Test
public void createLocalStoragePoolName() {
String hostMockName = "host1";
Expand Down Expand Up @@ -515,6 +527,24 @@ public void testEnableDefaultDatastoreDownloadRedirectionForExistingInstallation
.update(StorageManager.DataStoreDownloadFollowRedirects.key(),StorageManager.DataStoreDownloadFollowRedirects.defaultValue());
}

@Test
public void getStoragePoolNonDestroyedVolumesLogTestNonDestroyedVolumesReturnLog() {
Mockito.doReturn(1L).when(storagePoolVOMock).getId();
Mockito.doReturn(1L).when(volume1VOMock).getInstanceId();
Mockito.doReturn("786633d1-a942-4374-9d56-322dd4b0d202").when(volume1VOMock).getUuid();
Mockito.doReturn(1L).when(volume2VOMock).getInstanceId();
Mockito.doReturn("ffb46333-e983-4c21-b5f0-51c5877a3805").when(volume2VOMock).getUuid();
Mockito.doReturn("58760044-928f-4c4e-9fef-d0e48423595e").when(vmInstanceVOMock).getUuid();

Mockito.when(_volumeDao.findByPoolId(storagePoolVOMock.getId(), null)).thenReturn(List.of(volume1VOMock, volume2VOMock));
Mockito.doReturn(vmInstanceVOMock).when(vmInstanceDao).findById(Mockito.anyLong());

String log = storageManagerImpl.getStoragePoolNonDestroyedVolumesLog(storagePoolVOMock.getId());
String expected = String.format("[Volume [%s] (attached to VM [%s]), Volume [%s] (attached to VM [%s])]", volume1VOMock.getUuid(), vmInstanceVOMock.getUuid(), volume2VOMock.getUuid(), vmInstanceVOMock.getUuid());

Assert.assertEquals(expected, log);
}

private ChangeStoragePoolScopeCmd mockChangeStoragePooolScopeCmd(String newScope) {
ChangeStoragePoolScopeCmd cmd = new ChangeStoragePoolScopeCmd();
ReflectionTestUtils.setField(cmd, "id", 1L);
Expand Down

0 comments on commit 2a1db67

Please sign in to comment.