You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ha...@apache.org on 2021/09/24 08:29:25 UTC

[cloudstack] 01/01: Fix export snapshot and export template to secondary storage in VMware to export only one required disk

This is an automated email from the ASF dual-hosted git repository.

harikrishna pushed a commit to branch VMwareExportSnapshotFix
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit e4727f7fa0bb3e6317579d274f191d29e219442d
Author: Harikrishna Patnala <ha...@gmail.com>
AuthorDate: Fri Sep 24 13:36:17 2021 +0530

    Fix export snapshot and export template to secondary storage in VMware to export only one required disk
---
 .../storage/resource/VmwareStorageProcessor.java   | 22 ++++++++++++++++--
 .../hypervisor/vmware/mo/VirtualMachineMO.java     | 26 ++++++++++++----------
 2 files changed, 34 insertions(+), 14 deletions(-)

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 7ed4e2f..bd0d613 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
@@ -1241,9 +1241,12 @@ public class VmwareStorageProcessor implements StorageProcessor {
 
             DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
             ManagedObjectReference morPool = hyperHost.getHyperHostOwnerResourcePool();
-            vmMo.createFullCloneWithSpecificDisk(templateUniqueName, dcMo.getVmFolder(), morPool, VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()), volumeDeviceInfo);
+            VirtualDisk requiredDisk = volumeDeviceInfo.first();
+            vmMo.createFullCloneWithSpecificDisk(templateUniqueName, dcMo.getVmFolder(), morPool, requiredDisk);
             clonedVm = dcMo.findVm(templateUniqueName);
 
+            checkIfVMHasOnlyRequiredDisk(clonedVm, requiredDisk);
+
             clonedVm.tagAsWorkerVM();
             clonedVm.exportVm(secondaryMountPoint + "/" + installPath, templateUniqueName, false, false);
 
@@ -1828,13 +1831,15 @@ public class VmwareStorageProcessor implements StorageProcessor {
                 // 4 MB is the minimum requirement for VM memory in VMware
                 DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
                 ManagedObjectReference morPool = hyperHost.getHyperHostOwnerResourcePool();
-                vmMo.createFullCloneWithSpecificDisk(exportName, dcMo.getVmFolder(), morPool, VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()), volumeDeviceInfo);
+                VirtualDisk requiredDisk = volumeDeviceInfo.first();
+                vmMo.createFullCloneWithSpecificDisk(exportName, dcMo.getVmFolder(), morPool, requiredDisk);
                 clonedVm = dcMo.findVm(exportName);
                 if (clonedVm == null) {
                     String msg = "Failed to clone VM. volume path: " + volumePath;
                     s_logger.error(msg);
                     throw new Exception(msg);
                 }
+                checkIfVMHasOnlyRequiredDisk(clonedVm, requiredDisk);
                 clonedVm.tagAsWorkerVM();
                 vmMo = clonedVm;
             }
@@ -1849,6 +1854,19 @@ public class VmwareStorageProcessor implements StorageProcessor {
         }
     }
 
+    private void checkIfVMHasOnlyRequiredDisk(VirtualMachineMO clonedVm, VirtualDisk requiredDisk) throws Exception {
+
+        s_logger.info(String.format("Checking if Cloned VM %s is created only with required Disk, if not detach the remaining disks", clonedVm.getName()));
+        VirtualDisk[] vmDisks = clonedVm.getAllDiskDevice();
+        if (vmDisks.length != 1) {
+            String baseName = VmwareHelper.getDiskDeviceFileName(requiredDisk);
+            s_logger.info(String.format("Detaching all disks for the cloned VM: %s except disk with base name: %s, key=%d", clonedVm.getName(), baseName, requiredDisk.getKey()));
+            clonedVm.detachAllDisksExcept(VmwareHelper.getDiskDeviceFileName(requiredDisk), null);
+        } else {
+            s_logger.info(String.format("Cloned VM %s is created only with required Disk", clonedVm.getName()));
+        }
+    }
+
     // Ternary<String(backup uuid in secondary storage), String(device bus name), String[](original disk chain in the snapshot)>
     private Ternary<String, String, String[]> backupSnapshotToSecondaryStorage(VmwareContext context, VirtualMachineMO vmMo, VmwareHypervisorHost hypervisorHost, String installPath, String volumePath, String snapshotUuid,
                                                                                String secStorageUrl, String prevSnapshotUuid, String prevBackupUuid, String workerVmName,
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 2384935..93df0dc 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
@@ -751,30 +751,32 @@ public class VirtualMachineMO extends BaseMO {
         return false;
     }
 
-    public boolean createFullCloneWithSpecificDisk(String cloneName, ManagedObjectReference morFolder, ManagedObjectReference morResourcePool, ManagedObjectReference morDs, Pair<VirtualDisk, String> volumeDeviceInfo)
+    public boolean createFullCloneWithSpecificDisk(String cloneName, ManagedObjectReference morFolder, ManagedObjectReference morResourcePool, VirtualDisk requiredDisk)
             throws Exception {
 
         assert (morFolder != null);
         assert (morResourcePool != null);
-        assert (morDs != null);
-        VirtualDisk requiredDisk = volumeDeviceInfo.first();
 
         VirtualMachineRelocateSpec rSpec = new VirtualMachineRelocateSpec();
-        List<VirtualMachineRelocateSpecDiskLocator> diskLocator = new ArrayList<VirtualMachineRelocateSpecDiskLocator>(1);
-        VirtualMachineRelocateSpecDiskLocator loc = new VirtualMachineRelocateSpecDiskLocator();
-        loc.setDatastore(morDs);
-        loc.setDiskId(requiredDisk.getKey());
-        loc.setDiskMoveType(VirtualMachineRelocateDiskMoveOptions.MOVE_ALL_DISK_BACKINGS_AND_DISALLOW_SHARING.value());
-        diskLocator.add(loc);
-
-        rSpec.setDiskMoveType(VirtualMachineRelocateDiskMoveOptions.MOVE_ALL_DISK_BACKINGS_AND_DISALLOW_SHARING.value());
-        rSpec.getDisk().addAll(diskLocator);
+
+        VirtualDisk[] vmDisks = getAllDiskDevice();
+        VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+        for (VirtualDisk disk : vmDisks) {
+            if (requiredDisk.getKey() != disk.getKey()) {
+                VirtualDeviceConfigSpec virtualDeviceConfigSpec = new VirtualDeviceConfigSpec();
+                virtualDeviceConfigSpec.setDevice(disk);
+                virtualDeviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
+                vmConfigSpec.getDeviceChange().add(virtualDeviceConfigSpec);
+            }
+        }
         rSpec.setPool(morResourcePool);
 
         VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec();
         cloneSpec.setPowerOn(false);
         cloneSpec.setTemplate(false);
         cloneSpec.setLocation(rSpec);
+        cloneSpec.setMemory(false);
+        cloneSpec.setConfig(vmConfigSpec);
 
         ManagedObjectReference morTask = _context.getService().cloneVMTask(_mor, morFolder, cloneName, cloneSpec);