要解决的问题是:
在DataStore中有一块虚拟磁盘,如何将这块磁盘添加到其他的虚拟机上。
实际上是重新配置虚拟机的硬件资源,利用vSphere Management SDK的接口即可。
这里主要是给一个Demo,但是要注意一些限制:虚拟磁盘没有被占用。一般来说需要关闭这块虚拟磁盘所属的虚拟机,以此来解除占用。
/*
* ******************************************************
* Copyright VMware, Inc. 2010-2012. All Rights Reserved.
* ******************************************************
*
* DISCLAIMER. THIS PROGRAM IS PROVIDED TO YOU "AS IS" WITHOUT
* WARRANTIES OR CONDITIONS # OF ANY KIND, WHETHER ORAL OR WRITTEN,
* EXPRESS OR IMPLIED. THE AUTHOR SPECIFICALLY # DISCLAIMS ANY IMPLIED
* WARRANTIES OR CONDITIONS OF MERCHANTABILITY, SATISFACTORY # QUALITY,
* NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
*/
package com.vmware.general;
//import com.sun.org.glassfish.gmbal.ManagedObject;
import com.vmware.common.annotations.Action;
import com.vmware.common.annotations.Before;
import com.vmware.common.annotations.Option;
import com.vmware.common.annotations.Sample;
import com.vmware.connection.ConnectedVimServiceBase;
import com.vmware.vim25.*;
import javax.xml.ws.soap.SOAPFaultException;
import java.util.*;
/**
* <pre>
* VMDiskCreate
*
* This sample demonstrates how to create a virtual disk
*
* <b>Parameters:</b>
* url [required] : url of the web service
* username [required] : username for the authentication
* password [required] : password for the authentication
* vmname [required] : Name of the virtual machine
* datastorename [optional] : name of the DataStore
* disksize [required] : Size of the virtual disk in MB
* disktype [optional] : Virtual Disk Type
* [thin | preallocated | eagerzeroed | rdm | rdmp]
* persistence [optional] : Persistence mode of the virtual disk
* [persistent | independent_persistent | independent_nonpersistent]
* devicename [optional] : Canonical name of the LUN to use for disk types
*
* <b>Command Line:</b>
* VMDiskCreate --url [webserviceurl]
* --username [username] --password [password]
* --vmname [vmname] --disksize [8]
* --disktype [thin | preallocated | eagerzeroed | rdm | rdmp]
* --persistence [persistent | independent_persistent | independent_nonpersistent]
* --devicename vmhba0:0:0:0
* </pre>
*/
@Sample(
name = "test-mount",
description = "This sample demonstrates how to create a virtual disk"
)
public class TestMount extends ConnectedVimServiceBase {
private ManagedObjectReference dataStore;
String virtualMachineName = "testcentos";
private ManagedObjectReference propCollectorRef;
@Option(name = "vmname", required = false, description = "Name of the virtual machine")
public void setVirtualMachineName(String name) {
this.virtualMachineName = name;
}
boolean getTaskResultAfterDone(ManagedObjectReference task)
throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg,
InvalidCollectorVersionFaultMsg {
boolean retVal = false;
// info has a property - state for state of the task
Object[] result = waitForValues.wait(task, new String[]{"info.state",
"info.error"}, new String[]{"state"},
new Object[][]{new Object[]{TaskInfoState.SUCCESS,
TaskInfoState.ERROR}});
if (result[0].equals(TaskInfoState.SUCCESS)) {
retVal = true;
}
if (result[1] instanceof LocalizedMethodFault) {
throw new RuntimeException(((LocalizedMethodFault) result[1])
.getLocalizedMessage());
}
return retVal;
}
List<Integer> getControllerKey(ManagedObjectReference vmMor)
throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
List<Integer> retVal = new ArrayList<Integer>();
List<VirtualDevice> listvd = ((ArrayOfVirtualDevice) getMOREFs
.entityProps(vmMor, new String[] { "config.hardware.device" })
.get("config.hardware.device")).getVirtualDevice();
Map<Integer, VirtualDevice> deviceMap = new HashMap<Integer, VirtualDevice>();
for (VirtualDevice virtualDevice : listvd) {
deviceMap.put(virtualDevice.getKey(), virtualDevice);
}
boolean found = false;
for (VirtualDevice virtualDevice : listvd) {
if (virtualDevice instanceof VirtualSCSIController) {
VirtualSCSIController vscsic = (VirtualSCSIController) virtualDevice;
int[] slots = new int[16];
slots[7] = 1;
List<Integer> devicelist = vscsic.getDevice();
for (Integer deviceKey : devicelist) {
if (deviceMap.get(deviceKey).getUnitNumber() != null) {
slots[deviceMap.get(deviceKey).getUnitNumber()] = 1;
}
}
for (int i = 0; i < slots.length; i++) {
if (slots[i] != 1) {
retVal.add(vscsic.getKey());
retVal.add(i);
found = true;
break;
}
}
if (found) {
break;
}
}
}
if (!found) {
throw new RuntimeException(
"The SCSI controller on the vm has maxed out its "
+ "capacity. Please add an additional SCSI controller");
}
return retVal;
}
@Action
public void run() throws InvalidPropertyFaultMsg, DuplicateNameFaultMsg, RuntimeFaultFaultMsg, TaskInProgressFaultMsg,
VmConfigFaultFaultMsg, InsufficientResourcesFaultFaultMsg, InvalidDatastoreFaultMsg, FileFaultFaultMsg,
ConcurrentAccessFaultMsg, InvalidStateFaultMsg, InvalidNameFaultMsg, ToolsUnavailableFaultMsg,
InvalidCollectorVersionFaultMsg {
ManagedObjectReference propertycollector = connection.getServiceContent().getPropertyCollector();
// ManagedObjectReference redhatMor = getMOREFs.vmByVMname("Redhat", propertycollector);
ManagedObjectReference testcentosMor = getMOREFs.vmByVMname("testcentos", propertycollector);
VirtualDeviceConfigSpec virtualdiskconfigspec = new VirtualDeviceConfigSpec();
VirtualDisk tmpdisk = new VirtualDisk();
VirtualDiskFlatVer2BackingInfo diskfileBacking = new VirtualDiskFlatVer2BackingInfo();
int ckey = 0;
int unitNumber = 0;
List<Integer> getControllerKeyReturnArr = getControllerKey(testcentosMor);
if (!getControllerKeyReturnArr.isEmpty()) {
ckey = getControllerKeyReturnArr.get(0);
unitNumber = getControllerKeyReturnArr.get(1);
System.out.println("###WATCH ME###");
System.out.println("controllerKey is "+ckey);
System.out.println("unitNumber is "+unitNumber);
System.out.println("##############");
}
// String fileName = "[" + "datastore1" + "] " + "Redhat" + "/" + "Redhat" + ".vmdk";
String fileName = "[" + "datastore2" + "] " + "vcenter" + "/" + "centos6.5" + ".vmdk";
diskfileBacking.setFileName(fileName);
diskfileBacking.setDiskMode("persistent");
tmpdisk.setControllerKey(ckey);
tmpdisk.setUnitNumber(unitNumber);
tmpdisk.setBacking(diskfileBacking);
// tmpdisk.setCapacityInKB(4194304);
// tmpdisk.setKey(2001);
virtualdiskconfigspec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
// virtualdiskconfigspec.setFileOperation(VirtualDeviceConfigSpecFileOperation.CREATE);
virtualdiskconfigspec.setDevice(tmpdisk);
List<VirtualDeviceConfigSpec> alvdcs = new ArrayList<VirtualDeviceConfigSpec>();
alvdcs.add(virtualdiskconfigspec);
VirtualMachineConfigSpec vmcsreconfig = new VirtualMachineConfigSpec();
vmcsreconfig.getDeviceChange().addAll(alvdcs);
System.out.printf(" Reconfiguring the Virtual Machine - [ %s ]", virtualMachineName);
List<HostScsiDisk>tempdisks=new ArrayList<HostScsiDisk>();
ManagedObjectReference task = vimPort.reconfigVMTask(testcentosMor, vmcsreconfig);
if (getTaskResultAfterDone(task)) {
System.out.printf("\n Reconfiguring the Virtual Machine "
+ " - [ %s ] Successful", virtualMachineName);
} else {
System.out.printf(" Reconfiguring the Virtual Machine "
+ " - [ %s ] Failed", virtualMachineName);
}
//reboot the VM
System.out.println("reboot VM...");
vimPort.rebootGuest(testcentosMor);
System.out.println("config success");
}
}