mirror of https://github.com/apache/cloudstack.git
[VMware to KVM migration] Check source VM against the selected offering (#11908)
* [VMware to KVM migration] Check source VM against the selected offering * Fix build
This commit is contained in:
parent
c2c1e11580
commit
bfc4f60e1d
|
|
@ -61,6 +61,7 @@ import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
|
|||
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.cloud.agent.api.BackupSnapshotCommand;
|
||||
|
|
@ -1393,6 +1394,9 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
String datacenter = params.get(VmDetailConstants.VMWARE_DATACENTER_NAME);
|
||||
String username = params.get(VmDetailConstants.VMWARE_VCENTER_USERNAME);
|
||||
String password = params.get(VmDetailConstants.VMWARE_VCENTER_PASSWORD);
|
||||
Integer requestedCpuNumber = params.containsKey(VmDetailConstants.CPU_NUMBER) ? Integer.parseInt(params.get(VmDetailConstants.CPU_NUMBER)) : null;
|
||||
Integer requestedCpuSpeed = params.containsKey(VmDetailConstants.CPU_SPEED) ? Integer.parseInt(params.get(VmDetailConstants.CPU_SPEED)) : null;
|
||||
Integer requestedMemory = params.containsKey(VmDetailConstants.MEMORY) ? Integer.parseInt(params.get(VmDetailConstants.MEMORY)) : null;
|
||||
|
||||
try {
|
||||
VmwareContext context = connectToVcenter(vcenter, username, password);
|
||||
|
|
@ -1428,6 +1432,8 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
}
|
||||
}
|
||||
|
||||
checkSourceVmResourcesAgainstSelectedOfferingResources(vmMo, requestedCpuNumber, requestedCpuSpeed, requestedMemory);
|
||||
|
||||
logger.debug(String.format("Cloning VM %s at VMware host %s on vCenter %s", vmName, hostIp, vcenter));
|
||||
VirtualMachineMO clonedVM = createCloneFromSourceVM(vmName, vmMo, dataCenterMO);
|
||||
logger.debug(String.format("VM %s cloned successfully, to VM %s", vmName, clonedVM.getName()));
|
||||
|
|
@ -1444,6 +1450,29 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
}
|
||||
}
|
||||
|
||||
protected void checkSourceVmResourcesAgainstSelectedOfferingResources(VirtualMachineMO vmMo, Integer requestedCpuNumber, Integer requestedCpuSpeed, Integer requestedMemory) throws Exception {
|
||||
if (ObjectUtils.allNull(requestedCpuNumber, requestedCpuSpeed, requestedMemory)) {
|
||||
return;
|
||||
}
|
||||
VirtualMachineConfigSummary configSummary = vmMo.getConfigSummary();
|
||||
if (configSummary != null) {
|
||||
compareSourceVmResourceAgainstRequested(configSummary.getNumCpu(), requestedCpuNumber, "CPU number");
|
||||
compareSourceVmResourceAgainstRequested(configSummary.getCpuReservation(), requestedCpuSpeed, "CPU speed");
|
||||
compareSourceVmResourceAgainstRequested(configSummary.getMemorySizeMB(), requestedMemory, "Memory");
|
||||
}
|
||||
}
|
||||
|
||||
protected void compareSourceVmResourceAgainstRequested(Integer actualResource, Integer requestedResource, String resourceName) throws Exception {
|
||||
if (ObjectUtils.anyNull(actualResource, requestedResource)) {
|
||||
return;
|
||||
}
|
||||
if (requestedResource < actualResource) {
|
||||
String err = String.format("The requested %s (%d) is less than the source VM %s (%d)", resourceName, requestedResource, resourceName, actualResource);
|
||||
logger.error(err);
|
||||
throw new CloudRuntimeException(err);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isWindowsVm(VirtualMachineMO vmMo) throws Exception {
|
||||
UnmanagedInstanceTO sourceInstance = VmwareHelper.getUnmanagedInstance(vmMo.getRunningHost(), vmMo);
|
||||
return sourceInstance.getOperatingSystem().toLowerCase().contains("windows");
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.vmware.vim25.VirtualMachineConfigSummary;
|
||||
import org.apache.cloudstack.storage.NfsMountManager;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
|
|
@ -626,4 +627,24 @@ public class VMwareGuruTest {
|
|||
boolean result = vMwareGuru.removeVMTemplateOutOfBand(dataStore, templateDir);
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testCheckSourceVmResourcesAgainstSelectedOfferingResourcesInsufficientMemory() throws Exception {
|
||||
VirtualMachineMO virtualMachineMO = Mockito.mock(VirtualMachineMO.class);
|
||||
VirtualMachineConfigSummary configSummary = Mockito.mock(VirtualMachineConfigSummary.class);
|
||||
Mockito.when(virtualMachineMO.getConfigSummary()).thenReturn(configSummary);
|
||||
Mockito.when(configSummary.getNumCpu()).thenReturn(1);
|
||||
Mockito.when(configSummary.getMemorySizeMB()).thenReturn(2048);
|
||||
vMwareGuru.checkSourceVmResourcesAgainstSelectedOfferingResources(virtualMachineMO, 1, 500, 1024);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckSourceVmResourcesAgainstSelectedOfferingResourcesGreaterOffering() throws Exception {
|
||||
VirtualMachineMO virtualMachineMO = Mockito.mock(VirtualMachineMO.class);
|
||||
VirtualMachineConfigSummary configSummary = Mockito.mock(VirtualMachineConfigSummary.class);
|
||||
Mockito.when(virtualMachineMO.getConfigSummary()).thenReturn(configSummary);
|
||||
Mockito.when(configSummary.getNumCpu()).thenReturn(1);
|
||||
Mockito.when(configSummary.getMemorySizeMB()).thenReturn(1024);
|
||||
vMwareGuru.checkSourceVmResourcesAgainstSelectedOfferingResources(virtualMachineMO, 2, 1500, 2048);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1644,16 +1644,45 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
}
|
||||
|
||||
private Pair<UnmanagedInstanceTO, Boolean> getSourceVmwareUnmanagedInstance(String vcenter, String datacenterName, String username,
|
||||
String password, String clusterName, String sourceHostName,
|
||||
String sourceVM) {
|
||||
String password, String clusterName, String sourceHostName,
|
||||
String sourceVM, ServiceOfferingVO serviceOffering) {
|
||||
HypervisorGuru vmwareGuru = hypervisorGuruManager.getGuru(Hypervisor.HypervisorType.VMware);
|
||||
|
||||
Map<String, String> params = createParamsForTemplateFromVmwareVmMigration(vcenter, datacenterName,
|
||||
username, password, clusterName, sourceHostName, sourceVM);
|
||||
addServiceOfferingDetailsToParams(params, serviceOffering);
|
||||
|
||||
return vmwareGuru.getHypervisorVMOutOfBandAndCloneIfRequired(sourceHostName, sourceVM, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the minimum resources to check on the hypervisor source VM before converting the instance against the selected offering resources
|
||||
* @param params sets the minimum CPU number, CPU speed and memory to be checked against the source VM
|
||||
* @param serviceOffering service offering for the converted VM
|
||||
*/
|
||||
protected void addServiceOfferingDetailsToParams(Map<String, String> params, ServiceOfferingVO serviceOffering) {
|
||||
if (serviceOffering != null) {
|
||||
serviceOfferingDao.loadDetails(serviceOffering);
|
||||
Map<String, String> serviceOfferingDetails = serviceOffering.getDetails();
|
||||
|
||||
if (serviceOffering.getCpu() != null) {
|
||||
params.put(VmDetailConstants.CPU_NUMBER, String.valueOf(serviceOffering.getCpu()));
|
||||
} else if (MapUtils.isNotEmpty(serviceOfferingDetails) && serviceOfferingDetails.containsKey(ApiConstants.MIN_CPU_NUMBER)) {
|
||||
params.put(VmDetailConstants.CPU_NUMBER, serviceOfferingDetails.get(ApiConstants.MIN_CPU_NUMBER));
|
||||
}
|
||||
|
||||
if (serviceOffering.getSpeed() != null) {
|
||||
params.put(VmDetailConstants.CPU_SPEED, String.valueOf(serviceOffering.getSpeed()));
|
||||
}
|
||||
|
||||
if (serviceOffering.getRamSize() != null) {
|
||||
params.put(VmDetailConstants.MEMORY, String.valueOf(serviceOffering.getRamSize()));
|
||||
} else if (MapUtils.isNotEmpty(serviceOfferingDetails) && serviceOfferingDetails.containsKey(ApiConstants.MIN_MEMORY)) {
|
||||
params.put(VmDetailConstants.MEMORY, serviceOfferingDetails.get(ApiConstants.MIN_MEMORY));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String createOvfTemplateOfSourceVmwareUnmanagedInstance(String vcenter, String datacenterName, String username,
|
||||
String password, String clusterName, String sourceHostName,
|
||||
String sourceVMwareInstanceName, DataStoreTO convertLocation, int threadsCountToExportOvf) {
|
||||
|
|
@ -1734,7 +1763,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
// sourceVMwareInstance could be a cloned instance from sourceVMName, of the sourceVMName itself if its powered off.
|
||||
// isClonedInstance indicates if the VM is a clone of sourceVMName
|
||||
|
||||
Pair<UnmanagedInstanceTO, Boolean> sourceInstanceDetails = getSourceVmwareUnmanagedInstance(vcenter, datacenterName, username, password, clusterName, sourceHostName, sourceVMName);
|
||||
Pair<UnmanagedInstanceTO, Boolean> sourceInstanceDetails = getSourceVmwareUnmanagedInstance(vcenter, datacenterName, username, password, clusterName, sourceHostName, sourceVMName, serviceOffering);
|
||||
sourceVMwareInstance = sourceInstanceDetails.first();
|
||||
isClonedInstance = sourceInstanceDetails.second();
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import java.util.UUID;
|
|||
|
||||
import com.cloud.offering.DiskOffering;
|
||||
import com.cloud.vm.ImportVMTaskVO;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ResponseGenerator;
|
||||
import org.apache.cloudstack.api.ResponseObject;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
|
|
@ -1309,4 +1310,45 @@ public class UnmanagedVMsManagerImplTest {
|
|||
Mockito.when(configKeyMockParamsAllowedList.value()).thenReturn("network,x");
|
||||
unmanagedVMsManager.checkExtraParamsAllowed("--mac 00:0c:29:e6:3d:9d:ip:192.168.0.89,192.168.0.1,24,192.168.0.254 -x");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddServiceOfferingDetailsToParamsFixedOffering() {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
ServiceOfferingVO serviceOfferingVO = mock(ServiceOfferingVO.class);
|
||||
Mockito.when(serviceOfferingVO.getCpu()).thenReturn(2);
|
||||
Mockito.when(serviceOfferingVO.getRamSize()).thenReturn(2048);
|
||||
unmanagedVMsManager.addServiceOfferingDetailsToParams(params, serviceOfferingVO);
|
||||
Assert.assertEquals("2", params.get(VmDetailConstants.CPU_NUMBER));
|
||||
Assert.assertEquals("2048", params.get(VmDetailConstants.MEMORY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddServiceOfferingDetailsToParamsCustomConstrainedOffering() {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
ServiceOfferingVO serviceOfferingVO = mock(ServiceOfferingVO.class);
|
||||
Map<String, String> details = new HashMap<>();
|
||||
details.put(ApiConstants.MIN_CPU_NUMBER, "1");
|
||||
details.put(ApiConstants.MIN_MEMORY, "1024");
|
||||
Mockito.when(serviceOfferingVO.getDetails()).thenReturn(details);
|
||||
Mockito.when(serviceOfferingVO.getCpu()).thenReturn(null);
|
||||
Mockito.when(serviceOfferingVO.getSpeed()).thenReturn(1500);
|
||||
Mockito.when(serviceOfferingVO.getRamSize()).thenReturn(null);
|
||||
unmanagedVMsManager.addServiceOfferingDetailsToParams(params, serviceOfferingVO);
|
||||
Assert.assertEquals("1", params.get(VmDetailConstants.CPU_NUMBER));
|
||||
Assert.assertEquals("1500", params.get(VmDetailConstants.CPU_SPEED));
|
||||
Assert.assertEquals("1024", params.get(VmDetailConstants.MEMORY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddServiceOfferingDetailsToParamsCustomUnconstrainedOffering() {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
ServiceOfferingVO serviceOfferingVO = mock(ServiceOfferingVO.class);
|
||||
Mockito.when(serviceOfferingVO.getCpu()).thenReturn(null);
|
||||
Mockito.when(serviceOfferingVO.getSpeed()).thenReturn(null);
|
||||
Mockito.when(serviceOfferingVO.getRamSize()).thenReturn(null);
|
||||
unmanagedVMsManager.addServiceOfferingDetailsToParams(params, serviceOfferingVO);
|
||||
Assert.assertFalse(params.containsKey(VmDetailConstants.CPU_NUMBER));
|
||||
Assert.assertFalse(params.containsKey(VmDetailConstants.CPU_SPEED));
|
||||
Assert.assertFalse(params.containsKey(VmDetailConstants.MEMORY));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue