Reference jenkins master in workers.

The "stop:" function should be qualified by the name of the jenkins master
to make it globally unique (eg "stop:jenkins.example.com").

Supply the name of the master in the WORK_DATA that is sent to the client
when the job starts building so that the client can direct a subsequent
"stop:" request to the right worker.

Change-Id: I0112b84ae614ce4faaed880ea3d1073674dfe5fe
This commit is contained in:
James E. Blair 2013-04-29 11:20:59 -07:00
parent 5525624d6f
commit 4e560245c0
8 changed files with 65 additions and 33 deletions

View File

@ -42,35 +42,38 @@ public class CustomGearmanFunctionFactory extends DefaultGearmanFunctionFactory
private final AbstractProject<?,?> project;
private final Node node;
private final String theClass;
private final String masterName;
private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(
Constants.GEARMAN_WORKER_LOGGER_NAME);
public CustomGearmanFunctionFactory(String functionName, String className,
AbstractProject<?,?> project, Node node) {
AbstractProject<?,?> project, Node node,
String masterName) {
super(functionName, className);
this.theClass = className;
this.project = project;
this.node = node;
this.masterName = masterName;
}
@Override
public GearmanFunction getFunction() {
return createFunctionInstance(theClass, project, node);
return createFunctionInstance(theClass, project, node, masterName);
}
private static GearmanFunction createFunctionInstance(String className, AbstractProject<?,?> project, Node node) {
private static GearmanFunction createFunctionInstance(String className, AbstractProject<?,?> project, Node node, String masterName) {
GearmanFunction f = null;
try {
Class<?> c = Class.forName(className);
Constructor<?> con = c.getConstructor(new Class[]{Project.class, Node.class});
Object o = con.newInstance(new Object[] {project, node});
Constructor<?> con = c.getConstructor(new Class[]{Project.class, Node.class, String.class});
Object o = con.newInstance(new Object[] {project, node, masterName});
if (o instanceof GearmanFunction) {
f = (GearmanFunction) o;

View File

@ -49,13 +49,16 @@ public class ExecutorWorkerThread extends AbstractWorkerThread{
.getLogger(Constants.PLUGIN_LOGGER_NAME);
private final Node node;
private final String masterName;
private HashMap<String,GearmanFunctionFactory> functionMap;
// constructor
public ExecutorWorkerThread(String host, int port, String name, Node node) {
public ExecutorWorkerThread(String host, int port, String name, Node node,
String masterName) {
super(host, port, name);
this.node = node;
this.masterName = masterName;
this.functionMap = new HashMap<String,GearmanFunctionFactory>();
}
@ -153,7 +156,7 @@ public class ExecutorWorkerThread extends AbstractWorkerThread{
String jobFunctionName = "build:" + projectName;
newFunctionMap.put(jobFunctionName, new CustomGearmanFunctionFactory(
jobFunctionName, StartJobWorker.class.getName(),
project, this.node));
project, this.node, this.masterName));
} else { // register "build:$projectName:$projectLabel" if this
// node matches a node from the project label
@ -170,12 +173,12 @@ public class ExecutorWorkerThread extends AbstractWorkerThread{
// register with label (i.e. "build:$projectName:$projectLabel")
newFunctionMap.put(jobFunctionName, new CustomGearmanFunctionFactory(
jobFunctionName, StartJobWorker.class.getName(),
project, this.node));
project, this.node, this.masterName));
jobFunctionName = "build:" + projectName;
// also register without label (i.e. "build:$projectName")
newFunctionMap.put(jobFunctionName, new CustomGearmanFunctionFactory(
jobFunctionName, StartJobWorker.class.getName(),
project, this.node));
project, this.node, this.masterName));
}
}
}

View File

@ -46,6 +46,7 @@ public class GearmanProxy {
// handles to gearman workers
private final List<AbstractWorkerThread> gewtHandles;
private final List<AbstractWorkerThread> gmwtHandles;
private final String masterName;
// Singleton instance
public static synchronized GearmanProxy getInstance() {
@ -59,14 +60,23 @@ public class GearmanProxy {
private GearmanProxy() {
gewtHandles = Collections.synchronizedList(new ArrayList<AbstractWorkerThread>());
gmwtHandles = Collections.synchronizedList(new ArrayList<AbstractWorkerThread>());
}
Computer master = null;
String hostname = null;
try {
master = Jenkins.getInstance().getComputer("");
hostname = master.getHostName();
} catch (Exception e) {
logger.info("---- Can't get Master");
e.printStackTrace();
}
masterName = hostname;
}
/*
* This method initializes the gearman workers.
*/
public void initWorkers() {
/*
* Purpose here is to create a 1:1 mapping of 'gearman worker':'jenkins
* executor' then use the gearman worker to execute builds on that
@ -130,7 +140,8 @@ public class GearmanProxy {
AbstractWorkerThread gwt = new ManagementWorkerThread(
GearmanPluginConfig.get().getHost(),
GearmanPluginConfig.get().getPort(),
"master-manager");
masterName + "_manager",
masterName);
//gwt.registerJobs();
gwt.start();
gmwtHandles.add(gwt);
@ -146,11 +157,17 @@ public class GearmanProxy {
int executors = computer.getExecutors().size();
for (int i = 0; i < executors; i++) {
String nodeName = null;
nodeName = GearmanPluginUtil.getRealName(node);
if (nodeName == "master") {
nodeName = masterName;
}
ExecutorWorkerThread ewt = new ExecutorWorkerThread(GearmanPluginConfig.get().getHost(),
GearmanPluginConfig.get().getPort(),
GearmanPluginUtil.getRealName(node)+"-exec-"+Integer.toString(i),
node);
nodeName+"_exec-"+Integer.toString(i),
node, masterName);
//ewt.registerJobs();
ewt.start();

View File

@ -39,8 +39,11 @@ public class ManagementWorkerThread extends AbstractWorkerThread{
.getLogger(Constants.PLUGIN_LOGGER_NAME);
private boolean registered = false;
public ManagementWorkerThread(String host, int port, String name){
private final String masterName;
public ManagementWorkerThread(String host, int port, String name, String masterName){
super(host, port, name);
this.masterName = masterName;
}
/**
@ -53,7 +56,7 @@ public class ManagementWorkerThread extends AbstractWorkerThread{
@Override
public void registerJobs(){
if (!registered) {
String jobFunctionName = "stop:"+host;
String jobFunctionName = "stop:"+masterName;
logger.info("---- Registering job "+jobFunctionName+" on "+host);
Set<GearmanFunctionFactory> functionSet = new HashSet<GearmanFunctionFactory>();

View File

@ -73,10 +73,12 @@ public class StartJobWorker extends AbstractGearmanFunction {
Node node;
Project<?, ?> project;
String masterName;
public StartJobWorker(Project<?, ?> project, Node node) {
public StartJobWorker(Project<?, ?> project, Node node, String masterName) {
this.project = project;
this.node = node;
this.masterName = masterName;
}
private String buildStatusData(AbstractBuild<?, ?> build) {
@ -89,6 +91,7 @@ public class StartJobWorker extends AbstractGearmanFunction {
data.put("number", build.getNumber());
data.put("id", build.getId());
data.put("url", build.getUrl());
data.put("master", masterName);
String rootUrl = Hudson.getInstance().getRootUrl();
if (rootUrl != null) {

View File

@ -65,7 +65,7 @@ public class ExecutorWorkerThreadTest extends HudsonTestCase {
Project<?, ?> apple = createFreeStyleProject("apple");
apple.setAssignedLabel(new LabelAtom("oneiric-10"));
AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", slave);
AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", slave, "master");
oneiric.registerJobs();
Set<String> functions = oneiric.worker.getRegisteredFunctions();
@ -85,7 +85,7 @@ public class ExecutorWorkerThreadTest extends HudsonTestCase {
Project<?, ?> lemon = createFreeStyleProject("lemon");
lemon.setAssignedLabel(new LabelAtom("linux"));
AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", slave);
AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", slave, "master");
oneiric.registerJobs();
Set<String> functions = oneiric.worker.getRegisteredFunctions();
@ -105,7 +105,7 @@ public class ExecutorWorkerThreadTest extends HudsonTestCase {
Project<?, ?> lemon = createFreeStyleProject("lemon");
lemon.setAssignedLabel(new LabelAtom("bogus"));
AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", slave);
AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", slave, "master");
oneiric.registerJobs();
Set<String> functions = oneiric.worker.getRegisteredFunctions();
@ -122,7 +122,7 @@ public class ExecutorWorkerThreadTest extends HudsonTestCase {
Project<?, ?> lemon = createFreeStyleProject("lemon");
AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", slave);
AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", slave, "master");
oneiric.registerJobs();
Set<String> functions = oneiric.worker.getRegisteredFunctions();
@ -142,7 +142,7 @@ public class ExecutorWorkerThreadTest extends HudsonTestCase {
lemon.setAssignedLabel(new LabelAtom("linux"));
lemon.disable();
AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", slave);
AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", slave, "master");
oneiric.registerJobs();
Set<String> functions = oneiric.worker.getRegisteredFunctions();
@ -163,7 +163,7 @@ public class ExecutorWorkerThreadTest extends HudsonTestCase {
Project<?, ?> lemon = createFreeStyleProject("lemon");
lemon.setAssignedLabel(new LabelAtom("linux"));
AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", offlineSlave);
AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", offlineSlave, "master");
oneiric.registerJobs();
Set<String> functions = oneiric.worker.getRegisteredFunctions();
@ -181,7 +181,7 @@ public class ExecutorWorkerThreadTest extends HudsonTestCase {
MavenModuleSet lemon = createMavenProject("lemon");
lemon.setAssignedLabel(new LabelAtom("linux"));
AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", slave);
AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", slave, "master");
oneiric.registerJobs();
Set<String> functions = oneiric.worker.getRegisteredFunctions();
@ -202,7 +202,7 @@ public class ExecutorWorkerThreadTest extends HudsonTestCase {
Project<?, ?> lemon = createFreeStyleProject("lemon");
lemon.setAssignedLabel(new LabelAtom("!linux"));
AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", slave);
AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", slave, "master");
oneiric.registerJobs();
Set<String> functions = oneiric.worker.getRegisteredFunctions();

View File

@ -56,13 +56,14 @@ public class GearmanProxyTest extends HudsonTestCase {
assertEquals(0, gp.getNumExecutors());
gp.getGewtHandles().add(new ExecutorWorkerThread("localhost", 4730, "test-exec-0", slave));
gp.getGewtHandles().add(new ExecutorWorkerThread("localhost", 4730, "test-exec-1", slave));
gp.getGewtHandles().add(new ExecutorWorkerThread("localhost", 4730, "test-exec-2", slave));
gp.getGewtHandles().add(new ExecutorWorkerThread("localhost", 4730, "test_exec-0", slave, "master"));
gp.getGewtHandles().add(new ExecutorWorkerThread("localhost", 4730, "test_exec-1", slave, "master"));
gp.getGewtHandles().add(new ExecutorWorkerThread("localhost", 4730, "test_exec-2", slave, "master"));
assertEquals(3, gp.getNumExecutors());
gp.getGewtHandles().add(new ManagementWorkerThread("localhost", 4730, "manage-exec-2"));
gp.getGewtHandles().add(new ManagementWorkerThread("localhost", 4730,
"master_manage", "master"));
assertEquals(4, gp.getNumExecutors());
}

View File

@ -56,16 +56,18 @@ public class ManagementWorkerThreadTest {
@Test
public void testRegisterJobs() {
AbstractWorkerThread manager = new ManagementWorkerThread("GearmanServer", 4730, "manager");
AbstractWorkerThread manager = new ManagementWorkerThread("GearmanServer", 4730,
"master_manager", "master");
manager.registerJobs();
Set<String> functions = manager.worker.getRegisteredFunctions();
assertEquals("stop:GearmanServer", functions.toArray()[0]);
assertEquals("stop:master", functions.toArray()[0]);
}
@Test
public void testManagerId() {
AbstractWorkerThread manager = new ManagementWorkerThread("GearmanServer", 4730, "manager");
assertEquals("manager", manager.getName());
AbstractWorkerThread manager = new ManagementWorkerThread("GearmanServer", 4730,
"master_manager", "master");
assertEquals("master_manager", manager.getName());
}
}