Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1241,10 +1241,11 @@ private Ternary<String, Long, Long> createTemplateFromVolume(VmwareContext conte

DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
ManagedObjectReference morPool = hyperHost.getHyperHostOwnerResourcePool();
vmMo.createFullCloneWithSpecificDisk(templateUniqueName, dcMo.getVmFolder(), morPool, VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()), volumeDeviceInfo);
clonedVm = dcMo.findVm(templateUniqueName);

clonedVm.tagAsWorkerVM();
VirtualDisk requiredDisk = volumeDeviceInfo.first();
clonedVm = vmMo.createFullCloneWithSpecificDisk(templateUniqueName, dcMo.getVmFolder(), morPool, requiredDisk);
if (clonedVm == null) {
throw new Exception(String.format("Failed to clone VM with name %s during create template from volume operation", templateUniqueName));
}
clonedVm.exportVm(secondaryMountPoint + "/" + installPath, templateUniqueName, false, false);

// Get VMDK filename
Expand Down Expand Up @@ -1828,14 +1829,11 @@ private Pair<String, String[]> exportVolumeToSecondaryStorage(VmwareContext cont
// 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);
clonedVm = dcMo.findVm(exportName);
VirtualDisk requiredDisk = volumeDeviceInfo.first();
clonedVm = vmMo.createFullCloneWithSpecificDisk(exportName, dcMo.getVmFolder(), morPool, requiredDisk);
if (clonedVm == null) {
String msg = "Failed to clone VM. volume path: " + volumePath;
s_logger.error(msg);
throw new Exception(msg);
throw new Exception(String.format("Failed to clone VM with name %s during export volume operation", exportName));
}
clonedVm.tagAsWorkerVM();
vmMo = clonedVm;
}
vmMo.exportVm(exportPath, exportName, false, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -751,43 +751,87 @@ public boolean hasSnapshot() throws Exception {
return false;
}

public boolean createFullCloneWithSpecificDisk(String cloneName, ManagedObjectReference morFolder, ManagedObjectReference morResourcePool, ManagedObjectReference morDs, Pair<VirtualDisk, String> volumeDeviceInfo)
public VirtualMachineMO createFullCloneWithSpecificDisk(String cloneName, ManagedObjectReference morFolder, ManagedObjectReference morResourcePool, VirtualDisk requiredDisk)
throws Exception {

assert (morFolder != null);
assert (morResourcePool != null);
assert (morDs != null);
VirtualDisk requiredDisk = volumeDeviceInfo.first();
VirtualMachineRuntimeInfo runtimeInfo = getRuntimeInfo();
HostMO hostMo = new HostMO(_context, runtimeInfo.getHost());
DatacenterMO dcMo = new DatacenterMO(_context, hostMo.getHyperHostDatacenter());
DatastoreMO dsMo = new DatastoreMO(_context, morResourcePool);

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();
s_logger.debug(String.format("Removing the disks other than the required disk with key %s to the cloned VM", requiredDisk.getKey()));
for (VirtualDisk disk : vmDisks) {
s_logger.debug(String.format("Original disk with key %s found in the VM %s", disk.getKey(), getName()));
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);

boolean result = _context.getVimClient().waitForTask(morTask);
if (result) {
_context.waitForTaskProgressDone(morTask);
VirtualMachineMO clonedVm = dcMo.findVm(cloneName);
if (clonedVm == null) {
s_logger.error(String.format("Failed to clone VM %s", cloneName));
return null;
}
s_logger.debug(String.format("Cloned VM: %s as %s", getName(), cloneName));
return true;
clonedVm.tagAsWorkerVM();
makeSureVMHasOnlyRequiredDisk(clonedVm, requiredDisk, dsMo, dcMo);
return clonedVm;
} else {
s_logger.error("VMware cloneVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
return null;
}
}

return false;
private void makeSureVMHasOnlyRequiredDisk(VirtualMachineMO clonedVm, VirtualDisk requiredDisk, DatastoreMO dsMo, DatacenterMO dcMo) throws Exception {

String vmName = clonedVm.getName();
VirtualDisk[] vmDisks = clonedVm.getAllDiskDevice();
s_logger.debug(String.format("Checking if VM %s is created only with required Disk, if not detach the remaining disks", vmName));
if (vmDisks.length == 1) {
s_logger.debug(String.format("VM %s is created only with required Disk", vmName));
return;
}

VirtualDisk requiredCloneDisk = null;
for (VirtualDisk vmDisk: vmDisks) {
if (vmDisk.getKey() == requiredDisk.getKey()) {
requiredCloneDisk = vmDisk;
break;
}
}
if (requiredCloneDisk == null) {
s_logger.error(String.format("Failed to identify required disk in VM %s", vmName));
throw new CloudRuntimeException(String.format("VM %s is not created with required disk", vmName));
}

String baseName = VmwareHelper.getDiskDeviceFileName(requiredCloneDisk);
s_logger.debug(String.format("Detaching all disks for the VM: %s except disk with base name: %s, key=%d", vmName, baseName, requiredCloneDisk.getKey()));
List<String> detachedDisks = clonedVm.detachAllDisksExcept(baseName, null);
for (String diskPath : detachedDisks) {
dsMo.deleteFile(diskPath, dcMo.getMor(), true, null);
}
}

public boolean createFullClone(String cloneName, ManagedObjectReference morFolder, ManagedObjectReference morResourcePool, ManagedObjectReference morDs, Storage.ProvisioningType diskProvisioningType)
Expand Down