diff --git a/pom.xml b/pom.xml index 7329483..ca79507 100644 --- a/pom.xml +++ b/pom.xml @@ -17,322 +17,336 @@ --> + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - 4.0.0 + 4.0.0 - - org.jenkins-ci.plugins - plugin - 1.460 - + + org.jenkins-ci.plugins + plugin + 1.460 + - gearman-plugin - hpi + gearman-plugin + hpi - Gearman Plugin - http://wiki.jenkins-ci.org/display/JENKINS/Gearman+Plugin + Gearman Plugin + http://wiki.jenkins-ci.org/display/JENKINS/Gearman+Plugin - - - Apache License Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt + + + Apache License Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt repo - - + + - - - khaido - Khai Do - do.khai@gmail.com - - + + + khaido + Khai Do + do.khai@gmail.com + + - - scm:git:git://github.com/openstack-infra/gearman-plugin.git - scm:git:git@github.com:openstack-infra/gearman-plugin.git - https://github.com/openstack-infra/gearman-plugin - + + scm:git:git://github.com/openstack-infra/gearman-plugin.git + scm:git:git@github.com:openstack-infra/gearman-plugin.git + https://github.com/openstack-infra/gearman-plugin + - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - - + + + repo.jenkins-ci.org + http://repo.jenkins-ci.org/public/ + + + dev.nightlabs.org + http://dev.nightlabs.org/maven-repository/repo/ + + - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - - + + + repo.jenkins-ci.org + http://repo.jenkins-ci.org/public/ + + - - - java.net-m2-repository - http://maven.jenkins-ci.org/content/repositories/releases/ - - - github-project-site - gitsite:git@github.com/openstack-infra/gearman-plugin - - + + + java.net-m2-repository + http://maven.jenkins-ci.org/content/repositories/releases/ + + + github-project-site + gitsite:git@github.com/openstack-infra/gearman-plugin + + - - - UTF-8 - 1.6 - - 3.0.1 - 1.6 - 2.2 - 2.2 - 2.6 - 2.4.1 - 2.3.2 - 2.1 - 2.5 - 1.0 - 2.8 - 1.0 - 2.1.1 - 2.3.1 - 2.7 - 2.3.1 - 6.1.26 - 2.2 - 2.5 - 2.3.1 - 2.4.3 - 1.0 - 2.1 - 1.1 - 2.4.3 - 2.1.1 - 2.1.2 - 2.7.2 - 2.7.2 - 2.1.1 - 1.0-alpha-4 - 1.4 - 1.0-beta-4 - 1.5 - 1.0.5 - 2.4 - 1.2 - 2.3.1 - 2.1.0-1 - 2.0 - 2.0-beta-2 - 1.2 - 2.4 - 1.2 - 1.0-beta-3 - + + + UTF-8 + 1.6 + + 3.0.1 + 1.6 + 2.2 + 2.2 + 2.6 + 2.4.1 + 2.3.2 + 2.1 + 2.5 + 1.0 + 2.8 + 1.0 + 2.1.1 + 2.3.1 + 2.7 + 2.3.1 + 6.1.26 + 2.2 + 2.5 + 2.3.1 + 2.4.3 + 1.0 + 2.1 + 1.1 + 2.4.3 + 2.1.1 + 2.1.2 + 2.7.2 + 2.7.2 + 2.1.1 + 1.0-alpha-4 + 1.4 + 1.0-beta-4 + 1.5 + 1.0.5 + 2.4 + 1.2 + 2.3.1 + 2.1.0-1 + 2.0 + 2.0-beta-2 + 1.2 + 2.4 + 1.2 + 1.0-beta-3 + - - - - org.apache.maven.scm - maven-scm-provider-gitexe - 1.3 - - - org.apache.maven.scm - maven-scm-manager-plexus - 1.3 - - - org.kathrynhuxtable.maven.wagon - wagon-gitsite - 0.3.1 - - - - - - maven-clean-plugin - ${maven-clean-plugin.version} - - - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${compileSource} - ${compileTarget} - true - true - - - - maven-deploy-plugin - ${maven-deploy-plugin.version} - - - maven-enforcer-plugin - ${maven-enforcer-plugin.version} - - - maven-install-plugin - ${maven-install-plugin.version} - - - maven-jar-plugin - ${maven-jar-plugin.version} - - - maven-release-plugin - ${maven-release-plugin.version} - - true - true - clean deploy - clean deploy - release - - - - maven-remote-resources-plugin - ${maven-remote-resources-plugin.version} - - - maven-resources-plugin - ${maven-resources-plugin.version} - - - maven-site-plugin - ${maven-site-plugin.version} - - - maven-source-plugin - ${maven-source-plugin.version} - - - maven-surefire-plugin - ${maven-surefire-plugin.version} - - methods - true - 4 - - - - - - - maven-doap-plugin - ${maven-doap-plugin.version} - - - site - pre-site - - generate - - - - - ${project.reporting.outputDirectory}/doap.rdf - - false - - - - - maven-site-plugin - ${maven-site-plugin.version} - - - + + + + org.apache.maven.scm + maven-scm-provider-gitexe + 1.3 + + + org.apache.maven.scm + maven-scm-manager-plexus + 1.3 + + + org.kathrynhuxtable.maven.wagon + wagon-gitsite + 0.3.1 + + + + + + maven-clean-plugin + ${maven-clean-plugin.version} + + + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${compileSource} + ${compileTarget} + true + true + + + + maven-deploy-plugin + ${maven-deploy-plugin.version} + + + maven-enforcer-plugin + ${maven-enforcer-plugin.version} + + + maven-install-plugin + ${maven-install-plugin.version} + + + maven-jar-plugin + ${maven-jar-plugin.version} + + + maven-release-plugin + ${maven-release-plugin.version} + + true + true + clean deploy + clean deploy + release + + + + maven-remote-resources-plugin + ${maven-remote-resources-plugin.version} + + + maven-resources-plugin + ${maven-resources-plugin.version} + + + maven-site-plugin + ${maven-site-plugin.version} + + + maven-source-plugin + ${maven-source-plugin.version} + + + maven-surefire-plugin + ${maven-surefire-plugin.version} + + methods + true + 4 + + + + + + + maven-doap-plugin + ${maven-doap-plugin.version} + + + site + pre-site + + generate + + + + + ${project.reporting.outputDirectory}/doap.rdf + + false + + + + + maven-site-plugin + ${maven-site-plugin.version} + + + - - - - maven-changelog-plugin - ${maven-changelog-plugin.version} - - - maven-checkstyle-plugin - ${maven-checkstyle-plugin.version} - - - maven-javadoc-plugin - ${maven-javadoc-plugin.version} - - - maven-jxr-plugin - ${maven-jxr-plugin.version} - - - maven-pmd-plugin - ${maven-pmd-plugin.version} - - - maven-plugin-plugin - ${maven-plugin-plugin.version} - - - maven-project-info-reports-plugin - ${maven-project-info-reports-plugin.version} - - - - cim - distribution-management - index - issue-tracking - license - mailing-list - project-team - scm - summary - - - - - - maven-surefire-report-plugin - ${maven-surefire-report-plugin.version} - - - org.codehaus.mojo - cobertura-maven-plugin - ${cobertura-maven-plugin.version} - - - org.codehaus.mojo - findbugs-maven-plugin - ${findbugs-maven-plugin.version} - - - org.codehaus.mojo - javancss-maven-plugin - ${javancss-maven-plugin.version} - - - org.codehaus.mojo - jdepend-maven-plugin - ${jdepend-maven-plugin.version} - - - org.codehaus.mojo - taglist-maven-plugin - ${taglist-maven-plugin.version} - - - - - - org.slf4j - slf4j-api - 1.6.1 - - - org.slf4j - slf4j-simple - 1.7.2 - - + + + + maven-changelog-plugin + ${maven-changelog-plugin.version} + + + maven-checkstyle-plugin + ${maven-checkstyle-plugin.version} + + + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + + maven-jxr-plugin + ${maven-jxr-plugin.version} + + + maven-pmd-plugin + ${maven-pmd-plugin.version} + + + maven-plugin-plugin + ${maven-plugin-plugin.version} + + + maven-project-info-reports-plugin + ${maven-project-info-reports-plugin.version} + + + + cim + distribution-management + index + issue-tracking + license + mailing-list + project-team + scm + summary + + + + + + maven-surefire-report-plugin + ${maven-surefire-report-plugin.version} + + + org.codehaus.mojo + cobertura-maven-plugin + ${cobertura-maven-plugin.version} + + + org.codehaus.mojo + findbugs-maven-plugin + ${findbugs-maven-plugin.version} + + + org.codehaus.mojo + javancss-maven-plugin + ${javancss-maven-plugin.version} + + + org.codehaus.mojo + jdepend-maven-plugin + ${jdepend-maven-plugin.version} + + + org.codehaus.mojo + taglist-maven-plugin + ${taglist-maven-plugin.version} + + + + + + org.slf4j + slf4j-api + 1.6.1 + + + org.slf4j + slf4j-simple + 1.7.2 + + + org.gearman + gearman-java + 0.6-SNAPSHOT + + + com.google.code.gson + gson + 2.2.2 + + diff --git a/src/main/java/hudson/plugins/gearman/AbstractWorkerThread.java b/src/main/java/hudson/plugins/gearman/AbstractWorkerThread.java index 50e1171..d097c8d 100644 --- a/src/main/java/hudson/plugins/gearman/AbstractWorkerThread.java +++ b/src/main/java/hudson/plugins/gearman/AbstractWorkerThread.java @@ -19,57 +19,74 @@ package hudson.plugins.gearman; import java.util.Date; +import java.util.UUID; +import org.gearman.common.GearmanNIOJobServerConnection; +import org.gearman.worker.GearmanWorker; +import org.gearman.worker.GearmanWorkerImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class AbstractWorkerThread implements Runnable { +/* + * Thread to run gearman worker + */ - public static final String DEFAULT_NAME = "anonymous"; - public static final String DEFAULT_HOST = "localhost"; - public static final int DEFAULT_PORT = 4730; +public abstract class AbstractWorkerThread implements Runnable { + + public static final String DEFAULT_EXECUTOR_NAME = "anonymous"; private static final Logger logger = LoggerFactory - .getLogger(AbstractWorkerThread.class); + .getLogger(Constants.PLUGIN_EXECTUOR_LOGGER_NAME); protected String host; protected int port; protected String name; + protected GearmanWorker worker; + private GearmanNIOJobServerConnection conn; private Thread thread; - public AbstractWorkerThread() { - this(DEFAULT_HOST, DEFAULT_PORT, DEFAULT_NAME); - } - - public AbstractWorkerThread(String host, int port) { - this(host, port, DEFAULT_NAME); - } - public AbstractWorkerThread(String host, int port, String name) { this.name = name; this.host = host; this.port = port; + worker = new GearmanWorkerImpl(); + conn = new GearmanNIOJobServerConnection(host, port); + } + /* + * Register jobs with the gearman worker. This method should be overriden. + */ public void registerJobs() { logger.info("----- AbstractorWorker registerJobs function ----"); } + /* + * Start the thread + */ public void start() { thread = new Thread(this); thread.start(); } + /* + * Stop the thread + */ public void stop() { // Interrupt the thread so it unblocks any blocking call - logger.info("Stopping " + name + " (" + new Date().toString() + ")"); + if (worker.isRunning()) { + logger.info("Stopping " + name + " (" + new Date().toString() + ")"); + worker.stop(); + logger.info("Stopped " + name + " (" + new Date().toString() + ")"); + } thread.interrupt(); // Wait until the thread exits try { + thread.join(); } catch (InterruptedException ex) { // Unexpected interruption @@ -77,14 +94,24 @@ public class AbstractWorkerThread implements Runnable { System.exit(1); } - logger.info("Stopped " + name + " (" + new Date().toString() + ")"); - } + /* + * Execute the thread (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ @Override public void run() { - logger.info("Starting Worker "+ name +" ("+new Date().toString()+")"); + if (!worker.isRunning()) { + logger.info("Starting Worker " + name + " (" + + new Date().toString() + ")"); + worker.setWorkerID(UUID.randomUUID().toString()); + worker.addServer(conn); + // blocking call.. https://answers.launchpad.net/gearman-java/+question/219175 + worker.work(); + } while (!Thread.interrupted()) { @@ -92,8 +119,8 @@ public class AbstractWorkerThread implements Runnable { logger.info("Running Worker "+ name +" ("+new Date().toString()+")"); try { - Thread.sleep(1000); - } catch(InterruptedException ex) { + Thread.sleep(5000); + } catch (InterruptedException ex) { Thread.currentThread().interrupt(); } diff --git a/src/main/java/hudson/plugins/gearman/Constants.java b/src/main/java/hudson/plugins/gearman/Constants.java new file mode 100644 index 0000000..8ada2ef --- /dev/null +++ b/src/main/java/hudson/plugins/gearman/Constants.java @@ -0,0 +1,32 @@ +/* + * + * Copyright 2013 Hewlett-Packard Development Company, L.P. + * + * 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 hudson.plugins.gearman; + +/* + * Constants for the Gearman Plugin + */ +public interface Constants { + /* Defines. */ + + public static final String GEARMAN_DEFAULT_TCP_HOST = "127.0.0.1"; + public static final int GEARMAN_DEFAULT_TCP_PORT = 4730; + + public static final String PLUGIN_LOGGER_NAME = "hudson.plugins.gearman.logger"; + public static final String PLUGIN_EXECTUOR_LOGGER_NAME = "hudson.plugins.gearman.executor.logger"; +} diff --git a/src/main/java/hudson/plugins/gearman/ExecutorWorkerThread.java b/src/main/java/hudson/plugins/gearman/ExecutorWorkerThread.java index 15c5f4a..f10c43c 100644 --- a/src/main/java/hudson/plugins/gearman/ExecutorWorkerThread.java +++ b/src/main/java/hudson/plugins/gearman/ExecutorWorkerThread.java @@ -18,26 +18,61 @@ package hudson.plugins.gearman; -import java.util.Date; +import hudson.model.Node; + +import java.util.List; + +import jenkins.model.Jenkins; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ExecutorWorkerThread extends AbstractWorkerThread { +/* + * This is thread to run gearman executors + * Executors are used to initiate jenkins builds + */ +public class ExecutorWorkerThread extends AbstractWorkerThread{ private static final Logger logger = LoggerFactory .getLogger(AbstractWorkerThread.class); - public ExecutorWorkerThread(String host, int port, String name) { + private Node node; + + public ExecutorWorkerThread(String host, int port, String nodeName){ + super(host, port, nodeName); + this.node = findNode(nodeName); + + } + + /* + * This function finds the node with the corresponding node name Returns the + * node if found, otherwise returns null + */ + private Node findNode(String nodeName){ + + Jenkins jenkins = Jenkins.getInstance(); + List nodes = jenkins.getNodes(); + Node myNode = null; + + for (Node node : nodes) { + if (node.getNodeName().equals(nodeName)){ + myNode = node; + } + } + + return myNode; + } + + public ExecutorWorkerThread(String host, int port, String name, Node node){ super(host, port, name); + this.node = node; } @Override public void registerJobs() { - logger.info("----- ExecutorWorkerThread registerJobs function ----"); - logger.info("----- Register executor jobs here ----"); + logger.info("----- Registering executor jobs on " + name + " ----"); } diff --git a/src/main/java/hudson/plugins/gearman/GearmanPlugin.java b/src/main/java/hudson/plugins/gearman/GearmanPlugin.java index 17345d8..c103e6d 100644 --- a/src/main/java/hudson/plugins/gearman/GearmanPlugin.java +++ b/src/main/java/hudson/plugins/gearman/GearmanPlugin.java @@ -18,11 +18,16 @@ package hudson.plugins.gearman; +import java.util.List; +import java.util.Stack; + import hudson.Launcher; import hudson.Extension; import hudson.model.Build; import hudson.model.BuildListener; import hudson.model.AbstractBuild; +import hudson.model.Computer; +import hudson.model.Node; import hudson.tasks.Builder; import hudson.tasks.BuildStepDescriptor; @@ -34,6 +39,8 @@ import org.slf4j.LoggerFactory; import javax.management.Descriptor; +import jenkins.model.Jenkins; + import net.sf.json.JSONObject; /** @@ -49,7 +56,7 @@ import net.sf.json.JSONObject; public class GearmanPlugin extends Builder { private static final Logger logger = LoggerFactory - .getLogger(GearmanPlugin.class); + .getLogger(Constants.PLUGIN_LOGGER_NAME); private final String name; @DataBoundConstructor @@ -79,13 +86,25 @@ public class GearmanPlugin extends Builder { BuildStepDescriptor { private static final Logger logger = LoggerFactory - .getLogger(DescriptorImpl.class); + .getLogger(Constants.PLUGIN_LOGGER_NAME); private boolean launchWorker; // launchWorker state (from UI checkbox) private String host; // gearman server host private int port; // gearman server port + private Jenkins jenkins; + public static Stack gewtHandles; // handles to + // executor + // workers + public static Stack gmwtHandles; // handles to + // management + // workers public DescriptorImpl() { logger.info("--- DescriptorImpl Constructor ---"); + + jenkins = Jenkins.getInstance(); + gewtHandles = new Stack(); + gmwtHandles = new Stack(); + logger.info("--- DescriptorImpl Constructor ---" + host); logger.info("--- DescriptorImpl Constructor ---" + port); @@ -125,7 +144,7 @@ public class GearmanPlugin extends Builder { "Error getting the gearman host name"); } - // user input vaerification + // user input verification if (StringUtils.isEmpty(host) || StringUtils.isBlank(host)) throw new RuntimeException("Invalid gearman host name"); @@ -146,6 +165,52 @@ public class GearmanPlugin extends Builder { logger.info("--- DescriptorImpl Configure function ---" + this.getPort()); + /* + * Purpose here is to create a 1:1 mapping of 'gearman + * worker':'jenkins node' then use the gearman worker to execute + * builds on that jenkins node + */ + List nodes = jenkins.getNodes(); + + if (launchWorker && !nodes.isEmpty()) { + + AbstractWorkerThread gwt = null; + + for (Node node : nodes) { + Computer c = node.toComputer(); + if (c.isOnline()) { + // create a gearman executor for every node + gwt = new ExecutorWorkerThread(host, port, + node.getNodeName()); + gwt.registerJobs(); + gwt.start(); + gewtHandles.push(gwt); + } + } + + /* + * Create one additional worker as a management node. This + * worker will be used to abort builds. + */ + if (!gewtHandles.isEmpty()) { + gwt = new ManagementWorkerThread(host, port, host); + gwt.registerJobs(); + gwt.start(); + gmwtHandles.push(gwt); + + } + + } else if (!launchWorker) { // stop worker threads + while (!gewtHandles.isEmpty()) { // stop executors + AbstractWorkerThread task = gewtHandles.pop(); + task.stop(); + } + while (!gmwtHandles.isEmpty()) { // stop management + AbstractWorkerThread task = gmwtHandles.pop(); + task.stop(); + } + } + save(); return true; } diff --git a/src/main/java/hudson/plugins/gearman/ManagementWorkerThread.java b/src/main/java/hudson/plugins/gearman/ManagementWorkerThread.java index 92850c1..198f897 100644 --- a/src/main/java/hudson/plugins/gearman/ManagementWorkerThread.java +++ b/src/main/java/hudson/plugins/gearman/ManagementWorkerThread.java @@ -18,11 +18,15 @@ package hudson.plugins.gearman; -import java.util.Date; - +import org.gearman.worker.DefaultGearmanFunctionFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/* + * This is a thread to manage gearman executors + * This is used to abort/delete jenkins jobs. + */ + public class ManagementWorkerThread extends AbstractWorkerThread { private static final Logger logger = LoggerFactory @@ -37,8 +41,7 @@ public class ManagementWorkerThread extends AbstractWorkerThread { @Override public void registerJobs() { - logger.info("----- ManagementWorkerThread registerJobs function ----"); - logger.info("----- Register management jobs here ----"); + logger.info("----- Registering management jobs on " + name + " ----"); }