Package hudson.plugins.openshift

Source Code of hudson.plugins.openshift.OpenShiftSlave$DescriptorImpl

package hudson.plugins.openshift;

import com.openshift.client.*;
import com.openshift.client.cartridge.ICartridge;
import com.openshift.client.cartridge.IStandaloneCartridge;
import com.openshift.client.cartridge.StandaloneCartridge;
import hudson.Extension;
import hudson.FilePath;
import hudson.model.Descriptor.FormException;
import hudson.model.Hudson;
import hudson.model.Queue;
import hudson.model.TaskListener;
import hudson.slaves.AbstractCloudComputer;
import hudson.slaves.AbstractCloudSlave;
import hudson.slaves.CloudRetentionStrategy;
import hudson.slaves.NodeProperty;
import org.kohsuke.stapler.DataBoundConstructor;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class OpenShiftSlave extends AbstractCloudSlave {
    private static final long serialVersionUID = 8486485671018263774L;
    private static final Logger LOGGER = Logger.getLogger(OpenShiftSlave.class
            .getName());

    private String applicationUUID;
    private String builderType;
    private final String builderSize;
    private final String builderPlatform;
    private final long builderTimeout;
    private String uuid;

    /**
     * The name of the slave should be the 'sanitized version of the framework
     * that is used, removing all '.' and '-' characters (i.e. jbossas70, php53)
     * <p/>
     * The framework should be the exact OpenShift framework used (i.e.
     * jbossas-7)
     */
    @DataBoundConstructor
    public OpenShiftSlave(String name, String applicationUUID, String builderType, String builderSize, String builderPlatform,
                          String label, long builderTimeout, int executors, int slaveIdleTimeToLive) throws FormException, IOException {
        super(name, "Builder for " + label, null, executors, Mode.NORMAL,
                label, new OpenShiftComputerLauncher(),
                new CloudRetentionStrategy(slaveIdleTimeToLive), Collections
                        .<NodeProperty<?>>emptyList()
        );

        LOGGER.info("Creating slave with " + slaveIdleTimeToLive + "mins time-to-live");

        this.applicationUUID = applicationUUID;
        this.builderType = builderType;
        this.builderSize = builderSize;
        this.builderPlatform = builderPlatform;
        this.builderTimeout = builderTimeout;
    }

    private String getNamespace() {
        return System.getenv("OPENSHIFT_NAMESPACE");
    }

    @Override
    public String getRemoteFS() {
        return "/var/lib/openshift/" + uuid + "/app-root/data/jenkins";
    }

    @Override
    public FilePath getRootPath() {
        return createPath(getRemoteFS());
    }

    @SuppressWarnings("unchecked")
    @Override
    public AbstractCloudComputer<OpenShiftSlave> createComputer() {
        return new OpenShiftComputer(this);
    }

    @Override
    protected void _terminate(TaskListener listener) throws IOException,
            InterruptedException {
        LOGGER.info("Terminating slave " + name + " (uuid: " + uuid + ")");

        if (getComputer() != null && getComputer().getChannel() != null) {
            LOGGER.info("Closing the SSH channel...");
            getComputer().getChannel().close();
        }

        LOGGER.info("Terminating OpenShift application...");
        terminateApp();
    }

    protected IStandaloneCartridge getCartridge(IOpenShiftConnection connection) throws OpenShiftException {

        if(applicationUUID!=null && !applicationUUID.equals("")) {
            // new build configs provide the application uuid for cloning
            IApplication baseApp = Util.getApplicationFromUuid(applicationUUID);
            if(baseApp==null) {
                throw new OpenShiftException("Could not locate application with UUID "+applicationUUID);
            }
            if(baseApp.getCartridge().getUrl()!=null) {
                // downloadable cartridge
                return new StandaloneCartridge(baseApp.getCartridge().getName(), baseApp.getCartridge().getUrl());
            } else {
                // cartridge from repository
                String cartridgeType=baseApp.getCartridge().getName();
                List<IStandaloneCartridge> cartridges = connection.getStandaloneCartridges();
                for (IStandaloneCartridge cartridge : cartridges) {
                  if (cartridge.getName().equals(cartridgeType)) {
                    return cartridge;
                  }
                }
                throw new OpenShiftException("Cartridge for " + cartridgeType + " not found");
            }
        } else {
            // old configs provided the builder type.
            String targetCartridgeName = builderType.replace("redhat-", "");
            List<IStandaloneCartridge> cartridges = connection.getStandaloneCartridges();
            for (IStandaloneCartridge cartridge : cartridges) {
                if (cartridge.getName().equals(targetCartridgeName)) {
                    return cartridge;
                }
            }
            throw new OpenShiftException("Cartridge for " + targetCartridgeName + " not found");
        }
    }

    private void terminateApp() {
        try {
            getBuilderApplication().destroy();
        } catch (Exception e) {
            LOGGER.log(Level.WARNING, "Unable to terminate builder application", e);
        }
    }

    @Extension
    public static final class DescriptorImpl extends SlaveDescriptor {
        public String getDisplayName() {
            return "OpenShift Slave";
        }

        @Override
        public boolean isInstantiable() {
            return false;
        }
    }

    public String getHostName() throws IOException {
        try {
            IApplication app = getBuilderApplication();

            String url = null;

            String type = getCartridge(OpenShiftCloud.get().getOpenShiftConnection()).getName();

            for (IGearGroup gearGroup : app.getGearGroups()) {
                for(ICartridge cart : gearGroup.getCartridges()) {
                    if(cart.getName().equals(type)) {
                        url = ((IGear) gearGroup.getGears().toArray()[0]).getSshUrl();
                        break;
                    }
                }
                if(url != null) break;
            }

            if(url == null) {
                throw new IOException("Unable to find ssh url for " + name);
            }

            if (url.indexOf("@") != -1)
                url = url.substring(url.indexOf("@") + 1);

            url = url.replace("/", "");

            return url;
        } catch (Exception e) {
            throw new IOException("Unable to find application url for " + name, e);
        }
    }

    public void connect(boolean delayDNS) throws IOException {
        LOGGER.info("Connecting to slave " + name + "...");

        try {
            // Force a refresh of the user info to get the application UUID
            IApplication app = getBuilderApplication();

            if (app == null)
                throw new IOException("Failed to connect/find application " + name);

            uuid = app.getGearGroups().iterator().next().getGears().iterator().next().getId();

            LOGGER.info("Established UUID = " + uuid);
        } catch (Exception e) {
            throw new IOException("Unable to connect to application " + name, e);
        }

        // Sleep for 5 seconds for DNS to propagate to minimize cache penalties
        if (delayDNS) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // Ignore
            }
        }

        long startTime = System.currentTimeMillis();
        long currentTime = startTime;
        // Wait until DNS is resolvable
        while (isBuildRunning() && (builderTimeout == -1 || currentTime - startTime < builderTimeout)) {
            try {
                String hostname = getHostName();
                LOGGER.info("Checking to see if slave DNS for " + hostname + " is resolvable ... (timeout: " + builderTimeout + "ms)");
                InetAddress address = InetAddress.getByName(hostname);
                LOGGER.info("Slave DNS resolved - " + address);
                break;
            } catch (UnknownHostException e) {
                LOGGER.info("Slave DNS not propagated yet, retrying... (remaining: " + (builderTimeout - (currentTime - startTime)) + "ms)");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException ie) {
                    // Ignore interruptions
                }
                currentTime = System.currentTimeMillis();
            }
        }

        if (builderTimeout >= 0 && currentTime - startTime >= builderTimeout) {
            LOGGER.warning("Slave DNS not propagated. Timing out.");
            throw new IOException("Slave DNS not propagated. Timing out.");
        }
    }

    protected boolean isBuildRunning() {
        boolean running = true;
        Queue queue = Hudson.getInstance().getQueue();
        if (queue != null) {
            Queue.Item[] items = queue.getItems();
            if (items.length == 0)
                running = false;
        }

        return running;
    }

    public void provision() throws Exception {
        // Create a new application of the right type
        createApp();

        // Force a connection to establish the UUID
        connect(true);
    }

    private void createApp() throws IOException, OpenShiftException {
      IOpenShiftConnection connection = OpenShiftCloud.get().getOpenShiftConnection();
      IUser user = connection.getUser();
      IStandaloneCartridge cartridge = getCartridge(OpenShiftCloud.get().getOpenShiftConnection());

      IDomain domain = user.getDomain(getNamespace());
      List<IGearProfile> gearProfiles = domain.getAvailableGearProfiles();
      IGearProfile gearProfile = gearProfiles.get(0);
      for (IGearProfile profile : gearProfiles) {
        if (profile.getName().equals(builderSize)) {
          gearProfile = profile;
        }
      }

      LOGGER.info("Creating builder application " + cartridge.getName() + " "
              + name + " " + user.getDomain(getNamespace()).getId() + " of size "
              + gearProfile.getName() + " ...");

      ApplicationScale scale = ApplicationScale.NO_SCALE;
      if(builderPlatform.equalsIgnoreCase(Platform.WINDOWS.toString())) {
          scale = ApplicationScale.SCALE;
      }
      IApplication app = domain.createApplication(name, cartridge, scale, gearProfile);

      // No reason to have app running on builder gear - just need it installed
      LOGGER.info("Stopping application on builder gear ...");
      app.stop();
    }

    private IApplication getBuilderApplication() {
        IUser user;
        try {
            user = OpenShiftCloud.get().getOpenShiftConnection().getUser();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return user.getDomain(getNamespace()).getApplicationByName(name);
    }

    public String getUuid() {
        return uuid;
    }

    public enum Platform {
        WINDOWS("Windows"),
        LINUX("Linux");

        private final String platform;

        private Platform(String s) {
            platform = s;
        }

        public String toString(){
            return platform;
        }
    }
}
TOP

Related Classes of hudson.plugins.openshift.OpenShiftSlave$DescriptorImpl

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.