Package hudson.plugins.libvirt

Source Code of hudson.plugins.libvirt.VirtualMachineLauncher

/**
*  Copyright (C) 2010, Byte-Code srl <http://www.byte-code.com>
*  Copyright (C) 2012  Philipp Bartsch <tastybug@tastybug.com>
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
* Date: Mar 04, 2010
* @author Marco Mornati<mmornati@byte-code.com>
* @author Philipp Bartsch <tastybug@tastybug.com>
*/
package hudson.plugins.libvirt;

import hudson.model.TaskListener;
import hudson.model.Descriptor;
import hudson.model.Hudson;
import hudson.plugins.libvirt.lib.IDomain;
import hudson.slaves.Cloud;
import hudson.slaves.ComputerLauncher;
import hudson.slaves.SlaveComputer;

import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import jenkins.model.Jenkins;

import org.kohsuke.stapler.DataBoundConstructor;


public class VirtualMachineLauncher extends ComputerLauncher {

    private static final Logger LOGGER = Logger.getLogger(VirtualMachineLauncher.class.getName());
    private ComputerLauncher delegate;
    private transient VirtualMachine virtualMachine;
    private String hypervisorDescription;
    private String virtualMachineName;
    private String snapshotName;
    private final int WAIT_TIME_MS;
    private final int timesToRetryOnFailure;
   
    @DataBoundConstructor
    public VirtualMachineLauncher(ComputerLauncher delegate, String hypervisorDescription, String virtualMachineName, String snapshotName,
            int waitingTimeSecs, int timesToRetryOnFailure) {
        super();
        this.delegate = delegate;
        this.virtualMachineName = virtualMachineName;
        this.snapshotName = snapshotName;
        this.hypervisorDescription = hypervisorDescription;
        this.WAIT_TIME_MS = waitingTimeSecs*1000;
        this.timesToRetryOnFailure = timesToRetryOnFailure;
        lookupVirtualMachineHandle();
    }

    private void lookupVirtualMachineHandle() {
        if (hypervisorDescription != null && virtualMachineName != null) {
            LOGGER.log(Level.FINE, "Grabbing hypervisor...");
            Hypervisor hypervisor = null;
            for (Cloud cloud : Hudson.getInstance().clouds) {
                if (cloud instanceof Hypervisor && ((Hypervisor) cloud).getHypervisorDescription().equals(hypervisorDescription)) {
                    hypervisor = (Hypervisor) cloud;
                    break;
                }
            }
            LOGGER.log(Level.FINE, "Hypervisor found, searching for a matching virtual machine for \"" + virtualMachineName + "\"...");
            for (VirtualMachine vm : hypervisor.getVirtualMachines()) {
                if (vm.getName().equals(virtualMachineName)) {
                    virtualMachine = vm;
                    break;
                }
            }
        }
    }
   
    public ComputerLauncher getDelegate() {
        return delegate;
    }

    public VirtualMachine getVirtualMachine() {
        lookupVirtualMachineHandle();
        return virtualMachine;
    }

    public String getVirtualMachineName() {
        return virtualMachineName;
    }

    @Override
    public boolean isLaunchSupported() {
        return true;
    }

    public Hypervisor findOurHypervisorInstance() throws RuntimeException {
        if (hypervisorDescription != null && virtualMachineName != null) {
            Hypervisor hypervisor = null;
            for (Cloud cloud : Hudson.getInstance().clouds) {
                if (cloud instanceof Hypervisor && ((Hypervisor) cloud).getHypervisorDescription().equals(hypervisorDescription)) {
                    hypervisor = (Hypervisor) cloud;
                    return hypervisor;
                }
            }
        }
        LOGGER.log(Level.SEVERE, "Could not find our libvirt cloud instance!");
        throw new RuntimeException("Could not find our libvirt cloud instance!");
    }

    @Override
    public void launch(SlaveComputer slaveComputer, TaskListener taskListener) throws IOException, InterruptedException {
     
      taskListener.getLogger().println("Virtual machine \"" + virtualMachineName + "\" (slave title \"" + slaveComputer.getDisplayName() + "\") is to be started.");
      try {
          if (virtualMachine == null) {
              taskListener.getLogger().println("No connection ready to the Hypervisor, connecting...");
              lookupVirtualMachineHandle();
              if (virtualMachine == null) // still null? no such vm!
                throw new Exception("Virtual machine \"" + virtualMachineName + "\" (slave title \"" + slaveComputer.getDisplayName() + "\") not found on the specified hypervisor!");
          }
       
            Map<String, IDomain> computers = virtualMachine.getHypervisor().getDomains();
            IDomain domain = computers.get(virtualMachine.getName());
            if (domain != null) {
                if( domain.isNotBlockedAndNotRunning() ) {
                    taskListener.getLogger().println("Starting, waiting for " + WAIT_TIME_MS + "ms to let it fully boot up...");
                    domain.create();
                    Thread.sleep(WAIT_TIME_MS);

                    int attempts = 0;
                    while (true) {
                        attempts++;

                        taskListener.getLogger().println("Connecting slave client.");

                        // This call doesn't seem to actually throw anything, but we'll catch IOException just in case
                        try {
                            delegate.launch(slaveComputer, taskListener);
                        } catch (IOException e) {
                        }

                        if (slaveComputer.isOnline()) {
                            break;
                        } else if (attempts >= timesToRetryOnFailure) {
                            taskListener.getLogger().println("Maximum retries reached. Failed to start slave client.");
                            break;
                        }

                        taskListener.getLogger().println("Not up yet, waiting for " + WAIT_TIME_MS + "ms more (" +
                                                         attempts + "/" + timesToRetryOnFailure + " retries)...");
                        Thread.sleep(WAIT_TIME_MS);
                    }
                } else {
                    taskListener.getLogger().println("Already running, no startup required.");

                taskListener.getLogger().println("Connecting slave client.");
                delegate.launch(slaveComputer, taskListener);
                }
            } else {
              throw new IOException("VM \"" + virtualMachine.getName() + "\" (slave title \"" + slaveComputer.getDisplayName() + "\") not found!");
            }
        } catch (IOException e) {
            taskListener.fatalError(e.getMessage(), e);
           
            LogRecord rec = new LogRecord(Level.SEVERE, "Error while launching {0} on Hypervisor {1}.");
            rec.setParameters(new Object[]{virtualMachine.getName(), virtualMachine.getHypervisor().getHypervisorURI()});
            rec.setThrown(e);
            LOGGER.log(rec);
            throw e;
        } catch (Throwable t) {
          taskListener.fatalError(t.getMessage(), t);
           
            LogRecord rec = new LogRecord(Level.SEVERE, "Error while launching {0} on Hypervisor {1}.");
            rec.setParameters(new Object[]{virtualMachine.getName(), virtualMachine.getHypervisor().getHypervisorURI()});
            rec.setThrown(t);
            LOGGER.log(rec);
        }
    }

    @Override
    public synchronized void afterDisconnect(SlaveComputer slaveComputer, TaskListener taskListener) {
        delegate.afterDisconnect(slaveComputer, taskListener);
    }

    @Override
    public void beforeDisconnect(SlaveComputer slaveComputer, TaskListener taskListener) {
        delegate.beforeDisconnect(slaveComputer, taskListener);
    }

    @Override
    public Descriptor<ComputerLauncher> getDescriptor() {
      throw new UnsupportedOperationException();
    }
}
TOP

Related Classes of hudson.plugins.libvirt.VirtualMachineLauncher

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.