Package betsy.bpel.virtual.host.virtualbox

Source Code of betsy.bpel.virtual.host.virtualbox.VBoxController

package betsy.bpel.virtual.host.virtualbox;

import betsy.common.tasks.FileTasks;
import betsy.bpel.virtual.host.VirtualBoxMachine;
import betsy.bpel.virtual.host.exceptions.vm.VirtualMachineNotFoundException;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.virtualbox_4_2.*;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

/**
* The {@link VBoxController} establishes the connection between betsy and
* VirtualBox. It can be used to resolve machines, import or delete them and to
* adapt some settings of VirtualBox.
*
* @author Cedric Roeck
* @version 1.0
*/
public class VBoxController {

    public static final String BETSY_VBOX_GROUP = "/betsy-engines";
    private static final Logger log = Logger.getLogger(VBoxController.class);

    private final Map<String, VirtualBoxMachineImpl> virtualMachines = new HashMap<>();

    private IVirtualBox vBox;
    private VBoxApplianceImporter vBoxImporter;
    private VirtualBoxManager vBoxManager;

    public VBoxController() {
        log.trace("Initializing VBoxController");
        VBoxConnector vBoxConn = new VBoxConnector();
        this.vBox = vBoxConn.connect();
        this.vBoxManager = vBoxConn.getVBoxManager();
        this.vBoxImporter = vBoxConn.getVBoxImporter();

        log.trace("VirtualBoxController initialized");
    }

    /**
     * Import the Engine's virtualMachine from the given file.
     *
     * @param vmName     desired name of the virtualMachine
     * @param engineName name of the engine the new VM belongs to
     * @param importFile file of the appliance to import
     */
    public void importVirtualMachine(final String vmName, final String engineName, final Path importFile) {

        if (StringUtils.isBlank(vmName)) {
            throw new IllegalArgumentException(
                    "The name of the vm to import must not be null or empty");
        }
        if (StringUtils.isBlank(engineName)) {
            throw new IllegalArgumentException(
                    "The name of the engine to import must not be null or empty");
        }
        Objects.requireNonNull(importFile, "The file to import must not be null");

        IMachine importedVm = null;
        ISession session = null;
        try {
            log.info("Importing appliance from file " + importFile);
            IAppliance appliance = vBoxImporter.importAppliance(importFile);
            log.info("Appliance imported (machines: " + appliance.getMachines() + ")");

            if(appliance.getMachines().isEmpty()){
                throw new IllegalStateException("The appliance " + importFile + " has no machines inside");
            }

            // by definition the appliance container could contain several
            // separated machines which must be imported each at it's own.
            for (String uuid : appliance.getMachines()) {
                importedVm = vBox.findMachine(uuid);

                // acquire session lock
                session = vBoxManager.getSessionObject();
                importedVm.lockMachine(session, LockType.Write);
                IMachine lockedVM = session.getMachine();

                vBoxImporter.adjustApplianceSettings(lockedVM, vmName);

                try {
                    session.unlockMachine();
                    session = null;
                } catch (VBoxException exception) {
                    // ignore if was not locked
                    log.debug("Failed to unlock session after import");
                }
            } // END FOR ITERATION
        } catch (VBoxException exception) {
            // session must be unlocked for deleting the vm
            if (session != null) {
                try {
                    session.unlockMachine();
                } catch (VBoxException ignore) {
                    log.debug("Failed to unlock session after import exception", ignore);
                    // ignore if was not locked
                }
            }
            if (importedVm != null) {
                log.debug("Exception during import, delete VM again.");
                // Error --> delete VM again
                this.deleteMachine(importedVm);
            }
            log.warn("Unexpected import exception:", exception);
        }
    }

    /**
     * Get the {@link VirtualBoxMachineImpl} of betsy with the given name.
     *
     * @param name name of the VirtualMachine to get
     * @return VirtualBoxMachine with the searched name
     * @throws VirtualMachineNotFoundException thrown if there is no VirtualMachine with this name
     */
    public VirtualBoxMachine getVirtualMachine(final String name)
            throws VirtualMachineNotFoundException {

        if (virtualMachines.containsKey(name)) {
            return virtualMachines.get(name);
        } else {
            VirtualBoxMachineImpl vm = new VirtualBoxMachineImpl(vBoxManager,
                    getMachine(name));
            virtualMachines.put(name, vm);
            return vm;
        }
    }

    /**
     * Get the {@link IMachine} of VirtualBox with the given name.
     *
     * @param name name of the IMachine to get
     * @return IMachine with the searched name
     * @throws VirtualMachineNotFoundException thrown if there is no IMachine with this name
     */
    public IMachine getMachine(final String name)
            throws VirtualMachineNotFoundException {

        if (StringUtils.isBlank(name)) {
            throw new IllegalArgumentException(
                    "name of the virtual machine must not be null or empty");
        }

        List<String> groups = new LinkedList<>();
        groups.add(BETSY_VBOX_GROUP);
        List<IMachine> machines = vBox.getMachinesByGroups(groups);
        for (IMachine machine : machines) {
            if (machine.getName().equals(name)) {
                return machine;
            }
        }

        throw new VirtualMachineNotFoundException("VirtualMachine with name '"
                + name + "' could not be found in group " + BETSY_VBOX_GROUP);
    }

    private void deleteMachine(final IMachine machine) {
        Path logFolder = Paths.get(machine.getLogFolder());
        FileTasks.deleteDirectory(logFolder);

        List<IMedium> removableMediums = machine.unregister(CleanupMode.Full);
        machine.delete(removableMediums);
    }

}
TOP

Related Classes of betsy.bpel.virtual.host.virtualbox.VBoxController

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.