Beispiel #1
0
  /**
   * 创建虚拟机的配置信息
   *
   * @param ecb
   * @param dcMor
   * @param haMor
   * @param name
   * @param descr
   * @param guestId
   * @param numCpus
   * @param numCores
   * @param memoryMB
   * @param dsMor
   * @param diskSizeMB
   * @return
   * @throws Exception
   */
  private static VirtualMachineConfigSpec createVmConfigSpec(
      ExtendedAppUtil ecb,
      ManagedObjectReference dcMor,
      ManagedObjectReference haMor,
      String name,
      String descr,
      String guestId,
      int numCpus,
      int numCores,
      long memoryMB,
      ManagedObjectReference dsMor,
      long diskSizeMB)
      throws Exception {

    // http://pubs.vmware.com/vsphere-50/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc_50%2Fvim.VirtualDiskManager.VirtualDiskType.html
    // 厚置备延迟置零 (zeroed thick) //默认选项
    // thick=zeroedthick
    // 厚置备置零 (eager zeroed thick),创建的时候特别的长。
    // eagerZeroedThick
    // 精简置备 (thin)
    // thin
    // 厚置备延迟置零:以默认的厚格式创建虚拟磁盘。创建过程中为虚拟磁盘分配所需空间。创建时不会擦除物理设备上保留的任何数据,但是以后从虚拟机首次执行写操作时会按需要将其置零。
    // 厚置备置零:创建支持群集功能(如 Fault
    // Tolerance)的厚磁盘。在创建时为虚拟磁盘分配所需的空间。与平面格式相反,在创建过程中会将物理设备上保留的数据置零。创建这种格式的磁盘所需的时间可能会比创建其他类型的磁盘长。
    // 精简置备:使用精简置备格式。最初,精简置备的磁盘只使用该磁盘最初所需要的数据存储空间。如果以后精简磁盘需要更多空间,则它可以增长到为其分配的最大容量。

    // 0-thick和1-eagerZeroedThick区别:0-thick的getEagerlyScrub=null;1-eagerZeroedThick的getEagerlyScrub=true
    // 0-thick和2-thin区别:0-thick的getThinProvisioned=false;2-thin的getThinProvisioned=true
    // 1-eagerZeroedThickh和2-thin区别:1-eagerZeroedThickh的getEagerlyScrub=true,getThinProvisioned=false;2-thin的getEagerlyScrub=null,getThinProvisioned=true

    String diskType = DISKTYPE_THICK;

    VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();

    // 名称
    vmConfig.setName(name);
    // 备注
    vmConfig.setAnnotation(descr);
    // 操作系统id
    // http://pubs.vmware.com/vsphere-50/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc_50%2Fvim.vm.GuestOsDescriptor.GuestOsIdentifier.html
    vmConfig.setGuestId(guestId);
    // CPU
    vmConfig.setNumCPUs(numCpus);
    vmConfig.setNumCoresPerSocket(numCores);
    // 内存
    vmConfig.setMemoryMB(memoryMB);

    // 虚拟机的所有的设备,如磁盘,光驱,软盘等
    VirtualDeviceConfigSpec[] deviceConfigs = new VirtualDeviceConfigSpec[4];
    vmConfig.setDeviceChange(deviceConfigs);

    // SCSI控制器
    // --getBusNumber=0
    // --getScsiCtlrUnitNumber=7
    // --getHotAddRemove=true
    // --getSharedBus=noSharing
    // --getKey=1000
    // --getControllerKey=100
    // --getUnitNumber=3
    // --getBacking=null
    // --getConnectable=null

    VirtualDeviceConfigSpec scsiConfig = new VirtualDeviceConfigSpec();
    deviceConfigs[0] = scsiConfig;
    scsiConfig.setOperation(VirtualDeviceConfigSpecOperation.add);
    VirtualLsiLogicController scsiCtrl = new VirtualLsiLogicController();
    scsiConfig.setDevice(scsiCtrl);
    scsiCtrl.setBusNumber(0);
    int scsiCtlrKey = 20;
    scsiCtrl.setKey(scsiCtlrKey);
    // 样例代码中是VirtualSCSISharing.physicalSharing
    // scsiCtrl.setSharedBus(VirtualSCSISharing.physicalSharing);
    scsiCtrl.setSharedBus(VirtualSCSISharing.noSharing);
    // 样例代码中未设置ScsiCtlrUnitNumber和HotAddRemove

    // 磁盘
    DatastoreSummary dsSummary =
        (DatastoreSummary) ecb.getServiceUtil3().getDynamicProperty(dsMor, DYNAMICPROPERTY_SUMMARY);
    String dsName = "";
    if (dsSummary != null) {
      dsName = dsSummary.getName();
    }

    VirtualDeviceConfigSpec diskConfig = new VirtualDeviceConfigSpec();
    deviceConfigs[1] = diskConfig;
    diskConfig.setFileOperation(VirtualDeviceConfigSpecFileOperation.create);
    diskConfig.setOperation(VirtualDeviceConfigSpecOperation.add);

    // ----------------------com.vmware.vim25.VirtualDisk
    // --getCapacityInKB=16777216
    // [email protected]
    // ----getShares=1000
    // ----getLevel=normal
    // --[email protected]c206c0d1
    // ----getLimit=-1
    // [email protected]
    // ------getShares=1000
    // ------getLevel=normal
    // ----------------------
    // --getKey=2000
    // --getControllerKey=1000
    // --getUnitNumber=0
    // [email protected]a9802
    // ----getChangeId=null
    // ----getContentId=f03ee93a387f3ed891df36b1fffffffe
    // ----getDatastore=datastore-13
    // ----getDeltaDiskFormat=null
    // ----getDiskMode=persistent
    // ----getDynamicType=null
    // ----getFileName=[datastore1] testOPs/testOPs.vmdk
    // ----getUuid=6000C294-dedc-b5e9-e681-131218cd2db4
    // ----getDigestEnabled=false
    // ----getEagerlyScrub=null
    // ----getParent=null
    // ----getSplit=false
    // ----getThinProvisioned=false
    // ----getWriteThrough=false
    // --getConnectable=null
    VirtualDisk disk = new VirtualDisk();
    diskConfig.setDevice(disk);

    disk.setControllerKey(scsiCtlrKey);
    disk.setUnitNumber(0);
    // disk.setKey(0);
    disk.setKey(30);

    disk.setCapacityInKB(diskSizeMB * 1024);

    // http://pubs.vmware.com/vsphere-50/topic/com.vmware.wssdk.apiref.doc_50/vim.vm.device.VirtualDisk.FlatVer2BackingInfo.html
    VirtualDiskFlatVer2BackingInfo backingInfo = new VirtualDiskFlatVer2BackingInfo();
    disk.setBacking(backingInfo);
    // ===============================================================================
    // http://pubs.vmware.com/vsphere-50/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc_50%2Fvim.vm.device.VirtualDiskOption.DiskMode.html
    // The "persistent" mode is supported by every backing type.
    backingInfo.setDiskMode(DISKMODE_PERSISTENT);

    // 0-thick和1-eagerZeroedThick区别:0-thick的getEagerlyScrub=null;1-eagerZeroedThick的getEagerlyScrub=true
    // 0-thick和2-thin区别:0-thick的getThinProvisioned=false;2-thin的getThinProvisioned=true
    // 1-eagerZeroedThickh和2-thin区别:1-eagerZeroedThickh的getEagerlyScrub=true,getThinProvisioned=false;2-thin的getEagerlyScrub=null,getThinProvisioned=true

    // diskType= thick | eagerZeroedThick | thin
    if (diskType.equalsIgnoreCase(DISKTYPE_THIN)) {
      backingInfo.setThinProvisioned(true);
    } else {
      backingInfo.setThinProvisioned(false);
    }
    if (diskType.equalsIgnoreCase(DISKTYPE_EAGERZEROEDTHINK)) {
      backingInfo.setEagerlyScrub(true);
    } else {
      backingInfo.setEagerlyScrub(false);
    }
    backingInfo.setDatastore(dsMor);
    backingInfo.setFileName("");

    // 网络
    VirtualDeviceConfigSpec nicConfig = new VirtualDeviceConfigSpec();
    deviceConfigs[2] = nicConfig;
    nicConfig.setOperation(VirtualDeviceConfigSpecOperation.add);
    VirtualEthernetCard ethCard = new VirtualPCNet32();
    nicConfig.setDevice(ethCard);
    ethCard.setAddressType(ETHERNETCARD_ADDRESSTYPE_GENERATED);
    ethCard.setKey(40);
    VirtualEthernetCardNetworkBackingInfo ethBacking = new VirtualEthernetCardNetworkBackingInfo();
    ethCard.setBacking(ethBacking);
    ethBacking.setDeviceName(ETHERNETCARD_DEFAULT_NAME);

    // 新建IDE设备,出现错误:设备“4”正在引用不存在的控制器“50”。
    // int ideCtrlKey = 50;
    // int ideBusNumber = 3;
    // VirtualDeviceConfigSpec ideConfig = new VirtualDeviceConfigSpec();
    // deviceConfigs[3] = ideConfig;
    // VirtualIDEController ideCtrl = new VirtualIDEController();
    // ideConfig.setDevice(ideCtrl);
    // ideConfig.setOperation(VirtualDeviceConfigSpecOperation.add);
    // ideCtrl.setKey(ideCtrlKey);
    // ideCtrl.setBusNumber(ideBusNumber);

    // 光驱
    VirtualDeviceConfigSpec cdRomConfig = new VirtualDeviceConfigSpec();
    deviceConfigs[3] = cdRomConfig;
    VirtualCdrom cdRom = new VirtualCdrom();
    cdRomConfig.setDevice(cdRom);
    cdRomConfig.setOperation(VirtualDeviceConfigSpecOperation.add);

    // backing_备份,可以不设置VirtualCdromRemotePassthroughBackingInfo
    // // ----getDeviceName=
    // // ----getUseAutoDetect=false
    // // ----isExclusive=false
    VirtualCdromRemotePassthroughBackingInfo vcrpb = new VirtualCdromRemotePassthroughBackingInfo();
    vcrpb.setDeviceName("");
    vcrpb.setExclusive(false);
    vcrpb.setUseAutoDetect(false);
    cdRom.setBacking(vcrpb);

    // connectable_连接
    // ----getStatus=untried
    // ----isAllowGuestControl=true
    // ----isConnected=false
    // ----isStartConnected=false
    VirtualDeviceConnectInfo cdRomConnect = new VirtualDeviceConnectInfo();
    cdRom.setConnectable(cdRomConnect);
    // cdRomConnect.setStatus(arg0);
    cdRomConnect.setAllowGuestControl(true);
    cdRomConnect.setConnected(false);
    cdRomConnect.setStartConnected(false);

    // deviceInfo_设备信息,不设置

    int cdRomUnitNumber = 0;

    // 使用查找的IDE驱动器出现错误:为设备“3”指定了不兼容的设备备用。
    // controllerKey_控制器ID
    // key_设备ID
    // unitNumber_控制器上的连接设备数
    int ideCtrlKey = -1;

    // 寻找IDE驱动器
    ManagedObjectReference envBrowseMor =
        ecb.getServiceUtil3().getMoRefProp(haMor, DYNAMICPROPERTY_ENVIRONMENTBROWSER);
    VirtualMachineConfigOption cfgOpt =
        ecb.getServiceConnection3().getService().queryConfigOption(envBrowseMor, null, null);
    VirtualDevice[] defaultDevices = cfgOpt.getDefaultDevice();
    for (int i = 0; i < defaultDevices.length; i++) {
      VirtualDevice device = defaultDevices[i];
      if (device instanceof VirtualIDEController) {
        ideCtrlKey = device.getKey();
        int[] dArr = ((VirtualIDEController) device).getDevice();
        if (dArr != null) {
          cdRomUnitNumber = dArr.length + 1;
          for (int k = 0; k < dArr.length; k++) {
            if (cdRomUnitNumber <= dArr[k]) {
              cdRomUnitNumber = dArr[k] + 1;
            }
          }
        } else {
          cdRomUnitNumber = 0;
        }
        i = defaultDevices.length + 1;
      }
    }
    cdRom.setControllerKey(ideCtrlKey);
    cdRom.setUnitNumber(cdRomUnitNumber);
    // cdRom.setKey(cdRomKey);
    cdRom.setKey(60);

    // 文件
    VirtualMachineFileInfo vmfi = new VirtualMachineFileInfo();
    // VmPathName=[datastore1] testOPs/testOPs.vmx
    vmfi.setVmPathName("[" + dsName + "]");
    vmConfig.setFiles(vmfi);

    return vmConfig;
  }
  /**
   * Creates the vm config spec object.
   *
   * @param vmName the vm name
   * @param datastoreName the datastore name
   * @param diskSizeMB the disk size in mb
   * @param computeResMor the compute res moref
   * @param hostMor the host mor
   * @return the virtual machine config spec object
   * @throws Exception the exception
   */
  VirtualMachineConfigSpec createVmConfigSpec(
      String vmName,
      String datastoreName,
      int diskSizeMB,
      ManagedObjectReference computeResMor,
      ManagedObjectReference hostMor)
      throws RuntimeFaultFaultMsg, InvalidPropertyFaultMsg {

    ConfigTarget configTarget = getConfigTargetForHost(computeResMor, hostMor);
    List<VirtualDevice> defaultDevices = getDefaultDevices(computeResMor, hostMor);
    VirtualMachineConfigSpec configSpec = new VirtualMachineConfigSpec();
    String networkName = null;
    if (configTarget.getNetwork() != null) {
      for (int i = 0; i < configTarget.getNetwork().size(); i++) {
        VirtualMachineNetworkInfo netInfo = configTarget.getNetwork().get(i);
        NetworkSummary netSummary = netInfo.getNetwork();
        if (netSummary.isAccessible()) {
          networkName = netSummary.getName();
          break;
        }
      }
    }
    ManagedObjectReference datastoreRef = null;
    if (datastoreName != null) {
      boolean flag = false;
      for (int i = 0; i < configTarget.getDatastore().size(); i++) {
        VirtualMachineDatastoreInfo vdsInfo = configTarget.getDatastore().get(i);
        DatastoreSummary dsSummary = vdsInfo.getDatastore();
        if (dsSummary.getName().equals(datastoreName)) {
          flag = true;
          if (dsSummary.isAccessible()) {
            datastoreRef = dsSummary.getDatastore();
          } else {
            throw new RuntimeException("Specified Datastore is not accessible");
          }
          break;
        }
      }
      if (!flag) {
        throw new RuntimeException("Specified Datastore is not Found");
      }
    } else {
      boolean flag = false;
      for (int i = 0; i < configTarget.getDatastore().size(); i++) {
        VirtualMachineDatastoreInfo vdsInfo = configTarget.getDatastore().get(i);
        DatastoreSummary dsSummary = vdsInfo.getDatastore();
        if (dsSummary.isAccessible()) {
          datastoreName = dsSummary.getName();
          datastoreRef = dsSummary.getDatastore();
          flag = true;
          break;
        }
      }
      if (!flag) {
        throw new RuntimeException("No Datastore found on host");
      }
    }
    String datastoreVolume = getVolumeName(datastoreName);
    VirtualMachineFileInfo vmfi = new VirtualMachineFileInfo();
    vmfi.setVmPathName(datastoreVolume);
    configSpec.setFiles(vmfi);
    // Add a scsi controller
    int diskCtlrKey = 1;
    VirtualDeviceConfigSpec scsiCtrlSpec = new VirtualDeviceConfigSpec();
    scsiCtrlSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
    VirtualLsiLogicController scsiCtrl = new VirtualLsiLogicController();
    scsiCtrl.setBusNumber(0);
    scsiCtrlSpec.setDevice(scsiCtrl);
    scsiCtrl.setKey(diskCtlrKey);
    scsiCtrl.setSharedBus(VirtualSCSISharing.NO_SHARING);
    String ctlrType = scsiCtrl.getClass().getName();
    ctlrType = ctlrType.substring(ctlrType.lastIndexOf(".") + 1);

    // Find the IDE controller
    VirtualDevice ideCtlr = null;
    for (int di = 0; di < defaultDevices.size(); di++) {
      if (defaultDevices.get(di) instanceof VirtualIDEController) {
        ideCtlr = defaultDevices.get(di);
        break;
      }
    }

    // Add a floppy
    VirtualDeviceConfigSpec floppySpec = new VirtualDeviceConfigSpec();
    floppySpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
    VirtualFloppy floppy = new VirtualFloppy();
    VirtualFloppyDeviceBackingInfo flpBacking = new VirtualFloppyDeviceBackingInfo();
    flpBacking.setDeviceName("/dev/fd0");
    floppy.setBacking(flpBacking);
    floppy.setKey(3);
    floppySpec.setDevice(floppy);

    // Add a cdrom based on a physical device
    VirtualDeviceConfigSpec cdSpec = null;

    if (ideCtlr != null) {
      cdSpec = new VirtualDeviceConfigSpec();
      cdSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
      VirtualCdrom cdrom = new VirtualCdrom();
      VirtualCdromIsoBackingInfo cdDeviceBacking = new VirtualCdromIsoBackingInfo();
      cdDeviceBacking.setDatastore(datastoreRef);
      cdDeviceBacking.setFileName(datastoreVolume + "testcd.iso");
      cdrom.setBacking(cdDeviceBacking);
      cdrom.setKey(20);
      cdrom.setControllerKey(new Integer(ideCtlr.getKey()));
      cdrom.setUnitNumber(new Integer(0));
      cdSpec.setDevice(cdrom);
    }

    // Create a new disk - file based - for the vm
    VirtualDeviceConfigSpec diskSpec = null;
    diskSpec = createVirtualDisk(datastoreName, diskCtlrKey, datastoreRef, diskSizeMB);

    // Add a NIC. the network Name must be set as the device name to create the NIC.
    VirtualDeviceConfigSpec nicSpec = new VirtualDeviceConfigSpec();
    if (networkName != null) {
      nicSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
      VirtualEthernetCard nic = new VirtualPCNet32();
      VirtualEthernetCardNetworkBackingInfo nicBacking =
          new VirtualEthernetCardNetworkBackingInfo();
      nicBacking.setDeviceName(networkName);
      nic.setAddressType("generated");
      nic.setBacking(nicBacking);
      nic.setKey(4);
      nicSpec.setDevice(nic);
    }

    List<VirtualDeviceConfigSpec> deviceConfigSpec = new ArrayList<VirtualDeviceConfigSpec>();
    deviceConfigSpec.add(scsiCtrlSpec);
    deviceConfigSpec.add(floppySpec);
    deviceConfigSpec.add(diskSpec);
    if (ideCtlr != null) {
      deviceConfigSpec.add(cdSpec);
      deviceConfigSpec.add(nicSpec);
    } else {
      deviceConfigSpec = new ArrayList<VirtualDeviceConfigSpec>();
      deviceConfigSpec.add(nicSpec);
    }
    configSpec.getDeviceChange().addAll(deviceConfigSpec);
    return configSpec;
  }