>();
@@ -47,7 +51,7 @@ private PortAllocationManager(Computer node) {
* Preffered port. This method trys to assign this port, and upon failing, fall back to
* assigning a random port.
*/
- public synchronized int allocateRandom(AbstractBuild owner, int prefPort) throws InterruptedException, IOException {
+ public synchronized int allocateRandom(Run, ?> run, int prefPort) throws InterruptedException, IOException {
int i;
try {
// try to allocate preferential port,
@@ -56,7 +60,7 @@ public synchronized int allocateRandom(AbstractBuild owner, int prefPort) throws
// if not available, assign a random port
i = allocatePort(0);
}
- ports.put(i,owner);
+ ports.put(i,run.getId());
return i;
}
@@ -64,8 +68,7 @@ public synchronized int allocateRandom(AbstractBuild owner, int prefPort) throws
* Allocate a continuous range of ports within specified limits.
* The caller is responsible for freeing the individual ports within
* the allocated range.
- * @param portAllocator
- * @param build the current build
+ * @param run the current build
* @param start the first in the range of allowable ports
* @param end the last entry in the range of allowable ports
* @param count the number of ports to allocate
@@ -75,7 +78,7 @@ public synchronized int allocateRandom(AbstractBuild owner, int prefPort) throws
* @throws IOException if the allocation failed
*/
public int[] allocatePortRange(
- final AbstractBuild owner,
+ final Run, ?> run,
int start, int end, int count, boolean isConsecutive)
throws InterruptedException, IOException {
int[] allocated = new int[count];
@@ -100,7 +103,7 @@ public int[] allocatePortRange(
final int i;
synchronized (this) {
i = allocatePort(requestedPort);
- ports.put(i, owner);
+ ports.put(i, run.getId());
}
allocated[offset] = i;
} catch (PortUnavailableException ex) {
@@ -126,8 +129,8 @@ public int[] allocatePortRange(
*
* This method blocks until the port becomes available.
*/
- public synchronized int allocate(AbstractBuild owner, int port) throws InterruptedException, IOException {
- while(ports.get(port)!=null)
+ public synchronized int allocate(Run, ?> run, int port) throws InterruptedException, IOException {
+ while (ports.get(port) != null)
wait();
/*
@@ -160,13 +163,12 @@ the port actually becomes available (not only in our book-keeping but also at OS
// wait(10000);
// }
// }
- ports.put(port,owner);
+ ports.put(port,run.getId());
return port;
}
public synchronized boolean isFree(int port) {
- AbstractBuild owner = ports.get(port);
- if (owner == null) {
+ if (ports.get(port) == null) {
return true;
}
return false;
@@ -211,9 +213,9 @@ public synchronized void free(int n) {
* If the specified port is not available
*/
private int allocatePort(final int port) throws InterruptedException, IOException {
- AbstractBuild owner = ports.get(port);
- if(owner!=null)
- throw new PortUnavailableException("Owned by "+owner);
+ String id = ports.get(port);
+ if (id != null)
+ throw new PortUnavailableException("Owned by run " + id);
return node.getChannel().call(new AllocateTask(port));
}
@@ -254,5 +256,11 @@ public Integer call() throws IOException {
}
private static final long serialVersionUID = 1L;
+
+ @Override
+ public void checkRoles(RoleChecker roleChecker) throws SecurityException {
+ }
}
+
+ private static final long serialVersionUID = 1L;
}
diff --git a/src/main/java/org/jvnet/hudson/plugins/port_allocator/PortAllocator.java b/src/main/java/org/jvnet/hudson/plugins/port_allocator/PortAllocator.java
index bc12a32..ccdb062 100644
--- a/src/main/java/org/jvnet/hudson/plugins/port_allocator/PortAllocator.java
+++ b/src/main/java/org/jvnet/hudson/plugins/port_allocator/PortAllocator.java
@@ -1,16 +1,24 @@
package org.jvnet.hudson.plugins.port_allocator;
+import hudson.EnvVars;
import hudson.Extension;
+import hudson.FilePath;
import hudson.Launcher;
import hudson.model.*;
import hudson.tasks.BuildWrapper;
+import jenkins.tasks.SimpleBuildWrapper;
import hudson.util.FormValidation;
import net.sf.json.JSONObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jenkinsci.Symbol;
+import org.kohsuke.stapler.DataBoundConstructor;
+import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
+import com.google.common.collect.Lists;
+
import java.io.IOException;
import java.io.PrintStream;
import java.util.*;
@@ -22,28 +30,83 @@
*
*
* This just mediates between different Jobs running on the same Computer
- * by assigning free ports and its the jobs responsibility to open and close the ports.
+ * by assigning free ports and its the jobs responsibility to open and close the ports.
*
* @author Rama Pulavarthi
*/
-public class PortAllocator extends BuildWrapper
+public class PortAllocator extends SimpleBuildWrapper
{
private static final Log log = LogFactory.getLog(PortAllocator.class);
- public final PortType[] ports;
+ protected final List ports = Lists.newArrayList();
+
+ private String pool;
+ private final List pools = Lists.newArrayList();
+ private final List plainports = Lists.newArrayList();
+ private final List genericPorts = Lists.newArrayList();
+
+ private PortAllocator(PortType[] ports) {
+ if (ports != null) {
+ this.ports.addAll(Arrays.asList(ports));
+ }
+
+ }
+
+ @DataBoundConstructor
+ public PortAllocator() {
+ // empty
+ }
+
+ @DataBoundSetter
+ public void setPool(String pool) {
+ if (pool != null) {
+ this.ports.add(new PooledPortType(pool));
+ this.pool = pool;
+ }
+ }
+
+ public String getPool() {
+ return this.pool;
+ }
+
+ @DataBoundSetter
+ public void setPools(String[] pools) {
+ if (pools != null) {
+ for (String pool : pools) {
+ this.ports.add(new PooledPortType(pool));
+ this.pools.add(pool);
+ }
+ }
+ }
+
+ public String[] getPools() {
+ return this.pools.toArray(new String[this.pools.size()]);
+ }
+
+ @DataBoundSetter
+ public void setPlainports(String[] plainports) {
+ if (plainports != null) {
+ for (String port : plainports) {
+ this.ports.add(new DefaultPortType(port));
+ this.plainports.add(port);
+ }
+ }
+ }
+
+ public String[] getPlainports() {
+ return this.plainports.toArray(new String[this.plainports.size()]);
+ }
- private PortAllocator(PortType[] ports){
- this.ports = ports;
- }
@Override
- public Environment setUp(AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException {
- PrintStream logger = listener.getLogger();
+ public void setUp(Context context, Run, ?> run, FilePath workspace, Launcher launcher, TaskListener taskListener, EnvVars envVars) throws IOException, InterruptedException {
+ PrintStream logger = taskListener.getLogger();
- final Computer cur = Executor.currentExecutor().getOwner();
+ Computer cur = workspace.toComputer();
Map prefPortMap = new HashMap();
- if (build.getPreviousBuild() != null) {
- AllocatedPortAction prevAlloc = build.getPreviousBuild().getAction(AllocatedPortAction.class);
+ Run, ?> prevBuild = run.getPreviousBuild();
+ if (prevBuild != null) {
+ AllocatedPortAction prevAlloc = prevBuild.getAction(AllocatedPortAction.class);
if (prevAlloc != null) {
// try to assign ports assigned in previous build
prefPortMap = prevAlloc.getPreviousAllocatedPorts();
@@ -56,31 +119,19 @@ public Environment setUp(AbstractBuild build, Launcher launcher, BuildListener l
for (PortType pt : ports) {
logger.println("Allocating TCP port "+pt.name);
int prefPort = prefPortMap.get(pt.name)== null?0:prefPortMap.get(pt.name);
- Port p = pt.allocate(build, pam, prefPort, launcher, listener);
+ Port p = pt.allocate(run, pam, prefPort, launcher, taskListener);
allocated.add(p);
- portMap.put(pt.name,p.get());
+ portMap.put(pt.name, p.get());
logger.println(" -> Assigned "+p.get());
}
// TODO: only log messages when we are blocking.
logger.println("TCP port allocation complete");
- build.addAction(new AllocatedPortAction(portMap));
+ run.addAction(new AllocatedPortAction(portMap));
- return new Environment() {
-
- @Override
- public void buildEnvVars(Map env) {
- for (Port p : allocated)
- env.put(p.type.name, String.valueOf(p.get()));
- }
-
- @Override
- public boolean tearDown(AbstractBuild build, BuildListener listener) throws IOException, InterruptedException {
- for (Port p : allocated)
- p.cleanUp();
- return true;
- }
- };
+ context.setDisposer(new CleanupDisposer(allocated));
+ for (Port p : allocated)
+ context.env(p.type.name, String.valueOf(p.get()));
}
public String getDisplayName() {
@@ -95,9 +146,10 @@ public Descriptor getDescriptor() {
@Extension
public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl();
+ @Symbol("portallocator")
public static final class DescriptorImpl extends Descriptor {
- private Pool[] pools = new Pool[] {};
+ private List pools = new ArrayList();
public DescriptorImpl() {
super(PortAllocator.class);
@@ -114,7 +166,7 @@ public String getHelpFile() {
}
public List getPortTypes() {
- return PortTypeDescriptor.LIST;
+ return PortTypeDescriptor.LIST;
}
@Override
@@ -136,11 +188,12 @@ public BuildWrapper newInstance(StaplerRequest req, JSONObject formData) throws
@Override
public boolean configure(StaplerRequest req, JSONObject formData) throws FormException {
Pool[] pools = req.bindParametersToList(Pool.class, "pool.").toArray(new Pool[] {});
+ this.pools.clear();
for (Pool p : pools) {
p.name = checkPoolName(p.name);
checkPortNumbers(p.ports);
+ this.pools.add(p);
}
- this.pools = pools;
save();
return super.configure(req,formData);
}
@@ -184,7 +237,7 @@ private void checkPortNumbers(String ports) throws FormException {
}
}
- public Pool[] getPools() {
+ public List getPools() {
return pools;
}
@@ -201,4 +254,19 @@ public int getPoolSize(String poolName) throws PoolNotDefinedException {
return getPoolByName(poolName).getPortsAsInt().length;
}
}
+
+ private static class CleanupDisposer extends Disposer {
+
+ List allocated;
+
+ public CleanupDisposer(List allocated) {
+ this.allocated = allocated;
+ }
+
+ @Override
+ public void tearDown(Run, ?> build, FilePath workspace, Launcher launcher, TaskListener listener) throws IOException, InterruptedException {
+ for (Port p : allocated)
+ p.cleanUp();
+ }
+ }
}
diff --git a/src/main/java/org/jvnet/hudson/plugins/port_allocator/PortType.java b/src/main/java/org/jvnet/hudson/plugins/port_allocator/PortType.java
index ffab86a..3ed40ea 100644
--- a/src/main/java/org/jvnet/hudson/plugins/port_allocator/PortType.java
+++ b/src/main/java/org/jvnet/hudson/plugins/port_allocator/PortType.java
@@ -2,9 +2,10 @@
import hudson.ExtensionPoint;
import hudson.Launcher;
-import hudson.model.AbstractBuild;
import hudson.model.Describable;
import hudson.model.BuildListener;
+import hudson.model.Run;
+import hudson.model.TaskListener;
import java.io.IOException;
import java.io.Serializable;
@@ -53,15 +54,15 @@ public final boolean isFixedPort() {
/**
* Allocates a new port for a given build.
- *
+ * @param run
+ * The current build
* @param manager
* This can be used to assign a new TCP port number.
* @param prefPort
* The port number allocated to this type the last time.
* @param launcher
- * @param buildListener
*/
- public abstract Port allocate(AbstractBuild, ?> build, PortAllocationManager manager, int prefPort, Launcher launcher, BuildListener buildListener) throws IOException, InterruptedException;
+ public abstract Port allocate(Run, ?> run, PortAllocationManager manager, int prefPort, Launcher launcher, TaskListener taskListener) throws IOException, InterruptedException;
public abstract PortTypeDescriptor getDescriptor();
diff --git a/src/main/java/org/jvnet/hudson/plugins/port_allocator/PortTypeDescriptor.java b/src/main/java/org/jvnet/hudson/plugins/port_allocator/PortTypeDescriptor.java
index ac8c7cb..466130f 100644
--- a/src/main/java/org/jvnet/hudson/plugins/port_allocator/PortTypeDescriptor.java
+++ b/src/main/java/org/jvnet/hudson/plugins/port_allocator/PortTypeDescriptor.java
@@ -19,5 +19,5 @@ protected PortTypeDescriptor(Class extends PortType> clazz) {
/**
* All registered {@link PortTypeDescriptor}s.
*/
- public static final List LIST = new ArrayList();
+ static final List LIST = new ArrayList();
}
diff --git a/src/main/java/org/jvnet/hudson/plugins/port_allocator/TomcatShutdownPortType.java b/src/main/java/org/jvnet/hudson/plugins/port_allocator/TomcatShutdownPortType.java
index 89f471c..858b3f3 100644
--- a/src/main/java/org/jvnet/hudson/plugins/port_allocator/TomcatShutdownPortType.java
+++ b/src/main/java/org/jvnet/hudson/plugins/port_allocator/TomcatShutdownPortType.java
@@ -1,22 +1,27 @@
package org.jvnet.hudson.plugins.port_allocator;
import hudson.Launcher;
-import hudson.model.AbstractBuild;
-import hudson.model.BuildListener;
+import hudson.model.Run;
+import hudson.model.TaskListener;
import hudson.remoting.Callable;
import net.sf.json.JSONObject;
+import org.jenkinsci.remoting.RoleChecker;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;
import java.io.IOException;
import java.io.Serializable;
+import java.nio.charset.StandardCharsets;
import java.net.Socket;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
/**
* Tomcat shutdown port.
- *
+ *
* @author Kohsuke Kawaguchi
*/
+@SuppressFBWarnings(value="SE_INNER_CLASS")
public class TomcatShutdownPortType extends PortType {
/**
* Shutdown magic phrase.
@@ -30,18 +35,20 @@ public TomcatShutdownPortType(String name, String password) {
}
@Override
- public Port allocate(AbstractBuild, ?> build, final PortAllocationManager manager, int prefPort, final Launcher launcher, final BuildListener buildListener) throws IOException, InterruptedException {
+ public Port allocate(Run, ?> run, final PortAllocationManager manager, int prefPort, final Launcher launcher, final TaskListener taskListener)
+ throws IOException, InterruptedException
+ {
final int n;
if(isFixedPort())
- n = manager.allocate(build, getFixedPort());
+ n = manager.allocate(run, getFixedPort());
else
- n = manager.allocateRandom(build, prefPort);
+ n = manager.allocateRandom(run, prefPort);
final class TomcatCleanUpTask implements Callable, Serializable {
- private final BuildListener buildListener;
+ private final TaskListener taskListener;
- public TomcatCleanUpTask(BuildListener buildListener) {
- this.buildListener = buildListener;
+ public TomcatCleanUpTask(TaskListener taskListener) {
+ this.taskListener = taskListener;
}
public Void call() throws IOException {
@@ -54,16 +61,20 @@ public Void call() throws IOException {
}
try {
- s.getOutputStream().write(password.getBytes());
+ s.getOutputStream().write(password.getBytes(StandardCharsets.UTF_8));
s.close();
- buildListener.getLogger().println("Shutdown left-over Tomcat");
+ taskListener.getLogger().println("Shutdown left-over Tomcat");
} catch (IOException x) {
- x.printStackTrace(buildListener.error("Failed to write to Tomcat shutdown port"));
+ x.printStackTrace(taskListener.error("Failed to write to Tomcat shutdown port"));
}
return null;
}
private static final long serialVersionUID = 1L;
+
+ @Override
+ public void checkRoles(RoleChecker roleChecker) throws SecurityException {
+ }
}
return new Port(this) {
@@ -73,7 +84,7 @@ public int get() {
public void cleanUp() throws IOException, InterruptedException {
manager.free(n);
- launcher.getChannel().call(new TomcatCleanUpTask(buildListener));
+ launcher.getChannel().call(new TomcatCleanUpTask(taskListener));
}
};
}
diff --git a/src/main/resources/index.jelly b/src/main/resources/index.jelly
index b8c39be..921df5a 100644
--- a/src/main/resources/index.jelly
+++ b/src/main/resources/index.jelly
@@ -1,3 +1,4 @@
+