Package com.vmware.aurora.vc

Source Code of com.vmware.aurora.vc.VmConfigUtil

/***************************************************************************
* Copyright (c) 2012-2013 VMware, Inc. All Rights Reserved.
* Licensed 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.vmware.aurora.vc;

import java.util.List;

import com.google.gson.Gson;
import com.vmware.aurora.global.Configuration;
import com.vmware.aurora.global.DiskSize;
import com.vmware.aurora.util.AuAssert;
import com.vmware.vim.binding.impl.vim.DescriptionImpl;
import com.vmware.vim.binding.impl.vim.ext.ManagedByInfoImpl;
import com.vmware.vim.binding.impl.vim.option.OptionValueImpl;
import com.vmware.vim.binding.impl.vim.vm.ConfigSpecImpl;
import com.vmware.vim.binding.impl.vim.vm.device.ParaVirtualSCSIControllerImpl;
import com.vmware.vim.binding.impl.vim.vm.device.VirtualBusLogicControllerImpl;
import com.vmware.vim.binding.impl.vim.vm.device.VirtualCdromImpl;
import com.vmware.vim.binding.impl.vim.vm.device.VirtualDeviceImpl;
import com.vmware.vim.binding.impl.vim.vm.device.VirtualDeviceSpecImpl;
import com.vmware.vim.binding.impl.vim.vm.device.VirtualDiskImpl;
import com.vmware.vim.binding.impl.vim.vm.device.VirtualE1000Impl;
import com.vmware.vim.binding.impl.vim.vm.device.VirtualEthernetCardImpl;
import com.vmware.vim.binding.impl.vim.vm.device.VirtualFloppyImpl;
import com.vmware.vim.binding.impl.vim.vm.device.VirtualLsiLogicControllerImpl;
import com.vmware.vim.binding.impl.vim.vm.device.VirtualLsiLogicSASControllerImpl;
import com.vmware.vim.binding.impl.vim.vm.device.VirtualSCSIControllerImpl;
import com.vmware.vim.binding.impl.vim.vm.device.VirtualVmxnet3Impl;
import com.vmware.vim.binding.impl.vim.vm.device.VirtualVmxnetImpl;
import com.vmware.vim.binding.vim.Description;
import com.vmware.vim.binding.vim.ext.ManagedByInfo;
import com.vmware.vim.binding.vim.option.OptionValue;
import com.vmware.vim.binding.vim.vm.ConfigSpec;
import com.vmware.vim.binding.vim.vm.device.ParaVirtualSCSIController;
import com.vmware.vim.binding.vim.vm.device.VirtualBusLogicController;
import com.vmware.vim.binding.vim.vm.device.VirtualController;
import com.vmware.vim.binding.vim.vm.device.VirtualDevice;
import com.vmware.vim.binding.vim.vm.device.VirtualDeviceSpec;
import com.vmware.vim.binding.vim.vm.device.VirtualDisk;
import com.vmware.vim.binding.vim.vm.device.VirtualDiskOption.DiskMode;
import com.vmware.vim.binding.vim.vm.device.VirtualEthernetCard;
import com.vmware.vim.binding.vim.vm.device.VirtualLsiLogicController;
import com.vmware.vim.binding.vim.vm.device.VirtualLsiLogicSASController;
import com.vmware.vim.binding.vim.vm.device.VirtualSCSIController;
import com.vmware.vim.binding.vim.vm.device.VirtualSCSIController.Sharing;


/**
* Utility functions for help configuring virtual machine.
*/
public class VmConfigUtil {
   public enum ScsiControllerType {
      PVSCSI(ParaVirtualSCSIController.class, ParaVirtualSCSIControllerImpl.class),
      LSILOGIC(VirtualLsiLogicController.class, VirtualLsiLogicControllerImpl.class),
      LSILOGICSAS(VirtualLsiLogicSASController.class, VirtualLsiLogicSASControllerImpl.class),
      BUSLOGIC(VirtualBusLogicController.class, VirtualBusLogicControllerImpl.class);

      public final Class<? extends VirtualSCSIController> infClass;
      public final Class<? extends VirtualSCSIControllerImpl> implClass;

      ScsiControllerType(Class<? extends VirtualSCSIController> infClass,
            Class<? extends VirtualSCSIControllerImpl> implClass) {
         this.infClass = infClass;
         this.implClass = implClass;
      }

      VirtualSCSIController createController() {
         try {
            return implClass.newInstance();
         } catch (Exception e) {
            AuAssert.INTERNAL(e);
            return null;
         }
      }

      public static ScsiControllerType findController(Class<? extends VirtualSCSIController> clazz) {
         for (ScsiControllerType type : ScsiControllerType.values()) {
            if (type.infClass == clazz) {
               return type;
            }
         }
         return null;
      }
   }

   public enum EthernetControllerType {
      E1000(VirtualE1000Impl.class), VMXNET(VirtualVmxnetImpl.class), VMXNET3(
            VirtualVmxnet3Impl.class);

      private final Class<? extends VirtualEthernetCardImpl> clazz;

      EthernetControllerType(Class<? extends VirtualEthernetCardImpl> clazz) {
         this.clazz = clazz;
      }

      VirtualEthernetCard createController() {
         try {
            return clazz.newInstance();
         } catch (Exception e) {
            AuAssert.INTERNAL(e);
            return null;
         }
      }
   }

   private static final String HOT_ADD_CPU_KEY = "vcpu.hotadd";
   private static final String HOT_ADD_MEMORY_KEY = "mem.hotadd";

   public static final String MACHINE_ID = "machine.id";
   public static final String DBVM_CONFIG = "dbvm.config";

   /**
    * Create a scsi controller device for a vm.
    *
    * @param type
    * @param busNum
    * @return virtual device spec of the controller
    */
   public static VirtualDeviceSpec createControllerDevice(
         ScsiControllerType type, int busNum) {
      VirtualSCSIController controller = type.createController();
      controller.setBusNumber(busNum);
      controller.setHotAddRemove(true);
      controller.setKey(-1);
      controller.setSharedBus(Sharing.noSharing);
      return addDeviceSpec(controller);
   }

   public static VirtualDeviceSpec removeDeviceSpec(int key) {
      VirtualDevice dev = new VirtualDeviceImpl();
      dev.setKey(key);
      VirtualDeviceSpec devSpec = new VirtualDeviceSpecImpl();
      devSpec.setOperation(VirtualDeviceSpec.Operation.remove);
      devSpec.setDevice(dev);
      return devSpec;
   }

   public static VirtualDeviceSpec removeDeviceSpec(VirtualDevice dev) {
      VirtualDeviceSpec devSpec = new VirtualDeviceSpecImpl();
      devSpec.setOperation(VirtualDeviceSpec.Operation.remove);
      devSpec.setDevice(dev);
      return devSpec;
   }

   public static VirtualDeviceSpec createNetworkDevice(
         EthernetControllerType type) {
      VirtualEthernetCard nic = type.createController();
      nic.setKey(-1);
      return addDeviceSpec(nic);
   }

   public static VirtualDeviceSpec createNetworkDevice(
         EthernetControllerType type, String label, VcNetwork vN) {
      VirtualDeviceSpec deviceSpec = createNetworkDevice(type);

      VirtualDevice device = deviceSpec.getDevice();
      Description deviceInfo = new DescriptionImpl();
      deviceInfo.setSummary("XXX");
      deviceInfo.setLabel(label);
      device.setDeviceInfo(deviceInfo);
      setVirtualDeviceBacking(device, vN.getBackingInfo());

      return deviceSpec;
   }

   public static VirtualDeviceSpec addDeviceSpec(VirtualDevice dev) {
      VirtualDeviceSpec devSpec = new VirtualDeviceSpecImpl();
      devSpec.setOperation(VirtualDeviceSpec.Operation.add);
      devSpec.setDevice(dev);
      return devSpec;
   }

   /**
    * Create a default scsi controller at bus 0.
    *
    * @return virtual device spec of the controller
    */
   public static VirtualDeviceSpec createControllerDevice() {
      return createControllerDevice(ScsiControllerType.LSILOGIC, 0);
   }

   /**
    * Create a virtual disk backing object.
    *
    * @param vmdkPath
    *           full vmdk path in the datastore
    * @param diskMode
    *           virtual disk access mode
    * @return backing object
    */
   public static VirtualDevice.BackingInfo createVmdkBackingInfo(
         String vmdkPath, DiskMode diskMode) {
      return createVmdkBackingInfo(vmdkPath, diskMode, null, null, null);
   }

   /**
    * Create a virtual disk backing object.
    *
    * @param vmdkPath
    *           full vmdk path in the datastore
    * @param diskMode
    *           virtual disk access mode
    * @param parentBacking
    *           indicates creation of a child delta disk attached to this parent
    *           backing.
    * @param thinDisk
    *           requests creation of a thin disk, null if the field should not
    *           be set
    * @param eagerlyScrub Flag to indicate to the underlying filesystem whether the
    *  virtual disk backing file should be scrubbed completely at this time.
    * @see com.vmware.vim.binding.vim.vm.device.VirtualDisk.FlatVer2BackingInfo#setEagerlyScrub
    * @return backing object
    */
   public static VirtualDevice.BackingInfo createVmdkBackingInfo(
         String vmdkPath, DiskMode diskMode,
         VirtualDisk.FlatVer2BackingInfo parentBacking, Boolean thinDisk, Boolean eagerlyScrub) {
      VirtualDisk.FlatVer2BackingInfo vmdkBacking =
            new VirtualDiskImpl.FlatVer2BackingInfoImpl();
      vmdkBacking.setFileName(vmdkPath);
      vmdkBacking.setDiskMode(diskMode.toString());
      if (parentBacking != null) {
         vmdkBacking.setParent(parentBacking);
      }
      if (thinDisk != null) {
         vmdkBacking.setThinProvisioned(thinDisk);
      }
      if (eagerlyScrub != null) {
         vmdkBacking.setEagerlyScrub(eagerlyScrub);
      }
      return vmdkBacking;
   }

   /**
    * Create a virtual disk backing object. The disk will be under the VM
    * directory on the specified datastore.
    *
    * @param vm
    *           virtual machine
    * @param ds
    *           datastore (null if using the default VM datastore.)
    * @param diskName
    *           virtual disk file name
    * @param diskMode
    *           virtual disk access mode
    * @param parentBacking
    *           indicates creation of a child delta disk attached to this parent
    *           backing.
    * @return backing object
    */
   public static VirtualDevice.BackingInfo createVmdkBackingInfo(
         VcVirtualMachine vm, VcDatastore ds, String diskName,
         DiskMode diskMode, VirtualDevice.BackingInfo parentBacking) {
      String vmdkPath = VcFileManager.getDsPath(vm, ds, diskName);
      return createVmdkBackingInfo(vmdkPath, diskMode,
            (VirtualDisk.FlatVer2BackingInfo) parentBacking, null, null);
   }

   /**
    * Create a virtual disk backing object. The disk will be under the VM
    * directory on the specified datastore.
    *
    * @param vm
    *           virtual machine
    * @param ds
    *           datastore (null if using the default VM datastore.)
    * @param diskName
    *           virtual disk file name
    * @param diskMode
    *           virtual disk access mode
    * @return backing object
    */
   public static VirtualDevice.BackingInfo createVmdkBackingInfo(
         VcVirtualMachine vm, VcDatastore ds, String diskName, DiskMode diskMode, Boolean thin, Boolean eagerlyScrub) {
      String vmdkPath = VcFileManager.getDsPath(vm, ds, diskName);
      return createVmdkBackingInfo(vmdkPath, diskMode, null, thin, eagerlyScrub);
   }

   public static VirtualDevice.BackingInfo createVmdkBackingInfo(
         VcVirtualMachine vm, VcDatastore ds, DiskType diskType) {
      String vmdkPath = VcFileManager.getDsPath(vm, ds, diskType.getDiskName());
      return createVmdkBackingInfo(vmdkPath, diskType.getDiskMode(), null,
            diskType.isThinDisk(), null);
   }

   public static VirtualDevice.BackingInfo createVmdkBackingInfo(
         VcVirtualMachine vm, VcDatastore ds, String diskName,
         DiskMode diskMode, Boolean thinDisk) {
      String vmdkPath = VcFileManager.getDsPath(vm, ds, diskName);
      return createVmdkBackingInfo(vmdkPath, diskMode, null, thinDisk, null);
   }

   public static VirtualDevice.BackingInfo createVmdkBackingInfo(
         VcVirtualMachine vm, String diskName, DiskMode diskMode) {
      return createVmdkBackingInfo(vm, null, diskName, diskMode, false);
   }

   /**
    * @return the full Datastore path of a virtual disk.
    */
   public static String getVmdkPath(VirtualDisk vmdk) {
      VirtualDisk.FileBackingInfo backing =
            (VirtualDisk.FileBackingInfo) vmdk.getBacking();
      return backing.getFileName();
   }

   /**
    * Create a ISO backing object.
    *
    * @param isoPath
    *           pathname to the ISO image file.
    * @return backing object
    */
   public static VirtualDevice.BackingInfo createCdromBackingInfo(String isoPath) {
      return new VirtualCdromImpl.IsoBackingInfoImpl(isoPath, null);
   }

   /**
    * Set a new backing object for the virtual device. The state of the device
    * will be "startConnected" and "connected".
    *
    * @param device
    *           the virtual device device
    * @param backing
    *           the backing object
    */
   public static void setVirtualDeviceBacking(VirtualDevice device,
         VirtualDevice.BackingInfo backing) {
      VirtualDevice.ConnectInfo connectInfo =
            new VirtualDeviceImpl.ConnectInfoImpl();
      connectInfo.setConnected(true);
      connectInfo.setStartConnected(true);
      device.setBacking(backing);
      device.setConnectable(connectInfo);
   }

   /**
    * Create a virtual disk object.
    *
    * @param controller
    *           virtual adapter to add the virtual disk
    * @param unitNum
    *           slot number under the adapter
    * @param backing
    *           backing of the virtual device
    * @param capacity
    *           size of the disk
    * @return virtual disk object
    */
   public static VirtualDisk createVirtualDisk(VirtualDevice controller,
         int unitNum, VirtualDevice.BackingInfo backing, DiskSize size) {
      AuAssert.check(controller instanceof VirtualController);

      VirtualDisk vmdk = new VirtualDiskImpl();
      vmdk.setUnitNumber(unitNum);
      vmdk.setControllerKey(controller.getKey());
      if (size != null) {
         vmdk.setCapacityInKB(size.getKiB());
      }
      setVirtualDeviceBacking(vmdk, backing);
      return vmdk;
   }

   /**
    * Create a VM configuration specification. The result {\link ConfigSpec} can
    * be passed to {\link VcVirtualMachine.clone()} to clone a VM, or {\link
    * VcVirtualMachine.reconfigure()} to reconfigure the VM.
    *
    * @param deviceChange
    *           a list of change descriptions
    * @return configuration specification
    * @throws Exception
    */
   public static ConfigSpec createConfigSpec(
         List<VirtualDeviceSpec> deviceChange) throws Exception {
      ConfigSpec config = new ConfigSpecImpl();
      config.setDeviceChange(deviceChange
            .toArray(new VirtualDeviceSpec[deviceChange.size()]));
      return config;
   }

   public static ConfigSpec createConfigSpec(VirtualDeviceSpec... deviceChanges)
         throws Exception {
      ConfigSpec config = new ConfigSpecImpl();
      config.setDeviceChange(deviceChanges);
      return config;
   }

   /**
    * Wrapper around ConfigSpecImpl.setMemoryMB that also adjusts the maximum
    * allowed balloon size, to keep it proportional to the memory size
    *
    * @param spec
    *           -- vm spec
    * @param memSize
    *           -- memory size in MB
    */
   public static void setMemoryAndBalloon(ConfigSpec spec, Long memSize) {
      spec.setMemoryMB(memSize);
      Long maxBalloon = memSize * 75 / 100;
      OptionValue balloonOption =
            new OptionValueImpl("sched.mem.maxmemctl", maxBalloon.toString());
      spec.setExtraConfig(new OptionValue[] { balloonOption });
   }

   /**
    * Get debug information of a virtual device
    *
    * @param device
    * @return info
    */
   public static String getVirtualDeviceInfo(VirtualDevice device) {
      String type = device.getClass().getSimpleName();
      if (device instanceof VirtualController) {
         VirtualController controller = (VirtualController) device;
         return device.getDeviceInfo().getLabel() + ":" + type + " bus="
               + controller.getBusNumber() + ",key=" + device.getKey();
      } else {
         String backingInfo = null;
         VirtualDevice.BackingInfo backing = device.getBacking();
         if (backing instanceof VirtualDisk.FileBackingInfo) {
            if (device instanceof VirtualDisk) {
               backingInfo =
                     ((VirtualDisk.FileBackingInfo) backing).getFileName();
               backingInfo +=
                     "(" + ((VirtualDisk) device).getCapacityInKB() + "KB)";
            }
         } else if (backing instanceof VirtualEthernetCard.NetworkBackingInfo) {
            backingInfo =
                  ((VirtualEthernetCard.NetworkBackingInfo) backing)
                        .getDeviceName();
         } else if (backing != null) {
            backingInfo = backing.toString();
         }
         return device.getDeviceInfo().getLabel() + ":" + type + " unit="
               + device.getUnitNumber() + ",key=" + device.getKey()
               + ",controllerKey=" + device.getControllerKey() + ",backing="
               + backingInfo;
      }
   }

   public static void addManagedByToConfigSpec(ConfigSpec spec, String owner,
         String type) {
      ManagedByInfo managedBy = new ManagedByInfoImpl();
      managedBy.setExtensionKey(owner);
      managedBy.setType(type);

      spec.setManagedBy(managedBy);
   }

   /**
    * Set VMX extra config value encoded in JSON.
    *
    * @param optionKey
    *           unique name of the config value
    * @param value
    *           object representing the config value
    */
   public static void setExtraConfigInSpec(ConfigSpec spec, String optionKey,
         Object value) {
      String jsonString = (new Gson()).toJson(value);
      OptionValue[] extraConfig = new OptionValueImpl[1];
      extraConfig[0] = new OptionValueImpl(optionKey, jsonString);
      spec.setExtraConfig(extraConfig);
   }

   public static void copyAttachDisk(VcVirtualMachine dstVcVm,
         VcVirtualMachine srcVcVm, VcSnapshot srcVcSnap, DeviceId srcDiskId,
         DeviceId dstDiskId, String diskName, DiskMode diskMode,
         VcDatastore ds, String tmpSnapName, String tmpSnapDescription,
         boolean isChangeTrackingEnabled, boolean fullCopy) throws Exception {
      VcSnapshot tmpSnap = null;

      if (srcVcSnap == null) {
         /*
          * Testing shows that a child delta disk can only be attached to a
          * disk that belongs to a snapshot, so create a temporary snapshot.
          */
         // XXX assert srcVcVm.isPoweredOff(); This assert sometimes fails due to a race.
         srcVcSnap = srcVcVm.createSnapshot(tmpSnapName, tmpSnapDescription);
         tmpSnap = srcVcSnap;
      }

      dstVcVm.attachChildDisk(dstDiskId, srcVcSnap, srcDiskId, ds, diskName,
            diskMode);
      if (fullCopy) {
         dstVcVm.promoteDisk(dstDiskId);
         /*
          * See PR 823579 for an explanation of the following hack.
          * To work-around an ESX-side bug, we need to delete the tracker file
          * per disk link used by ESX for changed block tracking (CBT) and then
          * re-create it.
          *
          * For a VM which already has CBT enabled (eg. a DBVM), disabling and
          * then re-enabling CBT achieves the above. However this does not work
          * for a VM that does not have CBT enabled (eg. an external backup VM).
          * For such a VM, an operation like changing the disk mode to any
          * other mode and back, achieves the above.
          */
         if (isChangeTrackingEnabled) {
            dstVcVm.setRequestedChangeTracking(false);
         }
         AuAssert.check(!DiskMode.independent_persistent.equals(diskMode));
         dstVcVm.editVirtualDisk(dstDiskId, DiskMode.independent_persistent);
         if (isChangeTrackingEnabled) {
            dstVcVm.setRequestedChangeTracking(true);
         }
         dstVcVm.editVirtualDisk(dstDiskId, diskMode);
      }
      if (tmpSnap != null) {
         tmpSnap.remove();
      }
   }

   public static ConfigSpec createEnableDisableHotAddConfigSpec(
         boolean enableHotAddCpu, boolean enableHotAddMemory) {
      ConfigSpec cfgSpec = new ConfigSpecImpl();
      OptionValue hotAddMemory =
            new OptionValueImpl(HOT_ADD_MEMORY_KEY, String.valueOf(
                  enableHotAddMemory).toUpperCase());
      OptionValue hotAddCpu =
            new OptionValueImpl(HOT_ADD_CPU_KEY, String
                  .valueOf(enableHotAddCpu).toUpperCase());
      cfgSpec.setExtraConfig(new OptionValue[] { hotAddMemory, hotAddCpu });
      return cfgSpec;
   }

   /**
    * Create virtual device object for a CD-ROM/DVD-ROM device.
    *
    * @param backing
    *           the backing info for the new device
    * @return cdrom the device spec
    */
   public static VirtualDevice createCdromDevice(
         VirtualDevice.BackingInfo backing) {
      VirtualCdromImpl cdrom = new VirtualCdromImpl();
      setVirtualDeviceBacking(cdrom, backing);
      return cdrom;
   }

   public static VirtualDevice.BackingInfo createFloppyBackingInfo(
         String flpPath) {
      return new VirtualFloppyImpl.ImageBackingInfoImpl(flpPath, null);
   }

   public static VirtualDevice createFloppyDevice(
         VirtualDevice.BackingInfo backing) {
      VirtualFloppyImpl floppy = new VirtualFloppyImpl();
      setVirtualDeviceBacking(floppy, backing);
      return floppy;
   }

   /**
    * Support workaround for PR 904771. Detach disk (FileOperation.destroy not
    * set) is not enabled in vSphere 5.1 if snapshot exists. If this detach disk
    * is disabled, we will use destroy disk to replace detach disk operation.
    */
   private static final boolean DETACH_DISK_IS_ENABLED = false;
   private static final String DETACH_DISK_IS_ENABLED_KEY =
         "vc.detachDiskEnabled";

   public static boolean isDetachDiskEnabled() {
      return Configuration.getBoolean(DETACH_DISK_IS_ENABLED_KEY,
            DETACH_DISK_IS_ENABLED);
   }

   /**
    * Define whether use single VM operation solution in the Sagas such as
    * repair/upgrade. Should change this setting according to work flow
    * requirement. In vSphere 5.1, use this flag as a workaround. As destroy
    * independent disks is not enabled if snapshot exist. Single VM operation
    * solutions cannot work. So do not use single VM operation by default.
    */
   private static final boolean SINGLE_VM_OPS_IS_ENABLED = false;
   private static final String SINGLE_VM_OPS_IS_ENABLED_KEY =
         "cms.singleVMOpsEnabled";

   public static boolean isSingleVMOperationEnabled() {
      return Configuration.getBoolean(SINGLE_VM_OPS_IS_ENABLED_KEY,
            SINGLE_VM_OPS_IS_ENABLED);
   }
}
TOP

Related Classes of com.vmware.aurora.vc.VmConfigUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.