Skip to content

Commit 35b20b2

Browse files
authored
vmware: Fix worker VM hardware version format (#4851)
This PR fixes a small bug when explicitly setting VM hardware versions lower than version 10. Vmware expects the hardware version in format: vmx-DD where DD is a two-digit representation of the virtual hardware version. For hardware version lower than 10, CloudStack was not using to digits for the hardware version number, which ended up on an error while creating worker VMs. (vmx-8 for example instead of vmx-08)
1 parent 9da8124 commit 35b20b2

4 files changed

Lines changed: 39 additions & 5 deletions

File tree

plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,8 @@ private Ternary<String, Long, Long> createTemplateFromVolume(VirtualMachineMO vm
647647
}
648648

649649
// 4 MB is the minimum requirement for VM memory in VMware
650-
vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()), null);
650+
String vmxFormattedVirtualHardwareVersion = VirtualMachineMO.getVmxFormattedVirtualHardwareVersion(vmMo.getVirtualHardwareVersion());
651+
vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()), vmxFormattedVirtualHardwareVersion);
651652
clonedVm = vmMo.getRunningHost().findVmOnHyperHost(workerVmName);
652653
if (clonedVm == null) {
653654
String msg = "Unable to create dummy VM to export volume. volume path: " + volumePath;
@@ -965,7 +966,8 @@ private void exportVolumeToSecondaryStorage(VirtualMachineMO vmMo, String volume
965966

966967
if (clonedWorkerVMNeeded) {
967968
// 4 MB is the minimum requirement for VM memory in VMware
968-
vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()), null);
969+
String vmxFormattedVirtualHardwareVersion = VirtualMachineMO.getVmxFormattedVirtualHardwareVersion(vmMo.getVirtualHardwareVersion());
970+
vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()), vmxFormattedVirtualHardwareVersion);
969971
clonedVm = vmMo.getRunningHost().findVmOnHyperHost(workerVmName);
970972
if (clonedVm == null) {
971973
String msg = "Unable to create dummy VM to export volume. volume path: " + volumePath;

vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,7 +1637,7 @@ private static VirtualDeviceConfigSpec getControllerSpec(String diskController,
16371637

16381638
return controllerSpec;
16391639
}
1640-
public static VirtualMachineMO createWorkerVM(VmwareHypervisorHost hyperHost, DatastoreMO dsMo, String vmName, String hardwareVersion) throws Exception {
1640+
public static VirtualMachineMO createWorkerVM(VmwareHypervisorHost hyperHost, DatastoreMO dsMo, String vmName, String vmxFormattedHardwareVersion) throws Exception {
16411641

16421642
// Allow worker VM to float within cluster so that we will have better chance to
16431643
// create it successfully
@@ -1651,8 +1651,8 @@ public static VirtualMachineMO createWorkerVM(VmwareHypervisorHost hyperHost, Da
16511651
VirtualMachineMO workingVM = null;
16521652
VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
16531653
vmConfig.setName(vmName);
1654-
if (hardwareVersion != null){
1655-
vmConfig.setVersion(("vmx-" + hardwareVersion));
1654+
if (StringUtils.isNotBlank(vmxFormattedHardwareVersion)){
1655+
vmConfig.setVersion(vmxFormattedHardwareVersion);
16561656
} else {
16571657
ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), hyperHost.getHyperHostCluster());
16581658
DatacenterMO dataCenterMo = new DatacenterMO(hyperHost.getContext(), hyperHost.getHyperHostDatacenter());

vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import java.util.concurrent.Executors;
3535
import java.util.concurrent.Future;
3636

37+
import com.cloud.utils.exception.CloudRuntimeException;
3738
import org.apache.commons.collections.CollectionUtils;
3839
import org.apache.commons.lang.StringUtils;
3940
import org.apache.log4j.Logger;
@@ -3292,6 +3293,18 @@ public int getVirtualHardwareVersion() throws Exception {
32923293
return vhOption.getHwVersion();
32933294
}
32943295

3296+
/**
3297+
* Return a hardware version string in the format expected by Vmware
3298+
* Format: "vmx-DD" where DD represents the hardware version number
3299+
* @param virtualHardwareVersion numeric virtual hardware version
3300+
*/
3301+
public static String getVmxFormattedVirtualHardwareVersion(int virtualHardwareVersion) {
3302+
if (virtualHardwareVersion < 1) {
3303+
throw new CloudRuntimeException("Invalid hardware version: " + virtualHardwareVersion);
3304+
}
3305+
return String.format("vmx-%02d", virtualHardwareVersion);
3306+
}
3307+
32953308
public VirtualHardwareOption getVirtualHardwareOption() throws Exception {
32963309
VirtualMachineConfigOption vmConfigOption = _context.getService().queryConfigOption(getEnvironmentBrowser(), null, null);
32973310
return vmConfigOption.getHardwareOptions();

vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMOTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import com.cloud.hypervisor.vmware.util.VmwareClient;
2121
import com.cloud.hypervisor.vmware.util.VmwareContext;
22+
import com.cloud.utils.exception.CloudRuntimeException;
2223
import com.vmware.vim25.ManagedObjectReference;
2324
import com.vmware.vim25.VirtualDevice;
2425
import com.vmware.vim25.VirtualLsiLogicController;
@@ -27,6 +28,7 @@
2728
import com.vmware.vim25.VirtualSCSISharing;
2829
import org.junit.After;
2930
import org.junit.AfterClass;
31+
import org.junit.Assert;
3032
import org.junit.Before;
3133
import org.junit.BeforeClass;
3234
import org.junit.Test;
@@ -117,4 +119,21 @@ public void TestEnsureLsiLogicDeviceControllers() {
117119
}
118120

119121
}
122+
123+
@Test
124+
public void testGetVmxFormattedVirtualHardwareVersionOneDigit() {
125+
String vmxHwVersion = VirtualMachineMO.getVmxFormattedVirtualHardwareVersion(8);
126+
Assert.assertEquals("vmx-08", vmxHwVersion);
127+
}
128+
129+
@Test
130+
public void testGetVmxFormattedVirtualHardwareVersionTwoDigits() {
131+
String vmxHwVersion = VirtualMachineMO.getVmxFormattedVirtualHardwareVersion(11);
132+
Assert.assertEquals("vmx-11", vmxHwVersion);
133+
}
134+
135+
@Test(expected = CloudRuntimeException.class)
136+
public void testGetVmxFormattedVirtualHardwareVersionInvalid() {
137+
VirtualMachineMO.getVmxFormattedVirtualHardwareVersion(-1);
138+
}
120139
}

0 commit comments

Comments
 (0)