mirror of https://github.com/apache/cloudstack.git
Fix full backup VM restore (#5680)
Co-authored-by: SadiJr <sadi@scclouds.com.br>
This commit is contained in:
parent
28385be609
commit
9363f6490b
|
|
@ -42,6 +42,7 @@ import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
|
|||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
|
|
@ -500,7 +501,9 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
*/
|
||||
private void checkBackingInfo(VirtualDeviceBackingInfo backingInfo) {
|
||||
if (!(backingInfo instanceof VirtualDiskFlatVer2BackingInfo)) {
|
||||
throw new CloudRuntimeException("Unsopported backing, expected " + VirtualDiskFlatVer2BackingInfo.class.getSimpleName());
|
||||
String errorMessage = String.format("Unsupported backing info. Expected: [%s], but received: [%s].", VirtualDiskFlatVer2BackingInfo.class.getSimpleName(), backingInfo.getClass().getSimpleName());
|
||||
s_logger.error(errorMessage);
|
||||
throw new CloudRuntimeException(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -642,8 +645,11 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
* If VM exists: update VM
|
||||
*/
|
||||
private VMInstanceVO getVM(String vmInternalName, long templateId, long guestOsId, long serviceOfferingId, long zoneId, long accountId, long userId, long domainId) {
|
||||
s_logger.debug(String.format("Trying to get VM with specs: [vmInternalName: %s, templateId: %s, guestOsId: %s, serviceOfferingId: %s].", vmInternalName,
|
||||
templateId, guestOsId, serviceOfferingId));
|
||||
VMInstanceVO vm = _vmDao.findVMByInstanceNameIncludingRemoved(vmInternalName);
|
||||
if (vm != null) {
|
||||
s_logger.debug(String.format("Found an existing VM [id: %s, removed: %s] with internalName: [%s].", vm.getUuid(), vm.getRemoved() != null ? "yes" : "no", vmInternalName));
|
||||
vm.setState(VirtualMachine.State.Stopped);
|
||||
vm.setPowerState(VirtualMachine.PowerState.PowerOff);
|
||||
_vmDao.update(vm.getId(), vm);
|
||||
|
|
@ -655,6 +661,9 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
return _vmDao.findById(vm.getId());
|
||||
} else {
|
||||
long id = userVmDao.getNextInSequence(Long.class, "id");
|
||||
s_logger.debug(String.format("Can't find an existing VM with internalName: [%s]. Creating a new VM with: [id: %s, name: %s, templateId: %s, guestOsId: %s, serviceOfferingId: %s].",
|
||||
vmInternalName, id, vmInternalName, templateId, guestOsId, serviceOfferingId));
|
||||
|
||||
UserVmVO vmInstanceVO = new UserVmVO(id, vmInternalName, vmInternalName, templateId, HypervisorType.VMware, guestOsId, false, false, domainId, accountId, userId,
|
||||
serviceOfferingId, null, vmInternalName, null);
|
||||
vmInstanceVO.setDataCenterId(zoneId);
|
||||
|
|
@ -743,15 +752,19 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
long templateId = vmInstanceVO.getTemplateId();
|
||||
long instanceId = vmInstanceVO.getId();
|
||||
|
||||
String operation = "";
|
||||
for (VirtualDisk disk : virtualDisks) {
|
||||
Long poolId = getPoolId(disk);
|
||||
Volume volume = null;
|
||||
if (disksMapping.containsKey(disk) && disksMapping.get(disk) != null) {
|
||||
volume = updateVolume(disk, disksMapping, vmToImport, poolId, vmInstanceVO);
|
||||
operation = "updated";
|
||||
} else {
|
||||
volume = createVolume(disk, vmToImport, domainId, zoneId, accountId, instanceId, poolId, templateId, backup, true);
|
||||
operation = "created";
|
||||
}
|
||||
s_logger.debug("VM backup restored (updated/created) volume id:" + volume.getId() + " for VM id:" + instanceId);
|
||||
s_logger.debug(String.format("VM [id: %s, instanceName: %s] backup restore operation %s volume [id: %s].", instanceId, vmInstanceVO.getInstanceName(),
|
||||
operation, volume.getUuid()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -968,7 +981,10 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
return info.getDatastore();
|
||||
}
|
||||
|
||||
@Override public VirtualMachine importVirtualMachineFromBackup(long zoneId, long domainId, long accountId, long userId, String vmInternalName, Backup backup) throws Exception {
|
||||
@Override
|
||||
public VirtualMachine importVirtualMachineFromBackup(long zoneId, long domainId, long accountId, long userId, String vmInternalName, Backup backup) throws Exception {
|
||||
s_logger.debug(String.format("Trying to import VM [vmInternalName: %s] from Backup [%s].", vmInternalName,
|
||||
ReflectionToStringBuilderUtils.reflectOnlySelectedFields(backup, "id", "uuid", "vmId", "externalId", "backupType")));
|
||||
DatacenterMO dcMo = getDatacenterMO(zoneId);
|
||||
VirtualMachineMO vmToImport = dcMo.findVm(vmInternalName);
|
||||
if (vmToImport == null) {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import org.apache.cloudstack.backup.Backup;
|
|||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
|
@ -199,13 +200,13 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
|
|||
protected VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile vmProfile) {
|
||||
ServiceOffering offering = _serviceOfferingDao.findById(vmProfile.getId(), vmProfile.getServiceOfferingId());
|
||||
VirtualMachine vm = vmProfile.getVirtualMachine();
|
||||
HostVO host = hostDao.findById(vm.getHostId());
|
||||
Long clusterId = findClusterOfVm(vm);
|
||||
boolean divideMemoryByOverprovisioning = true;
|
||||
boolean divideCpuByOverprovisioning = true;
|
||||
|
||||
if (host != null) {
|
||||
divideMemoryByOverprovisioning = VmMinMemoryEqualsMemoryDividedByMemOverprovisioningFactor.valueIn(host.getClusterId());
|
||||
divideCpuByOverprovisioning = VmMinCpuSpeedEqualsCpuSpeedDividedByCpuOverprovisioningFactor.valueIn(host.getClusterId());
|
||||
if (clusterId != null) {
|
||||
divideMemoryByOverprovisioning = VmMinMemoryEqualsMemoryDividedByMemOverprovisioningFactor.valueIn(clusterId);
|
||||
divideCpuByOverprovisioning = VmMinCpuSpeedEqualsCpuSpeedDividedByCpuOverprovisioningFactor.valueIn(clusterId);
|
||||
}
|
||||
|
||||
Long minMemory = (long)(offering.getRamSize() / (divideMemoryByOverprovisioning ? vmProfile.getMemoryOvercommitRatio() : 1));
|
||||
|
|
@ -280,6 +281,22 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
|
|||
return to;
|
||||
}
|
||||
|
||||
protected Long findClusterOfVm(VirtualMachine vm) {
|
||||
HostVO host = hostDao.findById(vm.getHostId());
|
||||
if (host != null) {
|
||||
return host.getClusterId();
|
||||
}
|
||||
|
||||
s_logger.debug(String.format("VM [%s] does not have a host id. Trying the last host.", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(vm, "instanceName", "id", "uuid")));
|
||||
host = hostDao.findById(vm.getLastHostId());
|
||||
if (host != null) {
|
||||
return host.getClusterId();
|
||||
}
|
||||
|
||||
s_logger.debug(String.format("VM [%s] does not have a last host id.", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(vm, "instanceName", "id", "uuid")));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* The basic implementation assumes that the initial "host" defined to execute the command is the host that is in fact going to execute it.
|
||||
|
|
|
|||
|
|
@ -533,7 +533,8 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
|
|||
try {
|
||||
vm = guru.importVirtualMachineFromBackup(zoneId, domainId, accountId, userId, vmInternalName, backup);
|
||||
} catch (final Exception e) {
|
||||
LOG.error("Failed to import VM from backup restoration", e);
|
||||
LOG.error(String.format("Failed to import VM [vmInternalName: %s] from backup restoration [%s] with hypervisor [type: %s] due to: [%s].", vmInternalName,
|
||||
ReflectionToStringBuilderUtils.reflectOnlySelectedFields(backup, "id", "uuid", "vmId", "externalId", "backupType"), hypervisorType, e.getMessage()), e);
|
||||
throw new CloudRuntimeException("Error during vm backup restoration and import: " + e.getMessage());
|
||||
}
|
||||
if (vm == null) {
|
||||
|
|
|
|||
|
|
@ -452,4 +452,42 @@ public class KVMGuruTest {
|
|||
Assert.assertEquals(platformEmulator, virtualMachineTo.getPlatformEmulator());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetClusterIdFromVMHost() {
|
||||
Mockito.when(vm.getHostId()).thenReturn(123l);
|
||||
HostVO vo = new HostVO("");
|
||||
Long expected = 5l;
|
||||
vo.setClusterId(expected);
|
||||
|
||||
Mockito.when(hostDao.findById(123l)).thenReturn(vo);
|
||||
|
||||
Long clusterId = guru.findClusterOfVm(vm);
|
||||
|
||||
Assert.assertEquals(expected, clusterId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetClusterIdFromLastVMHost() {
|
||||
Mockito.when(vm.getHostId()).thenReturn(null);
|
||||
Mockito.when(vm.getLastHostId()).thenReturn(321l);
|
||||
HostVO vo = new HostVO("");
|
||||
Long expected = 7l;
|
||||
vo.setClusterId(expected);
|
||||
|
||||
Mockito.when(hostDao.findById(321l)).thenReturn(vo);
|
||||
|
||||
Long clusterId = guru.findClusterOfVm(vm);
|
||||
|
||||
Assert.assertEquals(expected, clusterId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNullWhenVMThereIsNoInformationOfUsedHosts() {
|
||||
Mockito.when(vm.getHostId()).thenReturn(null);
|
||||
Mockito.when(vm.getLastHostId()).thenReturn(null);
|
||||
|
||||
Long clusterId = guru.findClusterOfVm(vm);
|
||||
|
||||
Assert.assertNull(clusterId);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue