Fix to register all projects and register an additional gearman function for each project.

Jenkins.getProjects() wasn't returning maven and multi-config projects.
This change now attempts to register all projects.  The only caveat
is that the multi-config projects don't get registered quite right
because the labels are treated differently in that project.  I don't
plan to fix multi-config project registration because openstack
doesn't have any of those projects setup in jenkins.

Register an additional function for each executor worker.  We register
a generic "build:$projectName" function on each executor
that can run a build on $projectName.

Minor change, set gearman-plugin version to 'SNAPSHOT'.  The maven
release plugin will convert to a non-SNAPSHOT version on release.

Change-Id: I49a0f73d297e61657fb6f31f26e87c181a644115
This commit is contained in:
zaro 2013-02-15 09:53:51 -08:00
parent 56085bbf45
commit b734f0cd21
5 changed files with 32 additions and 46 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
/target /target
/work /work
/.config

View File

@ -29,7 +29,7 @@
<artifactId>gearman-plugin</artifactId> <artifactId>gearman-plugin</artifactId>
<packaging>hpi</packaging> <packaging>hpi</packaging>
<version>0.0.1</version> <version>0.0.1-SNAPSHOT</version>
<name>Gearman Plugin</name> <name>Gearman Plugin</name>
<url>http://wiki.jenkins-ci.org/display/JENKINS/Gearman+Plugin</url> <url>http://wiki.jenkins-ci.org/display/JENKINS/Gearman+Plugin</url>

View File

@ -26,6 +26,7 @@
package hudson.plugins.gearman; package hudson.plugins.gearman;
import hudson.model.AbstractProject;
import hudson.model.Node; import hudson.model.Node;
import hudson.model.Project; import hudson.model.Project;
@ -38,7 +39,7 @@ import org.slf4j.LoggerFactory;
public class CustomGearmanFunctionFactory extends DefaultGearmanFunctionFactory { public class CustomGearmanFunctionFactory extends DefaultGearmanFunctionFactory {
private final Project<?,?> project; private final AbstractProject<?,?> project;
private final Node node; private final Node node;
private final String theClass; private final String theClass;
@ -46,7 +47,7 @@ public class CustomGearmanFunctionFactory extends DefaultGearmanFunctionFactory
Constants.GEARMAN_WORKER_LOGGER_NAME); Constants.GEARMAN_WORKER_LOGGER_NAME);
public CustomGearmanFunctionFactory(String functionName, String className, public CustomGearmanFunctionFactory(String functionName, String className,
Project<?,?> project, Node node) { AbstractProject<?,?> project, Node node) {
super(functionName, className); super(functionName, className);
this.theClass = className; this.theClass = className;
this.project = project; this.project = project;
@ -62,7 +63,7 @@ public class CustomGearmanFunctionFactory extends DefaultGearmanFunctionFactory
private static GearmanFunction createFunctionInstance(String className, Project<?,?> project, Node node) { private static GearmanFunction createFunctionInstance(String className, AbstractProject<?,?> project, Node node) {
GearmanFunction f = null; GearmanFunction f = null;
try { try {

View File

@ -18,9 +18,9 @@
package hudson.plugins.gearman; package hudson.plugins.gearman;
import hudson.model.AbstractProject;
import hudson.model.Label; import hudson.model.Label;
import hudson.model.Node; import hudson.model.Node;
import hudson.model.Project;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -34,8 +34,11 @@ import org.slf4j.LoggerFactory;
/* /*
* This is thread to run gearman executors * This is the thread to run gearman executors
* Executors are used to initiate jenkins builds * Executors are used to initiate jenkins builds
*
* @author Khai Do
*
*/ */
public class ExecutorWorkerThread extends AbstractWorkerThread{ public class ExecutorWorkerThread extends AbstractWorkerThread{
@ -50,31 +53,6 @@ public class ExecutorWorkerThread extends AbstractWorkerThread{
this.node = node; this.node = node;
} }
/**
* This function finds the node with the corresponding node name Returns the
* node if found, otherwise returns null
*
* @param name
* The name of the jenkins node.
* @return
* The jenkins node if found, otherwise null
*/
private Node findNode(String nodeName){
Jenkins jenkins = Jenkins.getInstance();
List<Node> nodes = jenkins.getNodes();
Node myNode = null;
for (Node node : nodes) {
if (node.getNodeName().equals(nodeName)){
myNode = node;
}
}
return myNode;
}
/** /**
* This function tokenizes the labels in a label string * This function tokenizes the labels in a label string
* that is set in the jenkins projects * that is set in the jenkins projects
@ -100,7 +78,6 @@ public class ExecutorWorkerThread extends AbstractWorkerThread{
if (label != null) { if (label != null) {
// String projectLabelString = label.getExpression();
Scanner slabel = new Scanner(label); Scanner slabel = new Scanner(label);
try { try {
slabel.useDelimiter(pattern); slabel.useDelimiter(pattern);
@ -118,14 +95,14 @@ public class ExecutorWorkerThread extends AbstractWorkerThread{
/** /**
* Register gearman functions on this node. This will unregister all * Register gearman functions on this node. This will unregister all
* functions before registering new functions. * functions before registering new functions. Works for free-style
* and maven projects but does not work for multi-config projects
* *
* How functions are registered: * How functions are registered:
* - If the project has no label then we register the project with all * - If the project has no label then we register the project with all
* nodes * nodes
* *
* build:pep8 on precise-123 * build:pep8 on precise-123
* build:pep8 on precise-129
* build:pep8 on oneiric-456 * build:pep8 on oneiric-456
* *
* - If the project contains one label then we register with the node * - If the project contains one label then we register with the node
@ -133,16 +110,21 @@ public class ExecutorWorkerThread extends AbstractWorkerThread{
* considered just one label * considered just one label
* *
* build:pep8:precise on precise-123 * build:pep8:precise on precise-123
* build:pep8 on precise-123
* build:pep8:precise on precise-129 * build:pep8:precise on precise-129
* build:pep8:precise on precise-134 * build:pep8 on precise-129
* *
* - If the project contains multiple labels seperated by '||' then * - If the project contains multiple labels separated by '||' then
* we register with the nodes that contain the corresponding labels * we register with the nodes that contain the corresponding labels
* *
* build:pep8:precise on precise-123 * build:pep8:precise on precise-123
* build:pep8 on precise-123
* build:pep8:precise on precise-129 * build:pep8:precise on precise-129
* build:pep8 on precise-129
* build:pep8:oneiric on oneiric-456 * build:pep8:oneiric on oneiric-456
* build:pep8 on oneiric-456
* build:pep8:oneiric on oneiric-459 * build:pep8:oneiric on oneiric-459
* build:pep8 on oneiric-459
* *
*/ */
@Override @Override
@ -160,11 +142,8 @@ public class ExecutorWorkerThread extends AbstractWorkerThread{
*/ */
Jenkins jenkins = Jenkins.getInstance(); Jenkins jenkins = Jenkins.getInstance();
List<Project> allProjects = jenkins.getProjects(); List<AbstractProject> allProjects = jenkins.getAllItems(AbstractProject.class);
// this call dies with NPE if there is a project without any labels for (AbstractProject<?, ?> project : allProjects) {
// List<AbstractProject> projects =
// jenkins.getAllItems(AbstractProject.class);
for (Project<?, ?> project : allProjects) {
if (project.isDisabled()) { // ignore all disabled projects if (project.isDisabled()) { // ignore all disabled projects
continue; continue;
@ -182,8 +161,8 @@ public class ExecutorWorkerThread extends AbstractWorkerThread{
jobFunctionName, StartJobWorker.class.getName(), jobFunctionName, StartJobWorker.class.getName(),
project, this.node)); project, this.node));
} else { // register "build:projectName:nodeName" on the } else { // register "build:$projectName:$projectLabel" if this
// node that has a matching label // node matches a node from the project label
Set<Node> projectLabelNodes = label.getNodes(); Set<Node> projectLabelNodes = label.getNodes();
String projectLabelString = label.getExpression(); String projectLabelString = label.getExpression();
@ -197,9 +176,15 @@ public class ExecutorWorkerThread extends AbstractWorkerThread{
+ ":" + projectLabel; + ":" + projectLabel;
logger.info("Registering job " + jobFunctionName logger.info("Registering job " + jobFunctionName
+ " on " + this.node.getNodeName()); + " on " + this.node.getNodeName());
// register with label (i.e. "build:$projectName:$projectLabel")
worker.registerFunctionFactory(new CustomGearmanFunctionFactory( worker.registerFunctionFactory(new CustomGearmanFunctionFactory(
jobFunctionName, StartJobWorker.class jobFunctionName, StartJobWorker.class
.getName(), project, this.node)); .getName(), project, this.node));
// also register without label (i.e. "build:$projectName")
worker.registerFunctionFactory(new CustomGearmanFunctionFactory(
"build:" + projectName, StartJobWorker.class
.getName(), project, this.node));
} }
} }
} }

View File

@ -24,7 +24,7 @@ import org.slf4j.LoggerFactory;
/** /**
* This is a thread to run gearman management workers * This is a thread to run gearman management worker
* *
* @author Khai Do * @author Khai Do
*/ */
@ -33,7 +33,6 @@ public class ManagementWorkerThread extends AbstractWorkerThread{
private static final Logger logger = LoggerFactory private static final Logger logger = LoggerFactory
.getLogger(AbstractWorkerThread.class); .getLogger(AbstractWorkerThread.class);
private Thread thread;
public ManagementWorkerThread(String host, int port, String name){ public ManagementWorkerThread(String host, int port, String name){
super(host, port, name); super(host, port, name);
@ -49,7 +48,7 @@ public class ManagementWorkerThread extends AbstractWorkerThread{
@Override @Override
public void registerJobs(){ public void registerJobs(){
String jobFunctionName = "stop:"+host; String jobFunctionName = "stop:"+host;
System.out.println("Registering job "+jobFunctionName+" on "+host); logger.info("Registering job "+jobFunctionName+" on "+host);
worker.registerFunctionFactory(new DefaultGearmanFunctionFactory(jobFunctionName, worker.registerFunctionFactory(new DefaultGearmanFunctionFactory(jobFunctionName,
StopJobWorker.class.getName())); StopJobWorker.class.getName()));