Skip to content

Commit

Permalink
Merge branch 'master' into BuildTrigger-auth-JENKINS-16956
Browse files Browse the repository at this point in the history
  • Loading branch information
jglick committed Apr 11, 2014
2 parents 840bb66 + a1cd49b commit e321cbb
Show file tree
Hide file tree
Showing 22 changed files with 191 additions and 84 deletions.
9 changes: 8 additions & 1 deletion changelog.html
Expand Up @@ -55,7 +55,14 @@
<!-- Record your changes in the trunk here. -->
<div id="trunk" style="display:none"><!--=TRUNK-BEGIN=-->
<ul class=image>
<li class=>
<li class=bug>
Fixed NPE from view new job name autocompletion since 1.553.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-22142">issue 22142</a>)
<li class='major bug'>
Deadlocks in concurrent builds under some conditions since 1.556.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-22560">issue 22560</a>)
<li class=rfe>
JNLP slaves are now handled through NIO-based remoting channels for better scalability.
</ul>
</div><!--=TRUNK-END=-->

Expand Down
6 changes: 3 additions & 3 deletions cli/src/main/java/hudson/cli/CLI.java
Expand Up @@ -29,7 +29,7 @@
import hudson.remoting.Pipe;
import hudson.remoting.RemoteInputStream;
import hudson.remoting.RemoteOutputStream;
import hudson.remoting.SocketInputStream;
import hudson.remoting.SocketChannelStream;
import hudson.remoting.SocketOutputStream;

import javax.crypto.SecretKey;
Expand Down Expand Up @@ -201,7 +201,7 @@ public void close() throws IOException {
} else {
s = new Socket();
s.connect(clip.endpoint,3000);
out = new SocketOutputStream(s);
out = SocketChannelStream.out(s);
}

closables.add(new Closeable() {
Expand All @@ -210,7 +210,7 @@ public void close() throws IOException {
}
});

Connection c = new Connection(new SocketInputStream(s),out);
Connection c = new Connection(SocketChannelStream.in(s),out);

switch (clip.version) {
case 1:
Expand Down
5 changes: 2 additions & 3 deletions cli/src/main/java/hudson/cli/Connection.java
Expand Up @@ -23,8 +23,7 @@
*/
package hudson.cli;

import hudson.remoting.SocketInputStream;
import hudson.remoting.SocketOutputStream;
import hudson.remoting.SocketChannelStream;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
Expand Down Expand Up @@ -63,7 +62,7 @@ public class Connection {
public final DataOutputStream dout;

public Connection(Socket socket) throws IOException {
this(new SocketInputStream(socket),new SocketOutputStream(socket));
this(SocketChannelStream.in(socket),SocketChannelStream.out(socket));
}

public Connection(InputStream in, OutputStream out) {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/hudson/Launcher.java
Expand Up @@ -818,7 +818,7 @@ public Channel launchChannel(OutputStream out, ProcessBuilder pb) throws IOExcep
* Kill the process when the channel is severed.
*/
@Override
protected synchronized void terminate(IOException e) {
public synchronized void terminate(IOException e) {
super.terminate(e);
ProcessTree pt = ProcessTree.get();
try {
Expand Down
11 changes: 7 additions & 4 deletions core/src/main/java/hudson/TcpSlaveAgentListener.java
Expand Up @@ -32,8 +32,10 @@
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.BindException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.ServerSocketChannel;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand All @@ -55,7 +57,7 @@
*/
public final class TcpSlaveAgentListener extends Thread {

private final ServerSocket serverSocket;
private final ServerSocketChannel serverSocket;
private volatile boolean shuttingDown;

public final int configuredPort;
Expand All @@ -67,7 +69,8 @@ public final class TcpSlaveAgentListener extends Thread {
public TcpSlaveAgentListener(int port) throws IOException {
super("TCP slave agent listener port="+port);
try {
serverSocket = new ServerSocket(port);
serverSocket = ServerSocketChannel.open();
serverSocket.socket().bind(new InetSocketAddress(port));
} catch (BindException e) {
throw (BindException)new BindException("Failed to listen on port "+port+" because it's already in use.").initCause(e);
}
Expand All @@ -82,15 +85,15 @@ public TcpSlaveAgentListener(int port) throws IOException {
* Gets the TCP port number in which we are listening.
*/
public int getPort() {
return serverSocket.getLocalPort();
return serverSocket.socket().getLocalPort();
}

@Override
public void run() {
try {
// the loop eventually terminates when the socket is closed.
while (true) {
Socket s = serverSocket.accept();
Socket s = serverSocket.accept().socket();

// this prevents a connection from silently terminated by the router in between or the other peer
// and that goes without unnoticed. However, the time out is often very long (for example 2 hours
Expand Down
37 changes: 33 additions & 4 deletions core/src/main/java/hudson/cli/CliProtocol.java
Expand Up @@ -4,9 +4,13 @@
import hudson.model.Computer;
import hudson.remoting.Channel;
import hudson.remoting.Channel.Mode;
import hudson.remoting.ChannelBuilder;
import jenkins.AgentProtocol;
import jenkins.model.Jenkins;
import jenkins.slaves.NioChannelSelector;
import org.jenkinsci.remoting.nio.NioChannelHub;

import javax.inject.Inject;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
Expand All @@ -23,20 +27,33 @@
*/
@Extension
public class CliProtocol extends AgentProtocol {
@Inject
NioChannelSelector nio;

@Override
public String getName() {
return "CLI-connect";
}

@Override
public void handle(Socket socket) throws IOException, InterruptedException {
new Handler(socket).run();
new Handler(nio.getHub(),socket).run();
}

protected static class Handler {
protected final NioChannelHub hub;
protected final Socket socket;

/**
* @deprecated as of 1.559
* Use {@link #Handler(NioChannelHub, Socket)}
*/
public Handler(Socket socket) {
this(null,socket);
}

public Handler(NioChannelHub hub, Socket socket) {
this.hub = hub;
this.socket = socket;
}

Expand All @@ -47,9 +64,21 @@ public void run() throws IOException, InterruptedException {
}

protected void runCli(Connection c) throws IOException, InterruptedException {
Channel channel = new Channel("CLI channel from " + socket.getInetAddress(),
Computer.threadPoolForRemoting, Mode.BINARY,
new BufferedInputStream(c.in), new BufferedOutputStream(c.out), null, true, Jenkins.getInstance().pluginManager.uberClassLoader);
ChannelBuilder cb;
String name = "CLI channel from " + socket.getInetAddress();

// Connection can contain cipher wrapper, which can't be NIO-ed.
// if (hub!=null)
// cb = hub.newChannelBuilder(name, Computer.threadPoolForRemoting);
// else
cb = new ChannelBuilder(name, Computer.threadPoolForRemoting);

Channel channel = cb
.withMode(Mode.BINARY)
.withRestricted(true)
.withBaseLoader(Jenkins.getInstance().pluginManager.uberClassLoader)
.build(new BufferedInputStream(c.in), new BufferedOutputStream(c.out));

channel.setProperty(CliEntryPoint.class.getName(),new CliManagerImpl(channel));
channel.join();
}
Expand Down
11 changes: 10 additions & 1 deletion core/src/main/java/hudson/cli/CliProtocol2.java
Expand Up @@ -2,6 +2,7 @@

import hudson.Extension;
import jenkins.model.Jenkins;
import org.jenkinsci.remoting.nio.NioChannelHub;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
Expand All @@ -28,14 +29,22 @@ public String getName() {

@Override
public void handle(Socket socket) throws IOException, InterruptedException {
new Handler2(socket).run();
new Handler2(nio.getHub(), socket).run();
}

protected static class Handler2 extends Handler {
/**
* @deprecated as of 1.559
* Use {@link #Handler2(NioChannelHub, Socket)}
*/
public Handler2(Socket socket) {
super(socket);
}

public Handler2(NioChannelHub hub, Socket socket) {
super(hub, socket);
}

@Override
public void run() throws IOException, InterruptedException {
try {
Expand Down
16 changes: 6 additions & 10 deletions core/src/main/java/hudson/model/AbstractBuild.java
Expand Up @@ -71,7 +71,6 @@
import java.io.InterruptedIOException;
import java.io.StringWriter;
import java.lang.ref.WeakReference;
import java.text.MessageFormat;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Calendar;
Expand Down Expand Up @@ -156,7 +155,11 @@ public abstract class AbstractBuild<P extends AbstractProject<P,R>,R extends Abs
*/
protected transient List<Environment> buildEnvironments;

private transient LazyBuildMixIn.RunMixIn<P,R> runMixIn;
private transient final LazyBuildMixIn.RunMixIn<P,R> runMixIn = new LazyBuildMixIn.RunMixIn<P,R>() {
@Override protected R asRun() {
return _this();
}
};

protected AbstractBuild(P job) throws IOException {
super(job);
Expand All @@ -174,14 +177,7 @@ public final P getProject() {
return getParent();
}

@Override public final synchronized LazyBuildMixIn.RunMixIn<P,R> getRunMixIn() {
if (runMixIn == null) {
runMixIn = new LazyBuildMixIn.RunMixIn<P,R>() {
@Override protected R asRun() {
return _this();
}
};
}
@Override public final LazyBuildMixIn.RunMixIn<P,R> getRunMixIn() {
return runMixIn;
}

Expand Down
1 change: 1 addition & 0 deletions core/src/main/java/hudson/model/ItemGroupMixIn.java
Expand Up @@ -108,6 +108,7 @@ public boolean accept(File child) {
item = (V) Items.load( parent, subdir );
}else{
Logger.getLogger( ItemGroupMixIn.class.getName() ).log( Level.WARNING, "could not find file " + xmlFile.getFile());
continue;
}
} else {
item.onLoad(parent, subdir.getName());
Expand Down
Expand Up @@ -25,6 +25,8 @@

import hudson.model.Descriptor.FormException;
import hudson.slaves.NodeProperty;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.StaplerRequest;

Expand Down Expand Up @@ -77,5 +79,5 @@ public interface ReconfigurableDescribable<T extends ReconfigurableDescribable<T
* @return
* The new instance. To not to create an instance of a describable, return null.
*/
T reconfigure(StaplerRequest req, JSONObject form) throws FormException;
@CheckForNull T reconfigure(@Nonnull StaplerRequest req, @CheckForNull JSONObject form) throws FormException;
}
13 changes: 8 additions & 5 deletions core/src/main/java/hudson/model/Run.java
Expand Up @@ -1445,17 +1445,19 @@ public synchronized void deleteArtifacts() throws IOException {
* @throws IOException
* if we fail to delete.
*/
public synchronized void delete() throws IOException {
public void delete() throws IOException {
File rootDir = getRootDir();
if (!rootDir.isDirectory()) {
throw new IOException(this + ": " + rootDir + " looks to have already been deleted");
}

RunListener.fireDeleted(this);

synchronized (this) { // avoid holding a lock while calling plugin impls of onDeleted
// if we have a symlink, delete it, too
File link = new File(project.getBuildDir(), String.valueOf(getNumber()));
link.delete();

File rootDir = getRootDir();
if (!rootDir.isDirectory()) {
throw new IOException(this + ": " + rootDir + " looks to have already been deleted");
}
File tmp = new File(rootDir.getParentFile(),'.'+rootDir.getName());

if (tmp.exists()) {
Expand All @@ -1474,6 +1476,7 @@ public synchronized void delete() throws IOException {
LOGGER.log(FINE, "{0}: {1} successfully deleted", new Object[] {this, rootDir});

removeRunFromParent();
}
}

@SuppressWarnings("unchecked") // seems this is too clever for Java's type system?
Expand Down
30 changes: 3 additions & 27 deletions core/src/main/java/hudson/model/ViewDescriptor.java
Expand Up @@ -26,7 +26,8 @@
import hudson.views.ListViewColumn;
import hudson.views.ListViewColumnDescriptor;
import hudson.views.ViewJobFilter;
import jenkins.model.Jenkins;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.DoNotUse;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.AncestorInPath;

Expand Down Expand Up @@ -68,35 +69,10 @@ protected ViewDescriptor(Class<? extends View> clazz) {
protected ViewDescriptor() {
}

@Deprecated
public AutoCompletionCandidates doAutoCompleteCopyNewItemFrom(final String prefix) {
final AutoCompletionCandidates r = new AutoCompletionCandidates();

new ItemVisitor() {
@Override
public void onItemGroup(ItemGroup<?> group) {
// only dig deep when the path matches what's typed.
// for example, if 'foo/bar' is typed, we want to show 'foo/barcode'
if (prefix.startsWith(group.getFullName()))
super.onItemGroup(group);
}

@Override
public void onItem(Item i) {
if (i.getFullName().startsWith(prefix)) {
r.add((i.getFullName()));
super.onItem(i);
}
}
}.onItemGroup(Jenkins.getInstance());

return r;
}

/**
* Auto-completion for the "copy from" field in the new job page.
* @since 1.553
*/
@Restricted(DoNotUse.class)
public AutoCompletionCandidates doAutoCompleteCopyNewItemFrom(@QueryParameter final String value, @AncestorInPath ItemGroup container) {
return AutoCompletionCandidates.ofJobNames(TopLevelItem.class, value, container);
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/hudson/model/listeners/RunListener.java
Expand Up @@ -235,7 +235,7 @@ public static void fireFinalized(Run r) {
}

/**
* Fires the {@link #onFinalized(Run)} event.
* Fires the {@link #onDeleted} event.
*/
public static void fireDeleted(Run r) {
for (RunListener l : all()) {
Expand Down

0 comments on commit e321cbb

Please sign in to comment.