Find VBRViDatastore/VBRServer by name (#6582)

Co-authored-by: Rafael Weingärtner <rafaelweingartner@gmail.com>
This commit is contained in:
SadiJr 2022-08-02 04:07:03 -03:00 committed by GitHub
parent 9bc3b7b98c
commit 6ba0ef2f50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 120 additions and 17 deletions

View File

@ -66,6 +66,7 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
@ -634,9 +635,9 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
}
accountManager.checkAccess(CallContext.current().getCallingAccount(), null, true, vmFromBackup);
Pair<String, String> restoreInfo = getRestoreVolumeHostAndDatastore(vm);
String hostIp = restoreInfo.first();
String datastoreUuid = restoreInfo.second();
Pair<HostVO, StoragePoolVO> restoreInfo = getRestoreVolumeHostAndDatastore(vm);
HostVO host = restoreInfo.first();
StoragePoolVO datastore = restoreInfo.second();
LOG.debug("Asking provider to restore volume " + backedUpVolumeUuid + " from backup " + backupId +
" (with external ID " + backup.getExternalId() + ") and attach it to VM: " + vm.getUuid());
@ -647,17 +648,47 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
}
BackupProvider backupProvider = getBackupProvider(offering.getProvider());
Pair<Boolean, String> result = backupProvider.restoreBackedUpVolume(backup, backedUpVolumeUuid, hostIp, datastoreUuid);
if (!result.first()) {
throw new CloudRuntimeException("Error restoring volume " + backedUpVolumeUuid);
LOG.debug(String.format("Trying to restore volume using host private IP address: [%s].", host.getPrivateIpAddress()));
String[] hostPossibleValues = {host.getPrivateIpAddress(), host.getName()};
String[] datastoresPossibleValues = {datastore.getUuid(), datastore.getName()};
Pair<Boolean, String> result = restoreBackedUpVolume(backedUpVolumeUuid, backup, backupProvider, hostPossibleValues, datastoresPossibleValues);
if (BooleanUtils.isFalse(result.first())) {
throw new CloudRuntimeException(String.format("Error restoring volume [%s] of VM [%s] to host [%s] using backup provider [%s] due to: [%s].",
backedUpVolumeUuid, vm.getUuid(), host.getUuid(), backupProvider.getName(), result.second()));
}
if (!attachVolumeToVM(vm.getDataCenterId(), result.second(), vmFromBackup.getBackupVolumeList(),
backedUpVolumeUuid, vm, datastoreUuid, backup)) {
throw new CloudRuntimeException("Error attaching volume " + backedUpVolumeUuid + " to VM " + vm.getUuid());
backedUpVolumeUuid, vm, datastore.getUuid(), backup)) {
throw new CloudRuntimeException(String.format("Error attaching volume [%s] to VM [%s]." + backedUpVolumeUuid, vm.getUuid()));
}
return true;
}
protected Pair<Boolean, String> restoreBackedUpVolume(final String backedUpVolumeUuid, final BackupVO backup, BackupProvider backupProvider, String[] hostPossibleValues,
String[] datastoresPossibleValues) {
Pair<Boolean, String> result = new Pair<>(false, "");
for (String hostData : hostPossibleValues) {
for (String datastoreData : datastoresPossibleValues) {
LOG.debug(String.format("Trying to restore volume [UUID: %s], using host [%s] and datastore [%s].",
backedUpVolumeUuid, hostData, datastoreData));
try {
result = backupProvider.restoreBackedUpVolume(backup, backedUpVolumeUuid, hostData, datastoreData);
if (BooleanUtils.isTrue(result.first())) {
return result;
}
} catch (Exception e) {
LOG.debug(String.format("Failed to restore volume [UUID: %s], using host [%s] and datastore [%s] due to: [%s].",
backedUpVolumeUuid, hostData, datastoreData, e.getMessage()), e);
}
}
}
return result;
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_DELETE, eventDescription = "deleting VM backup", async = true)
public boolean deleteBackup(final Long backupId) {
@ -694,21 +725,20 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
/**
* Get the pair: hostIp, datastoreUuid in which to restore the volume, based on the VM to be attached information
*/
private Pair<String, String> getRestoreVolumeHostAndDatastore(VMInstanceVO vm) {
private Pair<HostVO, StoragePoolVO> getRestoreVolumeHostAndDatastore(VMInstanceVO vm) {
List<VolumeVO> rootVmVolume = volumeDao.findIncludingRemovedByInstanceAndType(vm.getId(), Volume.Type.ROOT);
Long poolId = rootVmVolume.get(0).getPoolId();
StoragePoolVO storagePoolVO = primaryDataStoreDao.findById(poolId);
String datastoreUuid = storagePoolVO.getUuid();
String hostIp = vm.getHostId() == null ?
getHostIp(storagePoolVO) :
hostDao.findById(vm.getHostId()).getPrivateIpAddress();
return new Pair<>(hostIp, datastoreUuid);
HostVO hostVO = vm.getHostId() == null ?
getFirstHostFromStoragePool(storagePoolVO) :
hostDao.findById(vm.getHostId());
return new Pair<>(hostVO, storagePoolVO);
}
/**
* Find a host IP from storage pool access
* Find a host from storage pool access
*/
private String getHostIp(StoragePoolVO storagePoolVO) {
private HostVO getFirstHostFromStoragePool(StoragePoolVO storagePoolVO) {
List<HostVO> hosts = null;
if (storagePoolVO.getScope().equals(ScopeType.CLUSTER)) {
hosts = hostDao.findByClusterId(storagePoolVO.getClusterId());
@ -716,9 +746,10 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
} else if (storagePoolVO.getScope().equals(ScopeType.ZONE)) {
hosts = hostDao.findByDataCenterId(storagePoolVO.getDataCenterId());
}
return hosts.get(0).getPrivateIpAddress();
return hosts.get(0);
}
/**
* Attach volume to VM
*/

View File

@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.backup;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
import org.apache.cloudstack.api.ServerApiException;
@ -30,6 +31,7 @@ import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.utils.Pair;
public class BackupManagerTest {
@Spy
@ -39,6 +41,12 @@ public class BackupManagerTest {
@Mock
BackupOfferingDao backupOfferingDao;
@Mock
BackupProvider backupProvider;
private String[] hostPossibleValues = {"127.0.0.1", "hostname"};
private String[] datastoresPossibleValues = {"e9804933-8609-4de3-bccc-6278072a496c", "datastore-name"};
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
@ -117,4 +125,68 @@ public class BackupManagerTest {
assertEquals("New description", updated.getDescription());
assertEquals(true, updated.isUserDrivenBackupAllowed());
}
@Test
public void restoreBackedUpVolumeTestHostIpAndDatastoreUuid() {
BackupVO backupVO = new BackupVO();
String volumeUuid = "5f4ed903-ac23-4f8a-b595-69c73c40593f";
Mockito.when(backupProvider.restoreBackedUpVolume(Mockito.any(), Mockito.eq(volumeUuid),
Mockito.eq("127.0.0.1"), Mockito.eq("e9804933-8609-4de3-bccc-6278072a496c"))).thenReturn(new Pair<Boolean, String>(Boolean.TRUE, "Success"));
Pair<Boolean,String> restoreBackedUpVolume = backupManager.restoreBackedUpVolume(volumeUuid, backupVO, backupProvider, hostPossibleValues, datastoresPossibleValues);
assertEquals(Boolean.TRUE, restoreBackedUpVolume.first());
assertEquals("Success", restoreBackedUpVolume.second());
Mockito.verify(backupProvider, times(1)).restoreBackedUpVolume(Mockito.any(), Mockito.anyString(),
Mockito.anyString(), Mockito.anyString());
}
@Test
public void restoreBackedUpVolumeTestHostIpAndDatastoreName() {
BackupVO backupVO = new BackupVO();
String volumeUuid = "5f4ed903-ac23-4f8a-b595-69c73c40593f";
Mockito.when(backupProvider.restoreBackedUpVolume(Mockito.any(), Mockito.eq(volumeUuid),
Mockito.eq("127.0.0.1"), Mockito.eq("datastore-name"))).thenReturn(new Pair<Boolean, String>(Boolean.TRUE, "Success2"));
Pair<Boolean,String> restoreBackedUpVolume = backupManager.restoreBackedUpVolume(volumeUuid, backupVO, backupProvider, hostPossibleValues, datastoresPossibleValues);
assertEquals(Boolean.TRUE, restoreBackedUpVolume.first());
assertEquals("Success2", restoreBackedUpVolume.second());
Mockito.verify(backupProvider, times(2)).restoreBackedUpVolume(Mockito.any(), Mockito.anyString(),
Mockito.anyString(), Mockito.anyString());
}
@Test
public void restoreBackedUpVolumeTestHostNameAndDatastoreUuid() {
BackupVO backupVO = new BackupVO();
String volumeUuid = "5f4ed903-ac23-4f8a-b595-69c73c40593f";
Mockito.when(backupProvider.restoreBackedUpVolume(Mockito.any(), Mockito.eq(volumeUuid),
Mockito.eq("hostname"), Mockito.eq("e9804933-8609-4de3-bccc-6278072a496c"))).thenReturn(new Pair<Boolean, String>(Boolean.TRUE, "Success3"));
Pair<Boolean,String> restoreBackedUpVolume = backupManager.restoreBackedUpVolume(volumeUuid, backupVO, backupProvider, hostPossibleValues, datastoresPossibleValues);
assertEquals(Boolean.TRUE, restoreBackedUpVolume.first());
assertEquals("Success3", restoreBackedUpVolume.second());
Mockito.verify(backupProvider, times(3)).restoreBackedUpVolume(Mockito.any(), Mockito.anyString(),
Mockito.anyString(), Mockito.anyString());
}
@Test
public void restoreBackedUpVolumeTestHostAndDatastoreName() {
BackupVO backupVO = new BackupVO();
String volumeUuid = "5f4ed903-ac23-4f8a-b595-69c73c40593f";
Mockito.when(backupProvider.restoreBackedUpVolume(Mockito.any(), Mockito.eq(volumeUuid),
Mockito.eq("hostname"), Mockito.eq("datastore-name"))).thenReturn(new Pair<Boolean, String>(Boolean.TRUE, "Success4"));
Pair<Boolean,String> restoreBackedUpVolume = backupManager.restoreBackedUpVolume(volumeUuid, backupVO, backupProvider, hostPossibleValues, datastoresPossibleValues);
assertEquals(Boolean.TRUE, restoreBackedUpVolume.first());
assertEquals("Success4", restoreBackedUpVolume.second());
Mockito.verify(backupProvider, times(4)).restoreBackedUpVolume(Mockito.any(), Mockito.anyString(),
Mockito.anyString(), Mockito.anyString());
}
}