Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
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;
Expand Down Expand Up @@ -500,7 +501,9 @@ private boolean isRootDisk(VirtualDisk disk, Map<VirtualDisk, VolumeVO> disksMap
*/
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);
}
}

Expand Down Expand Up @@ -642,8 +645,11 @@ private Long getImportingVMTemplate(List<VirtualDisk> virtualDisks, DatacenterMO
* 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);
Expand All @@ -655,6 +661,9 @@ private VMInstanceVO getVM(String vmInternalName, long templateId, long guestOsI
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);
Expand Down Expand Up @@ -743,15 +752,19 @@ private void syncVMVolumes(VMInstanceVO vmInstanceVO, List<VirtualDisk> virtualD
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()));
}
}

Expand Down Expand Up @@ -968,7 +981,10 @@ private ManagedObjectReference getDestStoreMor(VirtualMachineMO vmMo) throws Exc
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) {
Expand Down
25 changes: 21 additions & 4 deletions server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
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;
Expand Down Expand Up @@ -199,13 +200,13 @@ protected void addServiceOfferingExtraConfiguration(ServiceOffering offering, Vi
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));
Expand Down Expand Up @@ -280,6 +281,22 @@ protected VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile vmProfile) {
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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,8 @@ public boolean importRestoredVM(long zoneId, long domainId, long accountId, long
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) {
Expand Down
38 changes: 38 additions & 0 deletions server/src/test/java/com/cloud/hypervisor/KVMGuruTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -452,4 +452,42 @@ public void validateConfigureVmOsDescriptionHostNullAndGuestOsMappingNullAndGues
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);
}
}