From 479ef8aafaa6162daa1d26058d225d885065f4cc Mon Sep 17 00:00:00 2001 From: Spaceman1984 <49917670+Spaceman1984@users.noreply.github.com> Date: Fri, 9 Oct 2020 17:06:07 +0200 Subject: [PATCH] VMware: match hardware version for worker VM when taking a snapshot (#4321) * Add hardware version to worker VM * Added worker VM hardware version when creating a template from a volume and migrating a detached volume * Add null parameter back that was removed by merge --- .../manager/VmwareStorageManagerImpl.java | 8 +++---- .../vmware/resource/VmwareResource.java | 4 ++-- .../resource/VmwareStorageProcessor.java | 24 +++++++++++-------- .../vmware/mo/HypervisorHostHelper.java | 11 +++++++-- .../vmware/mo/VirtualMachineMO.java | 8 +++---- 5 files changed, 33 insertions(+), 22 deletions(-) diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java index 369e5b6ef6e..d59fcfbdf12 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java @@ -344,7 +344,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { dsMo = new DatastoreMO(hyperHost.getContext(), morDs); workerVMName = hostService.getWorkerName(context, cmd, 0); - vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName); + vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName, null); if (vmMo == null) { throw new Exception("Failed to find the newly create or relocated VM. vmName: " + workerVMName); @@ -647,7 +647,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } // 4 MB is the minimum requirement for VM memory in VMware - vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first())); + vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()), null); clonedVm = vmMo.getRunningHost().findVmOnHyperHost(workerVmName); if (clonedVm == null) { String msg = "Unable to create dummy VM to export volume. volume path: " + volumePath; @@ -965,7 +965,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { if (clonedWorkerVMNeeded) { // 4 MB is the minimum requirement for VM memory in VMware - vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first())); + vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()), null); clonedVm = vmMo.getRunningHost().findVmOnHyperHost(workerVmName); if (clonedVm == null) { String msg = "Unable to create dummy VM to export volume. volume path: " + volumePath; @@ -1008,7 +1008,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { if (vmMo == null) { // create a dummy worker vm for attaching the volume DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), morDs); - workerVm = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVmName); + workerVm = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVmName, null); if (workerVm == null) { String msg = "Unable to create worker VM to execute CopyVolumeCommand"; diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 740e122c9c4..3ef1fc27f01 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -763,7 +763,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa s_logger.info("Create worker VM " + vmName); // OfflineVmwareMigration: 2. create the worker with access to the data(store) - vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, vmName); + vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, vmName, null); if (vmMo == null) { // OfflineVmwareMigration: don't throw a general Exception but think of a specific one @@ -4595,7 +4595,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa dsMo = new DatastoreMO(hyperHost.getContext(), morSourceDS); s_logger.info("Create worker VM " + vmName); // OfflineVmwareMigration: 2. create the worker with access to the data(store) - vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, vmName); + vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, vmName, null); if (vmMo == null) { // OfflineVmwareMigration: don't throw a general Exception but think of a specific one throw new CloudRuntimeException("Unable to create a worker VM for volume operation"); diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java index f8b8f4c1f34..df780e76216 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -396,7 +396,7 @@ public class VmwareStorageProcessor implements StorageProcessor { if (vmName != null) { String workerVmName = hostService.getWorkerName(context, cmd, 0); - VirtualMachineMO vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVmName); + VirtualMachineMO vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVmName, null); if (vmMo == null) { throw new Exception("Unable to create a worker VM for volume creation"); @@ -794,7 +794,7 @@ public class VmwareStorageProcessor implements StorageProcessor { String dummyVmName = hostService.getWorkerName(context, cmd, 0); try { - vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName); + vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName, null); if (vmMo == null) { throw new Exception("Unable to create a dummy VM for volume creation"); } @@ -995,7 +995,7 @@ public class VmwareStorageProcessor implements StorageProcessor { if (vmMo == null || VmwareResource.getVmState(vmMo) == PowerState.PowerOff) { // create a dummy worker vm for attaching the volume DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), morDs); - workerVm = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVmName); + workerVm = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVmName, null); if (workerVm == null) { String msg = "Unable to create worker VM to execute CopyVolumeCommand"; @@ -1130,9 +1130,11 @@ public class VmwareStorageProcessor implements StorageProcessor { throw new Exception(msg); } + String hardwareVersion = String.valueOf(vmMo.getVirtualHardwareVersion()); + // 4 MB is the minimum requirement for VM memory in VMware Pair cloneResult = - vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first())); + vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()), hardwareVersion); clonedVm = cloneResult.first(); clonedVm.exportVm(secondaryMountPoint + "/" + installPath, templateUniqueName, false, false); @@ -1194,7 +1196,7 @@ public class VmwareStorageProcessor implements StorageProcessor { if (volume.getVmName() == null) { ManagedObjectReference secMorDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, volume.getDataStore().getUuid()); DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), secMorDs); - workerVmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, "workervm"+volume.getUuid()); + workerVmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, "workervm"+volume.getUuid(), null); if (workerVmMo == null) { throw new Exception("Unable to find created worker VM"); } @@ -1551,7 +1553,7 @@ public class VmwareStorageProcessor implements StorageProcessor { ManagedObjectReference dsMor = hyperHost.findDatastoreByName(dsFile.getDatastoreName()); DatastoreMO dsMo = new DatastoreMO(context, dsMor); - VirtualMachineMO workerVM = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName); + VirtualMachineMO workerVM = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName, null); if (workerVM == null) { throw new CloudRuntimeException("Failed to find the newly created worker VM: " + workerVMName); @@ -1716,12 +1718,14 @@ public class VmwareStorageProcessor implements StorageProcessor { throw new Exception(msg); } + String virtualHardwareVersion = String.valueOf(vmMo.getVirtualHardwareVersion()); + String diskDevice = volumeDeviceInfo.second(); String disks[] = vmMo.getCurrentSnapshotDiskChainDatastorePaths(diskDevice); if (clonedWorkerVMNeeded) { // 4 MB is the minimum requirement for VM memory in VMware Pair cloneResult = - vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, diskDevice, VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first())); + vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, diskDevice, VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()), virtualHardwareVersion); clonedVm = cloneResult.first(); clonedVm.exportVm(exportPath, exportName, false, false); } else { @@ -1798,7 +1802,7 @@ public class VmwareStorageProcessor implements StorageProcessor { if(vmMo == null) { dsMo = new DatastoreMO(hyperHost.getContext(), morDs); workerVMName = hostService.getWorkerName(context, cmd, 0); - vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName); + vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName, null); if (vmMo == null) { throw new Exception("Failed to find the newly create or relocated VM. vmName: " + workerVMName); } @@ -2251,7 +2255,7 @@ public class VmwareStorageProcessor implements StorageProcessor { String dummyVmName = hostService.getWorkerName(context, cmd, 0); try { s_logger.info("Create worker VM " + dummyVmName); - vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName); + vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName, null); if (vmMo == null) { throw new Exception("Unable to create a dummy VM for volume creation"); } @@ -2934,7 +2938,7 @@ public class VmwareStorageProcessor implements StorageProcessor { String dummyVmName = hostService.getWorkerName(context, cmd, 0); - VirtualMachineMO vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName); + VirtualMachineMO vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName, null); if (vmMo == null) { throw new Exception("Unable to create a dummy VM for volume creation"); diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java index c3143ae9954..1242d25f90c 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java @@ -1604,7 +1604,7 @@ public class HypervisorHostHelper { return controllerSpec; } - public static VirtualMachineMO createWorkerVM(VmwareHypervisorHost hyperHost, DatastoreMO dsMo, String vmName) throws Exception { + public static VirtualMachineMO createWorkerVM(VmwareHypervisorHost hyperHost, DatastoreMO dsMo, String vmName, String hardwareVersion) throws Exception { // Allow worker VM to float within cluster so that we will have better chance to // create it successfully @@ -1615,6 +1615,13 @@ public class HypervisorHostHelper { VirtualMachineMO workingVM = null; VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec(); vmConfig.setName(vmName); + if (hardwareVersion != null){ + vmConfig.setVersion(("vmx-" + hardwareVersion)); + } else { + ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), hyperHost.getHyperHostCluster()); + DatacenterMO dataCenterMo = new DatacenterMO(hyperHost.getContext(), hyperHost.getHyperHostDatacenter()); + setVMHardwareVersion(vmConfig, clusterMo, dataCenterMo); + } vmConfig.setMemoryMB((long)4); vmConfig.setNumCPUs(1); vmConfig.setGuestId(VirtualMachineGuestOsIdentifier.OTHER_GUEST.value()); @@ -1933,7 +1940,7 @@ public class HypervisorHostHelper { ManagedObjectReference morDs) throws Exception { VmwareContext context = host.getContext(); ManagedObjectReference morOvf = context.getServiceContent().getOvfManager(); - VirtualMachineMO workerVmMo = HypervisorHostHelper.createWorkerVM(host, new DatastoreMO(context, morDs), ovfName); + VirtualMachineMO workerVmMo = HypervisorHostHelper.createWorkerVM(host, new DatastoreMO(context, morDs), ovfName, null); if (workerVmMo == null) throw new Exception("Unable to find just-created worker VM"); diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java index f417e4e0e03..68bce537ba6 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java @@ -1959,21 +1959,21 @@ public class VirtualMachineMO extends BaseMO { } // return the disk chain (VMDK datastore paths) for cloned snapshot - public Pair cloneFromCurrentSnapshot(String clonedVmName, int cpuSpeedMHz, int memoryMb, String diskDevice, ManagedObjectReference morDs) + public Pair cloneFromCurrentSnapshot(String clonedVmName, int cpuSpeedMHz, int memoryMb, String diskDevice, ManagedObjectReference morDs, String virtualHardwareVersion) throws Exception { assert (morDs != null); String[] disks = getCurrentSnapshotDiskChainDatastorePaths(diskDevice); - VirtualMachineMO clonedVm = cloneFromDiskChain(clonedVmName, cpuSpeedMHz, memoryMb, disks, morDs); + VirtualMachineMO clonedVm = cloneFromDiskChain(clonedVmName, cpuSpeedMHz, memoryMb, disks, morDs, virtualHardwareVersion); return new Pair(clonedVm, disks); } - public VirtualMachineMO cloneFromDiskChain(String clonedVmName, int cpuSpeedMHz, int memoryMb, String[] disks, ManagedObjectReference morDs) throws Exception { + public VirtualMachineMO cloneFromDiskChain(String clonedVmName, int cpuSpeedMHz, int memoryMb, String[] disks, ManagedObjectReference morDs, String cloneHardwareVersion) throws Exception { assert (disks != null); assert (disks.length >= 1); HostMO hostMo = getRunningHost(); - VirtualMachineMO clonedVmMo = HypervisorHostHelper.createWorkerVM(hostMo, new DatastoreMO(hostMo.getContext(), morDs), clonedVmName); + VirtualMachineMO clonedVmMo = HypervisorHostHelper.createWorkerVM(hostMo, new DatastoreMO(hostMo.getContext(), morDs), clonedVmName, cloneHardwareVersion); if (clonedVmMo == null) throw new Exception("Unable to find just-created blank VM");