Package com.cybozu.vmbkp.soap

Source Code of com.cybozu.vmbkp.soap.VirtualMachineManager

/**
* @file
* @brief VirtualMachineManager
*
* Copyright (C) 2009,2010 Cybozu Inc., all rights reserved.
*
* @author Takashi HOSHINO <hoshino@labs.cybozu.co.jp>
*/
package com.cybozu.vmbkp.soap;

import java.util.List;
import java.util.LinkedList;
import java.util.logging.Logger;

import com.vmware.vim25.mo.VirtualMachine;
import com.vmware.vim25.mo.VirtualMachineSnapshot;
import com.vmware.vim25.mo.Task;
import com.vmware.vim25.VirtualMachineSnapshotTree;
import com.vmware.vim25.VirtualMachineSnapshotInfo;
import com.vmware.vim25.ManagedObjectReference;

import com.cybozu.vmbkp.util.VmInfo;
import com.cybozu.vmbkp.util.VmdkInfo;
import com.cybozu.vmbkp.util.AdapterType;
import com.cybozu.vmbkp.util.Utility;

import com.cybozu.vmbkp.soap.SnapshotManager;
import com.cybozu.vmbkp.soap.Connection;
import com.cybozu.vmbkp.soap.VirtualMachineConfigManager;
import com.cybozu.vmbkp.soap.VirtualControllerManager;

/* addDisksToVm */
import com.vmware.vim25.VirtualDeviceConfigSpec;
import com.vmware.vim25.VirtualMachineConfigSpec;

/* exportOvf */
import com.vmware.vim25.OvfFile;
import com.vmware.vim25.OvfCreateDescriptorParams;
import com.vmware.vim25.OvfCreateDescriptorResult;

/* createScsiSpec, createDiskSpec, createNicSpec */
import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
import com.vmware.vim25.VirtualDeviceConfigSpecFileOperation;
import com.vmware.vim25.VirtualSCSISharing;
import com.vmware.vim25.VirtualIDEController;
import com.vmware.vim25.VirtualSCSIController;
import com.vmware.vim25.VirtualBusLogicController;
import com.vmware.vim25.VirtualLsiLogicController;
import com.vmware.vim25.VirtualLsiLogicSASController;
import com.vmware.vim25.VirtualDisk;
import com.vmware.vim25.VirtualDiskFlatVer2BackingInfo;
import com.vmware.vim25.VirtualEthernetCard;
import com.vmware.vim25.VirtualE1000;
import com.vmware.vim25.VirtualEthernetCardNetworkBackingInfo;
import com.vmware.vim25.Description;


/**
* @brief Manage a virtual machine.
*/
public class VirtualMachineManager
{
    /**
     * Logger.
     */
    private static final Logger logger_ =
        Logger.getLogger(VirtualMachineManager.class.getName());

    Connection conn_;
    VirtualMachine vm_;
    VirtualMachineConfigManager configMgr_;

    /**
     * Constructor.
     *
     * You must not create objects directly with new operator by yourself.
     */
    public VirtualMachineManager(Connection conn, VirtualMachine vm)
    {
        conn_ = conn;
        vm_ = vm;
        configMgr_ = new VirtualMachineConfigManager(conn_, vm_.getConfig());
    }

    /**
     * Get name of the virtual machine.
     */
    public String getName()
    {
        if (vm_ == null) { return null; }
        return vm_.getName();
    }

    /**
     * Get moref of the virtual machine.
     */
    public String getMoref()
    {
        if (vm_ == null) { return null; }
        return vm_.getMOR().getVal();
    }

    /**
     * Get VmInfo.
     */
    public VmInfo getVmInfo()
    {
        if (vm_ == null) { return null; }
        return new VmInfo(getName(), getMoref());
    }

    /**
     * Get config manager.
     */
    public VirtualMachineConfigManager getConfig()
    {
        return configMgr_;
    }

    /********************************************************************************
     * Raw interface for object who talks soap also.
     ********************************************************************************/

    /**
     * Get VirtualMachine object.
     */
    protected VirtualMachine getVirtualMachine()
    {
        return vm_;
    }
   
    /********************************************************************************
     * Snapshot methods.
     ********************************************************************************/

    /**
     * Get manager of current snapshot if exists.
     */
    public SnapshotManager getCurrentSnapshot()
    {
        try {
            VirtualMachineSnapshot vmSnap = vm_.getCurrentSnapShot();
            if (vmSnap != null) {
                return new SnapshotManager(conn_, vm_, vmSnap);
            } else {
                return null;
            }
        } catch (Exception e) { logger_.warning(Utility.toString(e)); return null; }
    }
   
    /**
     * Search virtual machine snapshot with a specified name.
     */
    public SnapshotManager searchSnapshotWithName(String snapName)
    {
        VirtualMachineSnapshot vmSnap = getSnapshotInTree(snapName);
        if (vmSnap != null) {
            return new SnapshotManager(conn_, vm_, vmSnap);
        } else {
            return null;
        }
    }

    /**
     * Search snapshot with a moref. !!!Not implemented yet.!!!
     */
    public SnapshotManager searchSnapshotWithMoref(String snapMorefStr)
    {
        VirtualMachineSnapshot vmSnap =
            conn_.generateSnapshotWithMoref(snapMorefStr);
        if (vmSnap != null) {
            return new SnapshotManager(conn_, vm_, vmSnap);
        } else {
            return null;
        }
    }

    /**
     * Search snapshot tree with a moref.
     */
    protected VirtualMachineSnapshotTree searchSnapshotTreeWithMoref(String snapMorefStr)
    {
        return searchSnapshotTreeWithMoref
            (vm_.getSnapshot().getRootSnapshotList(), snapMorefStr);
    }

    /**
     * Called by searchSnapshotTreeWithMoref() for recursive search.
     */
    private VirtualMachineSnapshotTree searchSnapshotTreeWithMoref
        (VirtualMachineSnapshotTree[] snapTrees, String snapMorefStr)
    {
        for (int i = 0; i < snapTrees.length; i ++) {
            if (snapTrees[i].getSnapshot().getVal().equals(snapMorefStr)) {
                return snapTrees[i];
            }
            VirtualMachineSnapshotTree[] childTrees =
                snapTrees[i].getChildSnapshotList();
            VirtualMachineSnapshotTree ret =
                searchSnapshotTreeWithMoref(childTrees, snapMorefStr);
            if (ret != null) {
                return ret;
            }
        }
        return null;
    }
   
    /**
     * Find ManagedEntity from ManagedObject of snapshot.
     *
     * @param vm A virtual machine.
     * @param vmSnap Managed object of a snapshot.
     * @return The corresponding ManagedEntity as VirtualMachineSnapshotTree.
     */
    private VirtualMachineSnapshotTree getSnapshotInTree(VirtualMachineSnapshot vmSnap)
    {
        if (vmSnap == null) { return null; }
       
        VirtualMachineSnapshotTree[] snapTree =
            vm_.getSnapshot().getRootSnapshotList();

        if (snapTree == null) { return null; }
       
        VirtualMachineSnapshotTree st =
            findSnapshotInTree(snapTree, vmSnap);
        return st;
    }

    /**
     * Called by getSnapshotInTree().
     *
     * @param snapTree snapshot tree.
     * @param vmSnap snapshot
     * @return Found tree with the specified snapshot.
     */
    private VirtualMachineSnapshotTree findSnapshotInTree
        (VirtualMachineSnapshotTree[] snapTree, VirtualMachineSnapshot vmSnap)
    {
        for (int i = 0; i < snapTree.length; i ++) {
            VirtualMachineSnapshotTree node = snapTree[i];
            if (node.getSnapshot().equals(vmSnap.getMOR())) {
                return node;
            }
            VirtualMachineSnapshotTree[] childTree =
                node.getChildSnapshotList();
            if (childTree != null) {
                VirtualMachineSnapshotTree ret =
                    findSnapshotInTree(childTree, vmSnap);
                if (ret != null) {
                    return ret;
                }
            }
        }
        return null;
    }
   
    /**
     * Find a snapshot with the specified name as a moref
     * in the specified snapshot tree.
     *
     * Original version is written by Steve Jin in sample code in VMSnapshot.java.
     * @author Steve Jin
     */
    private ManagedObjectReference findSnapshotInTree
        (VirtualMachineSnapshotTree[] snapTree, String snapName)
    {
        for (int i = 0; i < snapTree.length; i ++) {
            VirtualMachineSnapshotTree node = snapTree[i];
            if (snapName.equals(node.getName())) {
                return node.getSnapshot();
            } else {
                VirtualMachineSnapshotTree[] childTree =
                    node.getChildSnapshotList();
                if (childTree != null) {
                    ManagedObjectReference mor =
                        findSnapshotInTree(childTree, snapName);
                    if (mor != null) { return mor; }
                }
            }
        }
        return null;
    }
   
    /**
     * Search snapshot with the specified name in the snapshot tree
     * of the virtual machine.
     *
     * Original version is written by Steve Jin in sample code
     * in VMSnapshot.java.
     * @author Steve Jin
     */
    private VirtualMachineSnapshot getSnapshotInTree(String snapName)
    {
        if (snapName == null) { return null; }
       
        VirtualMachineSnapshotTree[] snapTree =
            vm_.getSnapshot().getRootSnapshotList();
       
        if (snapTree != null) {
            ManagedObjectReference mor = findSnapshotInTree(snapTree, snapName);
            if (mor != null) {
                return new
                    VirtualMachineSnapshot(vm_.getServerConnection(), mor);
            }
        }
        return null;
    }

    /**
     * Task type for snapshot.
     */
    private enum TaskType { CREATE, DELETE, REVERT, NONE }

    /**
     * Task wrapper for snapshot.
     */
    private boolean snapshotTaskDetail(TaskType type, String snapName,
                                       String messageInSuccess, String messageInFailure)
    {

        VirtualMachineSnapshot vmsnap = null;

        if (type != TaskType.CREATE) {
            vmsnap = getSnapshotInTree(snapName);
            if (vmsnap == null) { return false; }
        }

        try {
            Task task = null;
            switch (type) {
            case CREATE:
                task = vm_.createSnapshot_Task(snapName, null, false, false);
                break;
            case DELETE:
                task = vmsnap.removeSnapshot_Task(true);
                break;
            case REVERT:
                task = vmsnap.revertToSnapshot_Task(null, true);
                break;
            default:
                throw new Exception("Snapshot TaskType is wrong.");
            }
            assert task != null;
            String ret = task.waitForTask();
            if (ret.equals("success")) {
                logger_.info(messageInSuccess);
                return true;
            } else {
                logger_.info(messageInFailure);
                return false;
            }
        } catch (Exception e) { logger_.warning(Utility.toString(e)); return false; }
    }
   
    /**
     * Create snapshot of a specified virtual machine.
     *
     * @param snapName the name of new snapshot.
     * @return True in success, false in failure.
     */
    public boolean createSnapshot(String snapName)
    {
        return snapshotTaskDetail(TaskType.CREATE, snapName,
                                  "Snapshot was created successfully.\n",
                                  "Snapshot creation task failed.\n");
    }

    /**
     * Delete snapshot of virtual machine
     *
     * @param snapName snapshot name to delete
     * @return true in success, false in failure.
     */
    public boolean deleteSnapshot(String snapName)
    {
        return snapshotTaskDetail(TaskType.DELETE, snapName,
                                  "Snapshot was deleted successfully.\n",
                                  "Delete snapshot task failed.\n");
    }

    /**
     * Revert a virtual machine to a snapshot.
     *
     * @param snapName snapshot name to revert.
     * @return true in success, false in failure.
     */
    public boolean revertToSnapshot(String snapName)
    {
        return snapshotTaskDetail(TaskType.REVERT, snapName,
                                  "Virtual machine was reverted successfully.\n",
                                  "Revert snapshot task failed.\n");
    }

    /**
     * Get the name of all snapshots of a specified virtual machine.
     *
     * @return a list of the name of snapshots.
     */
    public List<String> getAllSnapshotNameList()
    {
        VirtualMachineSnapshotInfo snapInfo = vm_.getSnapshot();
        if (snapInfo == null) { return null; }

        VirtualMachineSnapshotTree[] snapTree
            = snapInfo.getRootSnapshotList();

        List<String> ret = getAllSnapshotNameList(snapTree);

        return ret;
    }

    /**
     * For recursive processing.
     */
    private List<String>
        getAllSnapshotNameList(VirtualMachineSnapshotTree[] snapTree)
    {
        List<String> ret = new LinkedList<String>();
       
        for (int i = 0; snapTree != null && i < snapTree.length; i ++) {
            ret.add(snapTree[i].getName());
            VirtualMachineSnapshotTree[] childTree
                = snapTree[i].getChildSnapshotList();
            if (childTree != null) {
                ret.addAll(getAllSnapshotNameList(childTree));
            }
        }
        return ret;
    }

    /**
     * Add empty disks to a specified virtual machine.
     * The virtual machine must not have any SCSI Controller or Disks.
     *
     * @deprecated Use addEmptyDisks() instead.
     * @param datastoreName Datastore name to create disks.
     * @param diskSizeMbList A list of disk size in MB.
     *        If the list size is 2 then 2 disks will be created.
     * @return True in success, false in failure.
     */
    public boolean addDisksToVm
        (String datastoreName, List<Long> diskSizeMbList)
    {
        /* list for created devices */
        List<VirtualDeviceConfigSpec> specList =
            new LinkedList<VirtualDeviceConfigSpec>();

        /* create scsi controller spec */
        int cKey = 1000;
        VirtualDeviceConfigSpec scsiSpec = createScsiSpec(cKey);
        specList.add(scsiSpec);
       
        /* create hard disk spec */
        int unitNumber = 0;
        for (Long diskSizeMb: diskSizeMbList) {
            VirtualDeviceConfigSpec diskSpec = createDiskSpec
                (datastoreName, cKey, diskSizeMb.longValue(),
                 "persistent", unitNumber);
            specList.add(diskSpec);
            unitNumber ++;
        }

        /* set vm config spec */
        VirtualMachineConfigSpec vmConfigSpec =
            new VirtualMachineConfigSpec();
        vmConfigSpec.setChangeTrackingEnabled(true); /* set ctkEnabled option. */
        vmConfigSpec.setDeviceChange
            (specList.toArray(new VirtualDeviceConfigSpec[0]));

        /* reconfigure vm task */
        try {
            Task task = vm_.reconfigVM_Task(vmConfigSpec);
            String ret = task.waitForTask();
            logger_.info(String.format("%s: addDisksToVm()\n", ret));
            if (ret.equals("success")) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) { logger_.warning(Utility.toString(e)); return false; }
    }

    /**
     * Add empty disks and its related disk controllers to the virtual machine.
     *
     * If the virtual machine has controllers and disks which conflicts
     * newly adding devices with device key or busNumber/unitNumber,
     * reconfigure task will fail.
     *
     * @param ctrlmList a list of virtual controller manager.
     * @return true in success, false in failure.
     */
    public boolean addEmptyDisks(List<VirtualControllerManager> ctrlmList)
    {
        /* list for new devices */
        List<VirtualDeviceConfigSpec> specList =
            new LinkedList<VirtualDeviceConfigSpec>();

        /* add devices to the list */
        for (VirtualControllerManager ctrlm : ctrlmList) {
            /* create new device of the controller and
               all disks managed by it. */
            specList.addAll(ctrlm.createAll());
        }

        /* set vm config spec */
        VirtualMachineConfigSpec vmConfigSpec =
            new VirtualMachineConfigSpec();
        vmConfigSpec.setChangeTrackingEnabled(true); /* set ctkEnabled option. */
        vmConfigSpec.setDeviceChange
            (specList.toArray(new VirtualDeviceConfigSpec[0]));

        /* reconfigure vm task */
        try {
            Task task = vm_.reconfigVM_Task(vmConfigSpec);
            String ret = task.waitForTask();
            logger_.info(String.format("%s: addEmptyDisks()\n", ret));
            if (ret.equals("success")) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) { logger_.warning(Utility.toString(e)); return false; }
    }

    /**
     * Export ovf information of the virtual machine.
     *
     * This may contains disk information but they will be not used and deleted.
     *
     * @return ovf descriptor xml as string data.
     */
    public String exportOvf()
    {
        OvfFile[] ovfFiles = new OvfFile[0];
        OvfCreateDescriptorParams ovfDescParams = new OvfCreateDescriptorParams();
        ovfDescParams.setOvfFiles(ovfFiles);
        try {
            OvfCreateDescriptorResult ovfCreateDescriptorResult =
                conn_.getServiceInstance().getOvfManager().createDescriptor
                (vm_, ovfDescParams);
            return ovfCreateDescriptorResult.getOvfDescriptor();
        } catch (Exception e) { logger_.warning(Utility.toString(e)); return null; }
    }

    /**
     * Reload the information of the virtual machine
     * from the soap server.
     */
    public void reload()
    {
        /* reload config */
        configMgr_ = new VirtualMachineConfigManager(conn_, vm_.getConfig());
    }

    /**
     * This code is copied from
     * CreateVM.java of vi-java sample code.
     *
     * @deprecated This is called by addDisksToVm() only.
     * @author Steve Jin.
     */
    private VirtualDeviceConfigSpec createScsiSpec(int cKey)
    {
        VirtualDeviceConfigSpec scsiSpec =
            new VirtualDeviceConfigSpec();
        scsiSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
        VirtualLsiLogicController scsiCtrl =
            new VirtualLsiLogicController();
        scsiCtrl.setKey(cKey);
        scsiCtrl.setBusNumber(0);
        scsiCtrl.setSharedBus(VirtualSCSISharing.noSharing);
        scsiSpec.setDevice(scsiCtrl);
        return scsiSpec;
    }
 
    /**
     * This code is copied from
     * CreateVM.java of vi-java sample code.
     *
     * @deprecated This is called by addDisksToVm() only.
     * @author Steve Jin.
     */
    private VirtualDeviceConfigSpec createDiskSpec
        (String dsName, int cKey, long diskSizeMB, String diskMode, int unitNumber)
    {
        VirtualDeviceConfigSpec diskSpec =
            new VirtualDeviceConfigSpec();
        diskSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
        diskSpec.setFileOperation
            (VirtualDeviceConfigSpecFileOperation.create);
   
        VirtualDisk vd = new VirtualDisk();
        vd.setCapacityInKB(diskSizeMB * 1024L);
        diskSpec.setDevice(vd);
        vd.setKey(0);
        vd.setUnitNumber(unitNumber);
        vd.setControllerKey(cKey);

        VirtualDiskFlatVer2BackingInfo diskfileBacking =
            new VirtualDiskFlatVer2BackingInfo();
        String fileName = "["+ dsName +"]";
        diskfileBacking.setFileName(fileName);
        diskfileBacking.setDiskMode(diskMode);
        diskfileBacking.setThinProvisioned(true);
        vd.setBacking(diskfileBacking);
        return diskSpec;
    }
 
    /**
     * This code is copied from
     * CreateVM.java of vi-java sample code.
     *
     * @deprecated This is called by noone.
     * @author Steve Jin.
     */
    private VirtualDeviceConfigSpec createNicSpec
        (String netName, String nicName)
        throws Exception
    {
        VirtualDeviceConfigSpec nicSpec =
            new VirtualDeviceConfigSpec();
        nicSpec.setOperation(VirtualDeviceConfigSpecOperation.add);

        VirtualEthernetCard nic =  new VirtualE1000();
        VirtualEthernetCardNetworkBackingInfo nicBacking =
            new VirtualEthernetCardNetworkBackingInfo();
        nicBacking.setDeviceName(netName);

        Description info = new Description();
        info.setLabel(nicName);
        info.setSummary(netName);
        nic.setDeviceInfo(info);
   
        // type: "generated", "manual", "assigned" by VC
        nic.setAddressType("generated");
        nic.setBacking(nicBacking);
        nic.setKey(0);
  
        nicSpec.setDevice(nic);
        return nicSpec;
    }
}
TOP

Related Classes of com.cybozu.vmbkp.soap.VirtualMachineManager

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.