Use VStorageObjectManager for disk operations.

Created disks using VStorageObjectManager
Removed redundant code around attach volume and create volumes
This commit is contained in:
Harikrishna Patnala 2020-06-26 12:02:58 +05:30
parent 6c314492e7
commit aa07959f2a
8 changed files with 214 additions and 276 deletions

View File

@ -311,7 +311,14 @@ public class VmwareStorageLayoutHelper {
}
public static String getLegacyDatastorePathFromVmdkFileName(DatastoreMO dsMo, String vmdkFileName) throws Exception {
return String.format("[%s] %s/%s", dsMo.getName(), HypervisorHostHelper.VSPHERE_DATASTORE_BASE_FOLDER, vmdkFileName);
String vmdkDatastorePath = String.format("[%s] %s/%s", dsMo.getName(), HypervisorHostHelper.VSPHERE_DATASTORE_BASE_FOLDER, vmdkFileName);
if (!dsMo.fileExists(vmdkDatastorePath)) {
vmdkDatastorePath = String.format("[%s] %s/%s", dsMo.getName(), HypervisorHostHelper.VSPHERE_FCD_DEFAULT_FOLDER, vmdkFileName);
}
if (!dsMo.fileExists(vmdkDatastorePath)) {
vmdkDatastorePath = getDeprecatedLegacyDatastorePathFromVmdkFileName(dsMo, vmdkFileName);
}
return vmdkDatastorePath;
}
public static String getDeprecatedLegacyDatastorePathFromVmdkFileName(DatastoreMO dsMo, String vmdkFileName) throws Exception {

View File

@ -34,6 +34,10 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import com.cloud.hypervisor.vmware.mo.VirtualStorageObjectManagerMO;
import com.vmware.vim25.BaseConfigInfoDiskFileBackingInfo;
import com.vmware.vim25.VStorageObject;
import com.vmware.vim25.VirtualDiskType;
import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
import org.apache.cloudstack.storage.command.AttachAnswer;
import org.apache.cloudstack.storage.command.AttachCommand;
@ -2253,37 +2257,50 @@ public class VmwareStorageProcessor implements StorageProcessor {
String volumeUuid = UUID.randomUUID().toString().replace("-", "");
String volumeDatastorePath = dsMo.getDatastorePath(volumeUuid + ".vmdk");
String dummyVmName = hostService.getWorkerName(context, cmd, 0);
try {
s_logger.info("Create worker VM " + dummyVmName);
vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName, null);
if (vmMo == null) {
throw new Exception("Unable to create a dummy VM for volume creation");
}
synchronized (this) {
try {
vmMo.createDisk(volumeDatastorePath, (int)(volume.getSize() / (1024L * 1024L)), morDatastore, vmMo.getScsiDeviceControllerKey());
vmMo.detachDisk(volumeDatastorePath, false);
VirtualStorageObjectManagerMO vStorageObjectManagerMO = new VirtualStorageObjectManagerMO(context);
VStorageObject virtualDisk = vStorageObjectManagerMO.createDisk(morDatastore, VirtualDiskType.THIN, volume.getSize(), volumeDatastorePath, volumeUuid);
VolumeObjectTO newVol = new VolumeObjectTO();
DatastoreFile file = new DatastoreFile(((BaseConfigInfoDiskFileBackingInfo)virtualDisk.getConfig().getBacking()).getFilePath());
newVol.setPath(file.getFileBaseName());
newVol.setSize(volume.getSize());
return new CreateObjectAnswer(newVol);
/*
* // This is old code which uses workervm to create disks
* String dummyVmName = hostService.getWorkerName(context, cmd, 0);
try {
s_logger.info("Create worker VM " + dummyVmName);
vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName, null);
if (vmMo == null) {
throw new Exception("Unable to create a dummy VM for volume creation");
}
catch (Exception e) {
s_logger.error("Deleting file " + volumeDatastorePath + " due to error: " + e.getMessage());
VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, volumeUuid, dcMo, VmwareManager.s_vmwareSearchExcludeFolder.value());
throw new CloudRuntimeException("Unable to create volume due to: " + e.getMessage());
synchronized (this) {
try {
vmMo.createDisk(volumeDatastorePath, (int)(volume.getSize() / (1024L * 1024L)), morDatastore, vmMo.getScsiDeviceControllerKey());
vmMo.detachDisk(volumeDatastorePath, false);
}
catch (Exception e) {
s_logger.error("Deleting file " + volumeDatastorePath + " due to error: " + e.getMessage());
VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, volumeUuid, dcMo, VmwareManager.s_vmwareSearchExcludeFolder.value());
throw new CloudRuntimeException("Unable to create volume due to: " + e.getMessage());
}
}
VolumeObjectTO newVol = new VolumeObjectTO();
newVol.setPath(volumeUuid);
newVol.setSize(volume.getSize());
return new CreateObjectAnswer(newVol);
} finally {
s_logger.info("Destroy dummy VM after volume creation");
if (vmMo != null) {
vmMo.detachAllDisks();
vmMo.destroy();
}
}
VolumeObjectTO newVol = new VolumeObjectTO();
newVol.setPath(volumeUuid);
newVol.setSize(volume.getSize());
return new CreateObjectAnswer(newVol);
} finally {
s_logger.info("Destroy dummy VM after volume creation");
if (vmMo != null) {
vmMo.detachAllDisks();
vmMo.destroy();
}
}
* */
} catch (Throwable e) {
if (e instanceof RemoteException) {
s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");

View File

@ -139,6 +139,7 @@ public class HypervisorHostHelper {
private static final String VMDK_PACK_DIR = "ova";
private static final String OVA_OPTION_KEY_BOOTDISK = "cloud.ova.bootdisk";
public static final String VSPHERE_DATASTORE_BASE_FOLDER = ".cloudstack.base.folder";
public static final String VSPHERE_FCD_DEFAULT_FOLDER = "fcd";
public static VirtualMachineMO findVmFromObjectContent(VmwareContext context, ObjectContent[] ocs, String name, String instanceNameCustomField) {

View File

@ -77,4 +77,8 @@ public class TaskMO extends BaseMO {
return sb.toString();
}
public static TaskInfo getTaskInfo(VmwareContext context, ManagedObjectReference morTask) throws Exception {
return (TaskInfo)context.getVimClient().getDynamicProperty(morTask, "info");
}
}

View File

@ -38,6 +38,7 @@ import com.vmware.vim25.VStorageObject;
import com.vmware.vim25.VStorageObjectConfigInfo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.apache.commons.lang.StringUtils;
import com.google.gson.Gson;
import com.vmware.vim25.ArrayOfManagedObjectReference;
@ -1195,7 +1196,18 @@ public class VirtualMachineMO extends BaseMO {
s_logger.trace("vCenter API trace - createDisk() done(successfully)");
}
public void updateVmdkAdapter(String vmdkFileName, String newAdapterType) throws Exception {
public void updateVmdkAdapter(String vmdkFileName, String diskController) throws Exception {
DiskControllerType diskControllerType = DiskControllerType.getType(diskController);
VmdkAdapterType vmdkAdapterType = VmdkAdapterType.getAdapterType(diskControllerType);
if (vmdkAdapterType == VmdkAdapterType.none) {
String message = "Failed to attach disk due to invalid vmdk adapter type for vmdk file [" +
vmdkFileName + "] with controller : " + diskControllerType;
s_logger.debug(message);
throw new Exception(message);
}
String newAdapterType = vmdkAdapterType.toString();
Pair<VmdkFileDescriptor, byte[]> vmdkInfo = getVmdkFileInfo(vmdkFileName);
VmdkFileDescriptor vmdkFileDescriptor = vmdkInfo.first();
boolean isVmfsSparseFile = vmdkFileDescriptor.isVmfsSparseFile();
@ -1240,6 +1252,10 @@ public class VirtualMachineMO extends BaseMO {
}
}
public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs) throws Exception {
attachDisk(vmdkDatastorePathChain, morDs, null);
}
public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs, String diskController) throws Exception {
if(s_logger.isTraceEnabled())
@ -1262,24 +1278,20 @@ public class VirtualMachineMO extends BaseMO {
controllerKey = getIDEControllerKey(ideDeviceCount);
unitNumber = getFreeUnitNumberOnIDEController(controllerKey);
} else {
controllerKey = getScsiDiskControllerKey(diskController);
if (StringUtils.isNotBlank(diskController)) {
controllerKey = getScsiDiskControllerKey(diskController);
} else {
controllerKey = getScsiDeviceControllerKey();
}
unitNumber = -1;
}
synchronized (_mor.getValue().intern()) {
VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, null, controllerKey, vmdkDatastorePathChain, morDs, unitNumber, 1);
controllerKey = newDisk.getControllerKey();
unitNumber = newDisk.getUnitNumber();
VirtualDiskFlatVer2BackingInfo backingInfo = (VirtualDiskFlatVer2BackingInfo)newDisk.getBacking();
String vmdkFileName = backingInfo.getFileName();
DiskControllerType diskControllerType = DiskControllerType.getType(diskController);
VmdkAdapterType vmdkAdapterType = VmdkAdapterType.getAdapterType(diskControllerType);
if (vmdkAdapterType == VmdkAdapterType.none) {
String message = "Failed to attach disk due to invalid vmdk adapter type for vmdk file [" +
vmdkFileName + "] with controller : " + diskControllerType;
s_logger.debug(message);
throw new Exception(message);
if (StringUtils.isNotBlank(diskController)) {
String vmdkFileName = vmdkDatastorePathChain[0];
updateVmdkAdapter(vmdkFileName, diskController);
}
updateVmdkAdapter(vmdkFileName, vmdkAdapterType.toString());
VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
@ -1319,69 +1331,6 @@ public class VirtualMachineMO extends BaseMO {
}
public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs) throws Exception {
if (s_logger.isTraceEnabled())
s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + new Gson().toJson(vmdkDatastorePathChain) +
", datastore: " + morDs.getValue());
synchronized (_mor.getValue().intern()) {
VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, null, getScsiDeviceControllerKey(), vmdkDatastorePathChain, morDs, -1, 1);
VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
deviceConfigSpec.setDevice(newDisk);
deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
reConfigSpec.getDeviceChange().add(deviceConfigSpec);
ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
boolean result = _context.getVimClient().waitForTask(morTask);
if (!result) {
if (s_logger.isTraceEnabled())
s_logger.trace("vCenter API trace - attachDisk() done(failed)");
throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask));
}
_context.waitForTaskProgressDone(morTask);
}
if (s_logger.isTraceEnabled())
s_logger.trace("vCenter API trace - attachDisk() done(successfully)");
}
public void attachDisk(Pair<String, ManagedObjectReference>[] vmdkDatastorePathChain, int controllerKey) throws Exception {
if (s_logger.isTraceEnabled())
s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + new Gson().toJson(vmdkDatastorePathChain));
synchronized (_mor.getValue().intern()) {
VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, controllerKey, vmdkDatastorePathChain, -1, 1);
VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
deviceConfigSpec.setDevice(newDisk);
deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
reConfigSpec.getDeviceChange().add(deviceConfigSpec);
ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
boolean result = _context.getVimClient().waitForTask(morTask);
if (!result) {
if (s_logger.isTraceEnabled())
s_logger.trace("vCenter API trace - attachDisk() done(failed)");
throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask));
}
_context.waitForTaskProgressDone(morTask);
}
if (s_logger.isTraceEnabled())
s_logger.trace("vCenter API trace - attachDisk() done(successfully)");
}
// vmdkDatastorePath: [datastore name] vmdkFilePath
public List<Pair<String, ManagedObjectReference>> detachDisk(String vmdkDatastorePath, boolean deleteBackingFile) throws Exception {
@ -2489,7 +2438,7 @@ public class VirtualMachineMO extends BaseMO {
s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering);
if (((VirtualDisk) device).getVDiskId() == null) {
s_logger.debug("vDiskid does not exist for volume " + vmdkDatastorePath + " registering the disk now");
VirtualStorageObjectManager vStorageObjectManagerMO = new VirtualStorageObjectManager(getOwnerDatacenter().first().getContext());
VirtualStorageObjectManagerMO vStorageObjectManagerMO = new VirtualStorageObjectManagerMO(getOwnerDatacenter().first().getContext());
VStorageObject vStorageObject = vStorageObjectManagerMO.registerVirtualDisk(dsBackingFile, null, getOwnerDatacenter().first().getName());
VStorageObjectConfigInfo diskConfigInfo = vStorageObject.getConfig();
((VirtualDisk) device).setVDiskId(diskConfigInfo.getId());

View File

@ -1,58 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.hypervisor.vmware.mo;
import com.vmware.vim25.ID;
import com.vmware.vim25.VStorageObject;
import org.apache.log4j.Logger;
import com.vmware.vim25.ManagedObjectReference;
import com.cloud.hypervisor.vmware.util.VmwareContext;
public class VirtualStorageObjectManager extends BaseMO {
@SuppressWarnings("unused")
private static final Logger s_logger = Logger.getLogger(VirtualStorageObjectManager.class);
public VirtualStorageObjectManager(VmwareContext context) {
super(context, context.getServiceContent().getVStorageObjectManager());
}
public VirtualStorageObjectManager(VmwareContext context, ManagedObjectReference morDiskMgr) {
super(context, morDiskMgr);
}
public VirtualStorageObjectManager(VmwareContext context, String morType, String morValue) {
super(context, morType, morValue);
}
public VStorageObject registerVirtualDisk(DatastoreFile datastoreFile, String name, String dcName) throws Exception {
StringBuilder sb = new StringBuilder();
//https://10.2.2.254/folder/i-2-4-VM/89e3756d9b7444dc92388eb36ddd026b.vmdk?dcPath=datacenter-21&dsName=c84e4af9b6ac33e887a25d9242650091
sb.append("https://").append(_context.getServerAddress()).append("/folder/");
sb.append(datastoreFile.getRelativePath());
sb.append("?dcPath=");
sb.append(dcName);
sb.append("&dsName=");
sb.append(datastoreFile.getDatastoreName());
return _context.getService().registerDisk(_mor, sb.toString(), name);
}
public VStorageObject retrieveVirtualDisk (ID id, ManagedObjectReference morDS) throws Exception {
return _context.getService().retrieveVStorageObject(_mor, id, morDS);
}
}

View File

@ -0,0 +1,94 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.hypervisor.vmware.mo;
import com.vmware.vim25.ID;
import com.vmware.vim25.TaskInfo;
import com.vmware.vim25.VStorageObject;
import com.vmware.vim25.VirtualDiskType;
import com.vmware.vim25.VslmCreateSpec;
import com.vmware.vim25.VslmCreateSpecDiskFileBackingSpec;
import org.apache.log4j.Logger;
import com.vmware.vim25.ManagedObjectReference;
import com.cloud.hypervisor.vmware.util.VmwareContext;
public class VirtualStorageObjectManagerMO extends BaseMO {
@SuppressWarnings("unused")
private static final Logger s_logger = Logger.getLogger(VirtualStorageObjectManagerMO.class);
public VirtualStorageObjectManagerMO(VmwareContext context) {
super(context, context.getServiceContent().getVStorageObjectManager());
}
public VirtualStorageObjectManagerMO(VmwareContext context, ManagedObjectReference morDiskMgr) {
super(context, morDiskMgr);
}
public VirtualStorageObjectManagerMO(VmwareContext context, String morType, String morValue) {
super(context, morType, morValue);
}
public VStorageObject registerVirtualDisk(DatastoreFile datastoreFile, String name, String dcName) throws Exception {
StringBuilder sb = new StringBuilder();
//https://10.2.2.254/folder/i-2-4-VM/89e3756d9b7444dc92388eb36ddd026b.vmdk?dcPath=datacenter-21&dsName=c84e4af9b6ac33e887a25d9242650091
sb.append("https://").append(_context.getServerAddress()).append("/folder/");
sb.append(datastoreFile.getRelativePath());
sb.append("?dcPath=");
sb.append(dcName);
sb.append("&dsName=");
sb.append(datastoreFile.getDatastoreName());
return _context.getService().registerDisk(_mor, sb.toString(), name);
}
public VStorageObject retrieveVirtualDisk (ID id, ManagedObjectReference morDS) throws Exception {
return _context.getService().retrieveVStorageObject(_mor, id, morDS);
}
public VStorageObject createDisk(ManagedObjectReference morDS, VirtualDiskType diskType, long currentSizeInBytes, String datastoreFilepath, String filename) throws Exception {
long currentSizeInMB = currentSizeInBytes/(1024*1024);
VslmCreateSpecDiskFileBackingSpec diskFileBackingSpec = new VslmCreateSpecDiskFileBackingSpec();
diskFileBackingSpec.setDatastore(morDS);
diskFileBackingSpec.setProvisioningType(diskType.value());
// path should be just the folder name. For example, instead of '[datastore1] folder1/filename.vmdk' you would just do 'folder1'.
// path is introduced from 6.7. In 6.5 disk will be created in the default folder "fcd"
diskFileBackingSpec.setPath(null);
VslmCreateSpec vslmCreateSpec = new VslmCreateSpec();
vslmCreateSpec.setBackingSpec(diskFileBackingSpec);
vslmCreateSpec.setCapacityInMB(currentSizeInMB);
vslmCreateSpec.setName(filename);
ManagedObjectReference morTask = _context.getService().createDiskTask(_mor, vslmCreateSpec);
boolean result = _context.getVimClient().waitForTask(morTask);
VStorageObject vStorageObject = null;
if (result) {
_context.waitForTaskProgressDone(morTask);
//_context.getService().reconcileDatastoreInventoryTask(_mor, morDS);
TaskInfo taskInfo = TaskMO.getTaskInfo(_context, morTask);
vStorageObject = (VStorageObject)taskInfo.getResult();
} else {
s_logger.error("VMware CreateDisk_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
}
return vStorageObject;
}
}

View File

@ -212,35 +212,49 @@ public class VmwareHelper {
}
// vmdkDatastorePath: [datastore name] vmdkFilePath
public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, int controllerKey, String vmdkDatastorePath, int sizeInMb, ManagedObjectReference morDs,
int deviceNumber, int contextNumber) throws Exception {
public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, VirtualDisk device, int controllerKey, String vmdkDatastorePathChain[],
ManagedObjectReference morDs, int deviceNumber, int contextNumber) throws Exception {
VirtualDisk disk = new VirtualDisk();
assert (vmdkDatastorePathChain != null);
assert (vmdkDatastorePathChain.length >= 1);
VirtualDiskFlatVer2BackingInfo backingInfo = new VirtualDiskFlatVer2BackingInfo();
backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value());
backingInfo.setThinProvisioned(true);
backingInfo.setEagerlyScrub(false);
backingInfo.setDatastore(morDs);
backingInfo.setFileName(vmdkDatastorePath);
disk.setBacking(backingInfo);
VirtualDisk disk;
VirtualDiskFlatVer2BackingInfo backingInfo;
if (device != null) {
disk = device;
backingInfo = (VirtualDiskFlatVer2BackingInfo)disk.getBacking();
} else {
disk = new VirtualDisk();
backingInfo = new VirtualDiskFlatVer2BackingInfo();
backingInfo.setDatastore(morDs);
backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value());
disk.setBacking(backingInfo);
int ideControllerKey = vmMo.getIDEDeviceControllerKey();
if (controllerKey < 0)
controllerKey = ideControllerKey;
if (deviceNumber < 0) {
deviceNumber = vmMo.getNextDeviceNumber(controllerKey);
int ideControllerKey = vmMo.getIDEDeviceControllerKey();
if (controllerKey < 0)
controllerKey = ideControllerKey;
if (deviceNumber < 0) {
deviceNumber = vmMo.getNextDeviceNumber(controllerKey);
}
disk.setControllerKey(controllerKey);
disk.setKey(-contextNumber);
disk.setUnitNumber(deviceNumber);
VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo();
connectInfo.setConnected(true);
connectInfo.setStartConnected(true);
disk.setConnectable(connectInfo);
}
disk.setControllerKey(controllerKey);
disk.setKey(-contextNumber);
disk.setUnitNumber(deviceNumber);
disk.setCapacityInKB(sizeInMb * 1024);
backingInfo.setFileName(vmdkDatastorePathChain[0]);
if (vmdkDatastorePathChain.length > 1) {
String[] parentDisks = new String[vmdkDatastorePathChain.length - 1];
for (int i = 0; i < vmdkDatastorePathChain.length - 1; i++)
parentDisks[i] = vmdkDatastorePathChain[i + 1];
VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo();
connectInfo.setConnected(true);
connectInfo.setStartConnected(true);
disk.setConnectable(connectInfo);
setParentBackingInfo(backingInfo, morDs, parentDisks);
}
return disk;
}
@ -314,96 +328,6 @@ public class VmwareHelper {
return disk;
}
// vmdkDatastorePath: [datastore name] vmdkFilePath
public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, VirtualDisk device, int controllerKey, String vmdkDatastorePathChain[],
ManagedObjectReference morDs, int deviceNumber, int contextNumber) throws Exception {
assert (vmdkDatastorePathChain != null);
assert (vmdkDatastorePathChain.length >= 1);
VirtualDisk disk;
VirtualDiskFlatVer2BackingInfo backingInfo;
if (device != null) {
disk = device;
backingInfo = (VirtualDiskFlatVer2BackingInfo)disk.getBacking();
} else {
disk = new VirtualDisk();
backingInfo = new VirtualDiskFlatVer2BackingInfo();
backingInfo.setDatastore(morDs);
backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value());
disk.setBacking(backingInfo);
int ideControllerKey = vmMo.getIDEDeviceControllerKey();
if (controllerKey < 0)
controllerKey = ideControllerKey;
if (deviceNumber < 0) {
deviceNumber = vmMo.getNextDeviceNumber(controllerKey);
}
disk.setControllerKey(controllerKey);
disk.setKey(-contextNumber);
disk.setUnitNumber(deviceNumber);
VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo();
connectInfo.setConnected(true);
connectInfo.setStartConnected(true);
disk.setConnectable(connectInfo);
}
backingInfo.setFileName(vmdkDatastorePathChain[0]);
if (vmdkDatastorePathChain.length > 1) {
String[] parentDisks = new String[vmdkDatastorePathChain.length - 1];
for (int i = 0; i < vmdkDatastorePathChain.length - 1; i++)
parentDisks[i] = vmdkDatastorePathChain[i + 1];
setParentBackingInfo(backingInfo, morDs, parentDisks);
}
return disk;
}
@SuppressWarnings("unchecked")
public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, int controllerKey, Pair<String, ManagedObjectReference>[] vmdkDatastorePathChain,
int deviceNumber, int contextNumber) throws Exception {
assert (vmdkDatastorePathChain != null);
assert (vmdkDatastorePathChain.length >= 1);
VirtualDisk disk = new VirtualDisk();
VirtualDiskFlatVer2BackingInfo backingInfo = new VirtualDiskFlatVer2BackingInfo();
backingInfo.setDatastore(vmdkDatastorePathChain[0].second());
backingInfo.setFileName(vmdkDatastorePathChain[0].first());
backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value());
if (vmdkDatastorePathChain.length > 1) {
Pair<String, ManagedObjectReference>[] parentDisks = new Pair[vmdkDatastorePathChain.length - 1];
for (int i = 0; i < vmdkDatastorePathChain.length - 1; i++)
parentDisks[i] = vmdkDatastorePathChain[i + 1];
setParentBackingInfo(backingInfo, parentDisks);
}
disk.setBacking(backingInfo);
int ideControllerKey = vmMo.getIDEDeviceControllerKey();
if (controllerKey < 0)
controllerKey = ideControllerKey;
if (deviceNumber < 0) {
deviceNumber = vmMo.getNextDeviceNumber(controllerKey);
}
disk.setControllerKey(controllerKey);
disk.setKey(-contextNumber);
disk.setUnitNumber(deviceNumber);
VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo();
connectInfo.setConnected(true);
connectInfo.setStartConnected(true);
disk.setConnectable(connectInfo);
return disk;
}
private static void setParentBackingInfo(VirtualDiskFlatVer2BackingInfo backingInfo, ManagedObjectReference morDs, String[] parentDatastorePathList) {
VirtualDiskFlatVer2BackingInfo parentBacking = new VirtualDiskFlatVer2BackingInfo();