2013년 3월 6일 수요일

VMware: Lable of VirtualDevice only accept alphabetical characters, If not, got InvalidRequest error


vSphere API threw InvalidRequest error while I was trying to add a networkadapter of a VM.

com.vmware.vim25.InvalidRequest
at com.vmware.vim25.mo.VirtualMachine.reconfigVM_Task...

My code was following:
...
...
// Network Connection name
String[] network_name =  {"VM Network"};

// Get the existing network devices of the VM
List<VirtualDevice> listNetworkDevice = new ArrayList<VirtualDevice>();

for (VirtualDevice vDevice: vm.getConfig().getHardware().getDevice()) {
  if (vDevice.getDeviceInfo().getLabel().toLowerCase().indexOf("network") >= 0 || vDevice.getDeviceInfo().getLabel().indexOf("네트워크") >= 0)
    listNetworkDevice.add(vDevice);

}

// Get the label of network device 
String listNicLabel[] = listNetworkDevice.get(listNetworkDevice.size() - 1).getDeviceInfo().getLabel().split(" ");

int seqOfNIC = 0;
try {
  if( listNicLabel != null && listNicLabel.length >= 2)
    seqOfNIC = Integer.parseInt(listNicLabel[2]);                                                   
} catch (Exception e) {
    listNicLabel = new String[] { "Network", "Adapter" };
}

// Unique key that distinguish the device from other devices in the same VM. Here, it is just a temporary value
int nicKeyVal = 0;

for (int i = 0; i < customServerInfo.getNetworkBridgeName().length; i++) {                                 
             
  VirtualEthernetCard nic = new  VirtualVmxnet3();
  VirtualEthernetCardNetworkBackingInfo nicBacking = new VirtualEthernetCardNetworkBackingInfo();
  nicBacking.setDeviceName(customServerInfo.getNetworkBridgeName()[i]); // Network Connection
                
  String nicLabel = listNicLabel[0] + " " + listNicLabel[1] + " " + (++seqOfNIC);   
  
  Description info = new Description();
  info.setLabel(nicLabel);
  info.setSummary(customServerInfo.getNetworkBridgeName()[i]); 
  nic.setDeviceInfo(info);
                                  
  // type: "generated", "manual", "assigned" by VC
  nic.setAddressType("generated");
  nic.setBacking(nicBacking);
  nic.setKey(-1 * (4000 + (nicKeyVal++)));      
    
  VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
  deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
  deviceConfigSpec.setDevice(nic);
    
  listDeviceConfigSpec.add(deviceConfigSpec);
            
}

if (listDeviceConfigSpec.size() > 0) {
  vmSpec.setDeviceChange(listDeviceConfigSpec.toArray(new VirtualDeviceConfigSpec[listDeviceConfigSpec.size()]));

  Task task = vm.reconfigVM_Task(vmSpec);
  ...
  ...
}

In my above coding, I got the last label from the existing NetworkAdapter in line 21. (My VM already had two networks) and replaced the last sequence number with new one in line 35.
e.g.)
<<The last seq and name>>    <<The new seq and name>>
Network Adapter 2        =>      Network Adapter 3

However, Labels of vDevices were displayed in the language which you chose one when you installed vCenter. I installed it with Korean language, so I actually got the result of labels, for example, 네트워크 어댑터 1, 네트워크 어댑터 2 (They both mean "Network Adapter").

In Label property of Description class in vSphere API, it doesn't accept characters other than Alphabetical(and number).
So, You should change it with alphabetical characters for Label property. I changed this like:
String nicLabel = "Network Adapter" + " " + (++seqOfNIC);

Description info = new Description();
info.setLabel(nicLabel);
...
When you get InvalidRequest error for VM Creation / Reconfig job and you try to debug it, it can be one of good solutions that you comment all of setter methods except for mandatory and then uncomment one setter method per testing, after that you can find where it is wrong in your code. It seems not to have easy solution about solvoing InvalidRequest error.


References:
1. http://www.jarvana.com/jarvana/view/org/jvnet/hudson/vijava/2120100824/vijava-2120100824-sources.jar!/com/vmware/vim25/mo/samples/vm/CreateVM.java

댓글 없음:

댓글 쓰기