@@ -741,43 +741,87 @@ public boolean hasSnapshot() throws Exception {
741741 return false ;
742742 }
743743
744- public boolean createFullCloneWithSpecificDisk (String cloneName , ManagedObjectReference morFolder , ManagedObjectReference morResourcePool , ManagedObjectReference morDs , Pair < VirtualDisk , String > volumeDeviceInfo )
744+ public VirtualMachineMO createFullCloneWithSpecificDisk (String cloneName , ManagedObjectReference morFolder , ManagedObjectReference morResourcePool , VirtualDisk requiredDisk )
745745 throws Exception {
746746
747747 assert (morFolder != null );
748748 assert (morResourcePool != null );
749- assert (morDs != null );
750- VirtualDisk requiredDisk = volumeDeviceInfo .first ();
749+ VirtualMachineRuntimeInfo runtimeInfo = getRuntimeInfo ();
750+ HostMO hostMo = new HostMO (_context , runtimeInfo .getHost ());
751+ DatacenterMO dcMo = new DatacenterMO (_context , hostMo .getHyperHostDatacenter ());
752+ DatastoreMO dsMo = new DatastoreMO (_context , morResourcePool );
751753
752754 VirtualMachineRelocateSpec rSpec = new VirtualMachineRelocateSpec ();
753- List <VirtualMachineRelocateSpecDiskLocator > diskLocator = new ArrayList <VirtualMachineRelocateSpecDiskLocator >(1 );
754- VirtualMachineRelocateSpecDiskLocator loc = new VirtualMachineRelocateSpecDiskLocator ();
755- loc .setDatastore (morDs );
756- loc .setDiskId (requiredDisk .getKey ());
757- loc .setDiskMoveType (VirtualMachineRelocateDiskMoveOptions .MOVE_ALL_DISK_BACKINGS_AND_DISALLOW_SHARING .value ());
758- diskLocator .add (loc );
759-
760- rSpec .setDiskMoveType (VirtualMachineRelocateDiskMoveOptions .MOVE_ALL_DISK_BACKINGS_AND_DISALLOW_SHARING .value ());
761- rSpec .getDisk ().addAll (diskLocator );
755+
756+ VirtualDisk [] vmDisks = getAllDiskDevice ();
757+ VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec ();
758+ s_logger .debug (String .format ("Removing the disks other than the required disk with key %s to the cloned VM" , requiredDisk .getKey ()));
759+ for (VirtualDisk disk : vmDisks ) {
760+ s_logger .debug (String .format ("Original disk with key %s found in the VM %s" , disk .getKey (), getName ()));
761+ if (requiredDisk .getKey () != disk .getKey ()) {
762+ VirtualDeviceConfigSpec virtualDeviceConfigSpec = new VirtualDeviceConfigSpec ();
763+ virtualDeviceConfigSpec .setDevice (disk );
764+ virtualDeviceConfigSpec .setOperation (VirtualDeviceConfigSpecOperation .REMOVE );
765+ vmConfigSpec .getDeviceChange ().add (virtualDeviceConfigSpec );
766+ }
767+ }
762768 rSpec .setPool (morResourcePool );
763769
764770 VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec ();
765771 cloneSpec .setPowerOn (false );
766772 cloneSpec .setTemplate (false );
767773 cloneSpec .setLocation (rSpec );
774+ cloneSpec .setMemory (false );
775+ cloneSpec .setConfig (vmConfigSpec );
768776
769777 ManagedObjectReference morTask = _context .getService ().cloneVMTask (_mor , morFolder , cloneName , cloneSpec );
770778
771779 boolean result = _context .getVimClient ().waitForTask (morTask );
772780 if (result ) {
773781 _context .waitForTaskProgressDone (morTask );
782+ VirtualMachineMO clonedVm = dcMo .findVm (cloneName );
783+ if (clonedVm == null ) {
784+ s_logger .error (String .format ("Failed to clone VM %s" , cloneName ));
785+ return null ;
786+ }
774787 s_logger .debug (String .format ("Cloned VM: %s as %s" , getName (), cloneName ));
775- return true ;
788+ clonedVm .tagAsWorkerVM ();
789+ makeSureVMHasOnlyRequiredDisk (clonedVm , requiredDisk , dsMo , dcMo );
790+ return clonedVm ;
776791 } else {
777792 s_logger .error ("VMware cloneVM_Task failed due to " + TaskMO .getTaskFailureInfo (_context , morTask ));
793+ return null ;
778794 }
795+ }
779796
780- return false ;
797+ private void makeSureVMHasOnlyRequiredDisk (VirtualMachineMO clonedVm , VirtualDisk requiredDisk , DatastoreMO dsMo , DatacenterMO dcMo ) throws Exception {
798+
799+ String vmName = clonedVm .getName ();
800+ VirtualDisk [] vmDisks = clonedVm .getAllDiskDevice ();
801+ s_logger .debug (String .format ("Checking if VM %s is created only with required Disk, if not detach the remaining disks" , vmName ));
802+ if (vmDisks .length == 1 ) {
803+ s_logger .debug (String .format ("VM %s is created only with required Disk" , vmName ));
804+ return ;
805+ }
806+
807+ VirtualDisk requiredCloneDisk = null ;
808+ for (VirtualDisk vmDisk : vmDisks ) {
809+ if (vmDisk .getKey () == requiredDisk .getKey ()) {
810+ requiredCloneDisk = vmDisk ;
811+ break ;
812+ }
813+ }
814+ if (requiredCloneDisk == null ) {
815+ s_logger .error (String .format ("Failed to identify required disk in VM %s" , vmName ));
816+ throw new CloudRuntimeException (String .format ("VM %s is not created with required disk" , vmName ));
817+ }
818+
819+ String baseName = VmwareHelper .getDiskDeviceFileName (requiredCloneDisk );
820+ s_logger .debug (String .format ("Detaching all disks for the VM: %s except disk with base name: %s, key=%d" , vmName , baseName , requiredCloneDisk .getKey ()));
821+ List <String > detachedDisks = clonedVm .detachAllDisksExcept (baseName , null );
822+ for (String diskPath : detachedDisks ) {
823+ dsMo .deleteFile (diskPath , dcMo .getMor (), true , null );
824+ }
781825 }
782826
783827 public boolean createFullClone (String cloneName , ManagedObjectReference morFolder , ManagedObjectReference morResourcePool , ManagedObjectReference morDs )
0 commit comments