summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKhai Do <zaro0508@gmail.com>2014-10-02 12:44:49 -0700
committerKhai Do <zaro0508@gmail.com>2014-10-15 14:21:08 -0700
commit6307ba2225bbc9e8d4f41062bd6b944e40d7fa7a (patch)
tree03d701f4fa85932a263592476e0364397a726ec7
parent6961c9d441264818c53e08bd15e002430457980b (diff)
update to work with Jenkins LTS ver 1.565.30.1.0
This change updates the gearman-plugin to build against Jenkins LTS ver 1.565.3. This is required to support later versions of Jenkins because there have been changes to Jenkins events in core. This change adds the ItemListener to re-register gearman functions on changes to jenkins projects. Using the ItemListener is better because it provides more details on the item that's been changed and the events are more grandular. There was also a change to ComputerListener events (onTemporaryOffline and onTemporaryOnline) that needed to be handled seperately in this change. The SaveableListener is still needed due to a bug in ItemListener. The most notable change to function registration is that the gearman plugin will no longer register functions containing a node's self label. For example: Assume you have the following setup: a node: named 'trusty-slave1' and labeled 'trusty' a job: named 'my-job' that targets the 'trusty' label The gearman plugin used to register the following functions: 'build:my-job', 'build:my-job:trusty' and 'build:my-job:trusty-slave1' With this update the gearman plugin will only register 'build:my-job' and 'build:my-job:trusty'. It will no longer register functions containing the implicit node name (trusty-slave1). If your gearman client has been using explicit labels to execute builds then this change will not affect your workflow. Closes-Bug: #1353891 Change-Id: I9e57ec9f24bf303989a4df1fc4f1a0c4b6d001bc
Notes
Notes (review): Code-Review+2: James E. Blair <corvus@inaugust.com> Verified+2: Jenkins Code-Review+1: Antoine Musso <hashar@free.fr> Code-Review+2: Clark Boylan <cboylan@sapwetik.org> Code-Review+2: Khai Do <zaro0508@gmail.com> Workflow+1: Khai Do <zaro0508@gmail.com> Submitted-by: Jenkins Submitted-at: Mon, 20 Oct 2014 16:00:59 +0000 Reviewed-on: https://review.openstack.org/125755 Project: openstack-infra/gearman-plugin Branch: refs/heads/master
-rw-r--r--pom.xml4
-rw-r--r--src/main/java/hudson/plugins/gearman/ComputerListenerImpl.java54
-rw-r--r--src/main/java/hudson/plugins/gearman/ItemListenerImpl.java83
-rw-r--r--src/main/java/hudson/plugins/gearman/SaveableListenerImpl.java23
-rw-r--r--src/test/java/hudson/plugins/gearman/ExecutorWorkerThreadTest.java22
5 files changed, 138 insertions, 48 deletions
diff --git a/pom.xml b/pom.xml
index e2f03e6..2f34cbc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
28 <parent> 28 <parent>
29 <groupId>org.jenkins-ci.plugins</groupId> 29 <groupId>org.jenkins-ci.plugins</groupId>
30 <artifactId>plugin</artifactId> 30 <artifactId>plugin</artifactId>
31 <version>1.502</version><!-- which version of Jenkins is this plugin built against? --> 31 <version>1.565.3</version><!-- which version of Jenkins is this plugin built against? -->
32 </parent> 32 </parent>
33 33
34 <artifactId>gearman-plugin</artifactId> 34 <artifactId>gearman-plugin</artifactId>
@@ -228,9 +228,7 @@
228 <artifactId>maven-surefire-plugin</artifactId> 228 <artifactId>maven-surefire-plugin</artifactId>
229 <version>${maven-surefire-plugin.version}</version> 229 <version>${maven-surefire-plugin.version}</version>
230 <configuration> 230 <configuration>
231 <parallel>methods</parallel>
232 <testFailureIgnore>true</testFailureIgnore> 231 <testFailureIgnore>true</testFailureIgnore>
233 <threadCount>4</threadCount>
234 </configuration> 232 </configuration>
235 </plugin> 233 </plugin>
236 </plugins> 234 </plugins>
diff --git a/src/main/java/hudson/plugins/gearman/ComputerListenerImpl.java b/src/main/java/hudson/plugins/gearman/ComputerListenerImpl.java
index 568d1a7..08e07a9 100644
--- a/src/main/java/hudson/plugins/gearman/ComputerListenerImpl.java
+++ b/src/main/java/hudson/plugins/gearman/ComputerListenerImpl.java
@@ -1,6 +1,6 @@
1/* 1/*
2 * 2 *
3 * Copyright 2013 Hewlett-Packard Development Company, L.P. 3 * Copyright 2014 Hewlett-Packard Development Company, L.P.
4 * 4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License. 6 * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import hudson.Extension;
21import hudson.model.TaskListener; 21import hudson.model.TaskListener;
22import hudson.model.Computer; 22import hudson.model.Computer;
23import hudson.slaves.ComputerListener; 23import hudson.slaves.ComputerListener;
24import hudson.slaves.OfflineCause;
24 25
25import java.io.IOException; 26import java.io.IOException;
26 27
@@ -28,7 +29,7 @@ import org.slf4j.Logger;
28import org.slf4j.LoggerFactory; 29import org.slf4j.LoggerFactory;
29 30
30/** 31/**
31 * Update gearman workers when node changes 32 * Update gearman workers on node state and configuration changes
32 */ 33 */
33@Extension 34@Extension
34public class ComputerListenerImpl extends ComputerListener { 35public class ComputerListenerImpl extends ComputerListener {
@@ -36,12 +37,10 @@ public class ComputerListenerImpl extends ComputerListener {
36 private static final Logger logger = LoggerFactory 37 private static final Logger logger = LoggerFactory
37 .getLogger(Constants.PLUGIN_LOGGER_NAME); 38 .getLogger(Constants.PLUGIN_LOGGER_NAME);
38 39
39
40 @Override 40 @Override
41 public void onConfigurationChange() { 41 public void onConfigurationChange() {
42 // Bug: Configuration save occurs after this function is called 42 // only fired on nodes configuration changes like a label or
43 // gets called on any configuration change 43 // name change. Not fired on state changes, like offline or online.
44 // includes new slave and delete slave
45 logger.info("---- " + ComputerListenerImpl.class.getName() + ":" 44 logger.info("---- " + ComputerListenerImpl.class.getName() + ":"
46 + " onConfigurationChange"); 45 + " onConfigurationChange");
47 46
@@ -50,6 +49,10 @@ public class ComputerListenerImpl extends ComputerListener {
50 return; 49 return;
51 } 50 }
52 51
52 // re-register gearman functions on node configuration changes,
53 // specifically node label changes
54 GearmanProxy.getInstance().registerJobs();
55
53 // TODO: adjust for an update to executors. Method does not provide the 56 // TODO: adjust for an update to executors. Method does not provide the
54 // computer to know which thread to remove or add 57 // computer to know which thread to remove or add
55 } 58 }
@@ -84,10 +87,42 @@ public class ComputerListenerImpl extends ComputerListener {
84 return; 87 return;
85 } 88 }
86 89
90 GearmanProxy gp = GearmanProxy.getInstance();
87 /* 91 /*
88 * Need to treat the master differently than slaves because 92 * Spawn management executor worker if one doesn't exist yet.
89 * the master is not the same as a slave 93 * This worker does not need any executors. It only needs
94 * to work with gearman.
90 */ 95 */
96 gp.createManagementWorker();
97
98 // on creation of new slave
99 gp.createExecutorWorkersOnNode(c);
100 }
101
102 @Override
103 public void onTemporarilyOffline(Computer c, OfflineCause cause) {
104 // fired when master or slave goes into temporary offline state
105 logger.info("---- " + ComputerListenerImpl.class.getName() + ":"
106 + " onTemporarilyOffline computer " + c);
107 // update functions only when gearman-plugin is enabled
108 if (!GearmanPluginConfig.get().enablePlugin()) {
109 return;
110 }
111
112 // stop worker when jenkins slave is set to offline
113 GearmanProxy.getInstance().stop(c);
114 }
115
116 @Override
117 public void onTemporarilyOnline(Computer c) {
118 // fired when master or slave goes into temporary online state
119 logger.info("---- " + ComputerListenerImpl.class.getName() + ":"
120 + " onTemporarilyOnline computer " + c);
121 // update functions only when gearman-plugin is enabled
122 if (!GearmanPluginConfig.get().enablePlugin()) {
123 return;
124 }
125
91 GearmanProxy gp = GearmanProxy.getInstance(); 126 GearmanProxy gp = GearmanProxy.getInstance();
92 /* 127 /*
93 * Spawn management executor worker if one doesn't exist yet. 128 * Spawn management executor worker if one doesn't exist yet.
@@ -96,7 +131,8 @@ public class ComputerListenerImpl extends ComputerListener {
96 */ 131 */
97 gp.createManagementWorker(); 132 gp.createManagementWorker();
98 133
99 // on creation of new slave 134 // on brining a slave back online
100 gp.createExecutorWorkersOnNode(c); 135 gp.createExecutorWorkersOnNode(c);
101 } 136 }
137
102} 138}
diff --git a/src/main/java/hudson/plugins/gearman/ItemListenerImpl.java b/src/main/java/hudson/plugins/gearman/ItemListenerImpl.java
new file mode 100644
index 0000000..42ca024
--- /dev/null
+++ b/src/main/java/hudson/plugins/gearman/ItemListenerImpl.java
@@ -0,0 +1,83 @@
1/*
2 *
3 * Copyright 2014 Hewlett-Packard Development Company, L.P.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package hudson.plugins.gearman;
20
21import hudson.Extension;
22import hudson.model.Item;
23import hudson.model.listeners.ItemListener;
24
25import org.slf4j.Logger;
26import org.slf4j.LoggerFactory;
27
28/*
29 * This handles events for generic items in Jenkins. We also extended
30 * the SaveableListener to catch any events that this one misses.
31 */
32@Extension
33public class ItemListenerImpl extends ItemListener {
34
35 private static final Logger logger = LoggerFactory
36 .getLogger(Constants.PLUGIN_LOGGER_NAME);
37
38 @Override
39 public void onCopied(Item src, Item item) {
40 // Called after a new job is created by copying from an existing job
41 registerJobs();
42 }
43
44 @Override
45 public void onRenamed(Item item, String oldName, String newName) {
46 // Called after a job is renamed
47 registerJobs();
48 }
49
50 @Override
51 public void onLoaded() {
52 registerJobs();
53 }
54
55 @Override
56 public void onCreated(Item item) {
57 registerJobs();
58 }
59
60 @Override
61 public void onUpdated(Item item) {
62 registerJobs();
63 }
64
65 @Override
66 public void onDeleted(Item item) {
67 registerJobs();
68 }
69
70 @Override
71 public void onLocationChanged(Item item, String oldFullName, String newFullName) {
72 registerJobs();
73 }
74
75 // register gearman functions
76 private void registerJobs() {
77 // update functions only when gearman-plugin is enabled
78 if (!GearmanPluginConfig.get().enablePlugin()) {
79 return;
80 }
81 GearmanProxy.getInstance().registerJobs();
82 }
83}
diff --git a/src/main/java/hudson/plugins/gearman/SaveableListenerImpl.java b/src/main/java/hudson/plugins/gearman/SaveableListenerImpl.java
index 9ecdab0..b1fecd3 100644
--- a/src/main/java/hudson/plugins/gearman/SaveableListenerImpl.java
+++ b/src/main/java/hudson/plugins/gearman/SaveableListenerImpl.java
@@ -22,18 +22,16 @@ import hudson.Extension;
22import hudson.XmlFile; 22import hudson.XmlFile;
23import hudson.model.Saveable; 23import hudson.model.Saveable;
24import hudson.model.AbstractProject; 24import hudson.model.AbstractProject;
25import hudson.model.Node;
26import hudson.model.listeners.SaveableListener; 25import hudson.model.listeners.SaveableListener;
27 26
28import java.util.List;
29
30import org.slf4j.Logger; 27import org.slf4j.Logger;
31import org.slf4j.LoggerFactory; 28import org.slf4j.LoggerFactory;
32 29
33/** 30/**
34 * Using the SaveableListener is required as a work around because 31 * Using the SaveableListener is required as a work around because
35 * updating gearman function in ComputerListener.onConfigurationChange 32 * the itemListener.onUpdate event does not fire on changes to
36 * doesn't work. 33 * project updates using the Jenkins REST API
34 * Bug: https://issues.jenkins-ci.org/browse/JENKINS-25175
37 */ 35 */
38@Extension 36@Extension
39public class SaveableListenerImpl extends SaveableListener { 37public class SaveableListenerImpl extends SaveableListener {
@@ -41,22 +39,19 @@ public class SaveableListenerImpl extends SaveableListener {
41 private static final Logger logger = LoggerFactory 39 private static final Logger logger = LoggerFactory
42 .getLogger(Constants.PLUGIN_LOGGER_NAME); 40 .getLogger(Constants.PLUGIN_LOGGER_NAME);
43 41
44 /*
45 * TODO: this works, but is NOT GOOD!
46 * This listener fires for every change to an object. So if you
47 * have 3 nodes in Jenkins it will fire 3 times even though
48 * the change was only applied to one of the nodes.
49 *
50 */
51 @Override 42 @Override
43 // This works but is NOT good because this event is a catch all
44 // for just about any change that happens in Jenkins. This event
45 // also doesn't provide much detail on what has changed.
52 public void onChange(Saveable o, XmlFile file) { 46 public void onChange(Saveable o, XmlFile file) {
53 // update functions only when gearman-plugin is enabled 47 // update functions only when gearman-plugin is enabled
54 if (!GearmanPluginConfig.get().enablePlugin()) { 48 if (!GearmanPluginConfig.get().enablePlugin()) {
55 return; 49 return;
56 } 50 }
57 51
58 // update for when any changes are applied to a project or node 52 // only look for changes to projects, specifically for project
59 if (o instanceof Node || o instanceof AbstractProject) { 53 // label changes. Node changes are handled in ComputerListenerImpl
54 if (o instanceof AbstractProject) {
60 GearmanProxy.getInstance().registerJobs(); 55 GearmanProxy.getInstance().registerJobs();
61 } 56 }
62 } 57 }
diff --git a/src/test/java/hudson/plugins/gearman/ExecutorWorkerThreadTest.java b/src/test/java/hudson/plugins/gearman/ExecutorWorkerThreadTest.java
index 38ab140..80bb6fd 100644
--- a/src/test/java/hudson/plugins/gearman/ExecutorWorkerThreadTest.java
+++ b/src/test/java/hudson/plugins/gearman/ExecutorWorkerThreadTest.java
@@ -70,28 +70,6 @@ public class ExecutorWorkerThreadTest extends HudsonTestCase {
70 70
71 /* 71 /*
72 * This test verifies that gearman functions are correctly registered for a 72 * This test verifies that gearman functions are correctly registered for a
73 * project that contains a label matching a slave node's self label
74 */
75 @Test
76 public void testRegisterJobs_NodeSelfLabel() throws Exception {
77
78
79 Project<?, ?> apple = createFreeStyleProject("apple");
80 apple.setAssignedLabel(new LabelAtom("oneiric-10"));
81
82 AbstractWorkerThread oneiric = new ExecutorWorkerThread("GearmanServer", 4730, "MyWorker", slave.toComputer(), "master", new NoopAvailabilityMonitor());
83 oneiric.testInitWorker();
84 oneiric.registerJobs();
85 Set<String> functions = oneiric.worker.getRegisteredFunctions();
86
87 assertEquals(2, functions.size());
88 assertTrue(functions.contains("build:apple"));
89 assertTrue(functions.contains("build:apple:oneiric-10"));
90
91 }
92
93 /*
94 * This test verifies that gearman functions are correctly registered for a
95 * project that contains a single label matching a label on the slave node 73 * project that contains a single label matching a label on the slave node
96 */ 74 */
97 @Test 75 @Test