@@ -751,43 +751,87 @@ public boolean hasSnapshot() throws Exception {
751751 return false ;
752752 }
753753
754- public boolean createFullCloneWithSpecificDisk (String cloneName , ManagedObjectReference morFolder , ManagedObjectReference morResourcePool , ManagedObjectReference morDs , Pair < VirtualDisk , String > volumeDeviceInfo )
754+ public VirtualMachineMO createFullCloneWithSpecificDisk (String cloneName , ManagedObjectReference morFolder , ManagedObjectReference morResourcePool , VirtualDisk requiredDisk )
755755 throws Exception {
756756
757757 assert (morFolder != null );
758758 assert (morResourcePool != null );
759- assert (morDs != null );
760- VirtualDisk requiredDisk = volumeDeviceInfo .first ();
759+ VirtualMachineRuntimeInfo runtimeInfo = getRuntimeInfo ();
760+ HostMO hostMo = new HostMO (_context , runtimeInfo .getHost ());
761+ DatacenterMO dcMo = new DatacenterMO (_context , hostMo .getHyperHostDatacenter ());
762+ DatastoreMO dsMo = new DatastoreMO (_context , morResourcePool );
761763
762764 VirtualMachineRelocateSpec rSpec = new VirtualMachineRelocateSpec ();
763- List <VirtualMachineRelocateSpecDiskLocator > diskLocator = new ArrayList <VirtualMachineRelocateSpecDiskLocator >(1 );
764- VirtualMachineRelocateSpecDiskLocator loc = new VirtualMachineRelocateSpecDiskLocator ();
765- loc .setDatastore (morDs );
766- loc .setDiskId (requiredDisk .getKey ());
767- loc .setDiskMoveType (VirtualMachineRelocateDiskMoveOptions .MOVE_ALL_DISK_BACKINGS_AND_DISALLOW_SHARING .value ());
768- diskLocator .add (loc );
769-
770- rSpec .setDiskMoveType (VirtualMachineRelocateDiskMoveOptions .MOVE_ALL_DISK_BACKINGS_AND_DISALLOW_SHARING .value ());
771- rSpec .getDisk ().addAll (diskLocator );
765+
766+ VirtualDisk [] vmDisks = getAllDiskDevice ();
767+ VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec ();
768+ s_logger .debug (String .format ("Removing the disks other than the required disk with key %s to the cloned VM" , requiredDisk .getKey ()));
769+ for (VirtualDisk disk : vmDisks ) {
770+ s_logger .debug (String .format ("Original disk with key %s found in the VM %s" , disk .getKey (), getName ()));
771+ if (requiredDisk .getKey () != disk .getKey ()) {
772+ VirtualDeviceConfigSpec virtualDeviceConfigSpec = new VirtualDeviceConfigSpec ();
773+ virtualDeviceConfigSpec .setDevice (disk );
774+ virtualDeviceConfigSpec .setOperation (VirtualDeviceConfigSpecOperation .REMOVE );
775+ vmConfigSpec .getDeviceChange ().add (virtualDeviceConfigSpec );
776+ }
777+ }
772778 rSpec .setPool (morResourcePool );
773779
774780 VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec ();
775781 cloneSpec .setPowerOn (false );
776782 cloneSpec .setTemplate (false );
777783 cloneSpec .setLocation (rSpec );
784+ cloneSpec .setMemory (false );
785+ cloneSpec .setConfig (vmConfigSpec );
778786
779787 ManagedObjectReference morTask = _context .getService ().cloneVMTask (_mor , morFolder , cloneName , cloneSpec );
780788
781789 boolean result = _context .getVimClient ().waitForTask (morTask );
782790 if (result ) {
783791 _context .waitForTaskProgressDone (morTask );
792+ VirtualMachineMO clonedVm = dcMo .findVm (cloneName );
793+ if (clonedVm == null ) {
794+ s_logger .error (String .format ("Failed to clone VM %s" , cloneName ));
795+ return null ;
796+ }
784797 s_logger .debug (String .format ("Cloned VM: %s as %s" , getName (), cloneName ));
785- return true ;
798+ clonedVm .tagAsWorkerVM ();
799+ makeSureVMHasOnlyRequiredDisk (clonedVm , requiredDisk , dsMo , dcMo );
800+ return clonedVm ;
786801 } else {
787802 s_logger .error ("VMware cloneVM_Task failed due to " + TaskMO .getTaskFailureInfo (_context , morTask ));
803+ return null ;
788804 }
805+ }
789806
790- return false ;
807+ private void makeSureVMHasOnlyRequiredDisk (VirtualMachineMO clonedVm , VirtualDisk requiredDisk , DatastoreMO dsMo , DatacenterMO dcMo ) throws Exception {
808+
809+ String vmName = clonedVm .getName ();
810+ VirtualDisk [] vmDisks = clonedVm .getAllDiskDevice ();
811+ s_logger .debug (String .format ("Checking if VM %s is created only with required Disk, if not detach the remaining disks" , vmName ));
812+ if (vmDisks .length == 1 ) {
813+ s_logger .debug (String .format ("VM %s is created only with required Disk" , vmName ));
814+ return ;
815+ }
816+
817+ VirtualDisk requiredCloneDisk = null ;
818+ for (VirtualDisk vmDisk : vmDisks ) {
819+ if (vmDisk .getKey () == requiredDisk .getKey ()) {
820+ requiredCloneDisk = vmDisk ;
821+ break ;
822+ }
823+ }
824+ if (requiredCloneDisk == null ) {
825+ s_logger .error (String .format ("Failed to identify required disk in VM %s" , vmName ));
826+ throw new CloudRuntimeException (String .format ("VM %s is not created with required disk" , vmName ));
827+ }
828+
829+ String baseName = VmwareHelper .getDiskDeviceFileName (requiredCloneDisk );
830+ s_logger .debug (String .format ("Detaching all disks for the VM: %s except disk with base name: %s, key=%d" , vmName , baseName , requiredCloneDisk .getKey ()));
831+ List <String > detachedDisks = clonedVm .detachAllDisksExcept (baseName , null );
832+ for (String diskPath : detachedDisks ) {
833+ dsMo .deleteFile (diskPath , dcMo .getMor (), true , null );
834+ }
791835 }
792836
793837 public boolean createFullClone (String cloneName , ManagedObjectReference morFolder , ManagedObjectReference morResourcePool , ManagedObjectReference morDs , Storage .ProvisioningType diskProvisioningType )
0 commit comments