提交 2350c9b1 编写于 作者: K kohsuke

implemented the CLI entry point hook up

git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@17590 71c3de6d-444a-0410-be80-ed276b4c234a
上级 f9f3e4e4
......@@ -10,6 +10,30 @@
<artifactId>cli</artifactId>
<name>Hudson CLI</name>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>attached</goal>
</goals>
<phase>package</phase>
<configuration>
<descriptorId>jar-with-dependencies</descriptorId>
<archive>
<manifest>
<mainClass>hudson.cli.CLI</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
......
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.cli;
import hudson.remoting.Callable;
import hudson.remoting.Channel;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.lang.reflect.Method;
/**
* CLI entry point to Hudson.
*
* @author Kohsuke Kawaguchi
*/
public class CLI {
public static void main(final String[] args) throws Exception {
URL target = new URL("http://localhost:8080/duplexChannel");
URL target = new URL("http://localhost:8080/cli");
FullDuplexHttpStream con = new FullDuplexHttpStream(target);
ExecutorService pool = Executors.newCachedThreadPool();
Channel channel = new Channel("Chunked connection to "+target,
......@@ -22,12 +45,8 @@ public class CLI {
// execute the command
int r=-1;
try {
r = channel.call(new Callable<Integer,Exception>() {
public Integer call() throws Exception {
Method m = Class.forName("hudson.model.Hudson").getMethod("cli", String[].class);
return (Integer)m.invoke(null,new Object[]{args});
}
});
CliEntryPoint cli = (CliEntryPoint)channel.getRemoteProperty(CliEntryPoint.class.getName());
r = cli.main(args);
} finally {
channel.close();
pool.shutdown();
......
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.cli;
/**
* Remotable interface for CLI entry point on the server side.
*
* @author Kohsuke Kawaguchi
*/
public interface CliEntryPoint {
/**
* Just like the static main method.
*/
int main(String[] args);
}
......@@ -297,10 +297,15 @@ THE SOFTWARE.
<dependencies>
<dependency>
<groupId>org.jvnet.hudson.main</groupId>
<groupId>${project.groupId}</groupId>
<artifactId>remoting</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>cli</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jvnet.hudson</groupId>
<artifactId>jtidy</artifactId>
......
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.model;
import hudson.remoting.Channel;
......@@ -19,7 +42,7 @@ import java.util.logging.Logger;
*
* @author Kohsuke Kawaguchi
*/
final class FullDuplexHttpChannel {
abstract class FullDuplexHttpChannel {
private Channel channel;
private final PipedOutputStream pipe = new PipedOutputStream();
......@@ -62,10 +85,13 @@ final class FullDuplexHttpChannel {
}
};
ping.start();
main(channel);
channel.join();
ping.interrupt();
}
protected abstract void main(Channel channel) throws IOException, InterruptedException;
/**
* This is where we receive inputs from the client.
*/
......
......@@ -44,6 +44,7 @@ import hudson.ExtensionList;
import hudson.ExtensionPoint;
import hudson.DescriptorExtensionList;
import hudson.ExtensionListView;
import hudson.cli.CliEntryPoint;
import hudson.logging.LogRecorderManager;
import hudson.lifecycle.Lifecycle;
import hudson.model.Descriptor.FormException;
......@@ -147,6 +148,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URL;
import java.security.SecureRandom;
import java.text.NumberFormat;
......@@ -2651,12 +2653,25 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
rsp.getWriter().println("GCed");
}
/**
* {@link CliEntryPoint} implementation exposed to the remote CLI.
*/
private final class CliManager implements CliEntryPoint, Serializable {
public int main(String[] args) {
System.out.println(Arrays.asList(args));
return 0;
}
private Object writeReplace() {
return Channel.current().export(CliEntryPoint.class,this);
}
}
private transient final Map<UUID,FullDuplexHttpChannel> duplexChannels = new HashMap<UUID, FullDuplexHttpChannel>();
/**
* Handles HTTP requests for duplex channels.
* Handles HTTP requests for duplex channels for CLI.
*/
public void doDuplexChannel(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException {
public void doCli(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException {
checkPermission(READ);
requirePOST();
......@@ -2664,7 +2679,11 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
FullDuplexHttpChannel server;
if(req.getHeader("Side").equals("download")) {
duplexChannels.put(uuid,server=new FullDuplexHttpChannel(uuid, !hasPermission(ADMINISTER)));
duplexChannels.put(uuid,server=new FullDuplexHttpChannel(uuid, !hasPermission(ADMINISTER)) {
protected void main(Channel channel) throws IOException, InterruptedException {
channel.setProperty(CliEntryPoint.class.getName(),new CliManager());
}
});
try {
server.download(req,rsp);
} finally {
......@@ -2675,14 +2694,6 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
}
}
/**
* Called by the CLI over a {@link Channel} to execute an CLI command.
*/
public static int cli(String... args) {
System.out.println(Arrays.asList(args));
return 0;
}
/**
* Binds /userContent/... to $HUDSON_HOME/userContent.
*/
......
......@@ -97,7 +97,7 @@ import java.net.URL;
*
* @author Kohsuke Kawaguchi
*/
public class Channel implements VirtualChannel {
public class Channel implements VirtualChannel, IChannel {
private final ObjectInputStream ois;
private final ObjectOutputStream oos;
private final String name;
......@@ -173,6 +173,16 @@ public class Channel implements VirtualChannel {
*/
public final AtomicInteger resourceLoadingCount = new AtomicInteger();
/**
* Property bag that contains application-specific stuff.
*/
private final Hashtable<Object,Object> properties = new Hashtable<Object,Object>();
/**
* Proxy to the remote {@link Channel} object.
*/
private IChannel remoteChannel;
/**
* Communication mode.
* @since 1.161
......@@ -276,6 +286,10 @@ public class Channel implements VirtualChannel {
this.isRestricted = restricted;
ObjectOutputStream oos = null;
if(export(this,false)!=1)
throw new AssertionError(); // export number 1 is reserved for the channel itself
remoteChannel = RemoteInvocationHandler.wrap(this,1,IChannel.class,false);
// write the magic preamble.
// certain communication channel, such as forking JVM via ssh,
// may produce some garbage at the beginning (for example a remote machine
......@@ -662,6 +676,27 @@ public class Channel implements VirtualChannel {
// termination is done by CloseCommand when we received it.
}
/**
* Gets the application specific property set by {@link #setProperty(Object, Object)}.
* These properties are also accessible from the remote channel via {@link #getRemoteProperty(Object)}.
*
* <p>
* This mechanism can be used for one side to discover contextual objects created by the other JVM
* (as opposed to executing {@link Callable}, which cannot have any reference to the context
* of the remote {@link Channel}.
*/
public Object getProperty(Object key) {
return properties.get(key);
}
public Object setProperty(Object key, Object value) {
return properties.put(key,value);
}
public Object getRemoteProperty(Object key) {
return remoteChannel.getProperty(key);
}
public String toString() {
return super.toString()+":"+name;
}
......
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.remoting;
/**
* Internally used to mark methods on {@link Channel} that are exported to remote.
*
* @author Kohsuke Kawaguchi
*/
interface IChannel {
Object getProperty(Object key);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册