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}
-
-
- ${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}
+
+
+ ${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 + " ----");
}