> implements Saveable {
* null to indicate that there's no help.
*/
public String getHelpFile() {
- InputStream in = getHelpStream();
+ return getHelpFile(null);
+ }
+
+ /**
+ * Returns the path to the help screen HTML for the given field.
+ *
+ *
+ * The help files are assumed to be at "help/FIELDNAME.html" with possible
+ * locale variations.
+ */
+ public String getHelpFile(String fieldName) {
+ if(fieldName==null) fieldName="";
+ else fieldName='/'+fieldName;
+
+ String page = "/descriptor/" + clazz.getName() + "/help"+fieldName;
+
+ try {
+ if(Stapler.getCurrentRequest().getView(clazz,"help"+fieldName+".jelly")!=null)
+ return page;
+ } catch (IOException e) {
+ throw new Error(e);
+ }
+
+ InputStream in = getHelpStream(fieldName);
IOUtils.closeQuietly(in);
- if(in!=null) return "/descriptor/"+clazz.getName()+"/help";
+ if(in!=null) return page;
return null;
}
@@ -475,8 +504,17 @@ public abstract class Descriptor> implements Saveable {
/**
* Serves help.html from the resource of {@link #clazz}.
*/
- public void doHelp(StaplerResponse rsp) throws IOException {
- InputStream in = getHelpStream();
+ public void doHelp(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
+ String path = req.getRestOfPath();
+ if(path.contains("..")) throw new ServletException("Illegal path: "+path);
+
+ RequestDispatcher rd = Stapler.getCurrentRequest().getView(clazz, "help"+path+".jelly");
+ if(rd!=null) {// Jelly-generated help page
+ rd.forward(req,rsp);
+ return;
+ }
+
+ InputStream in = getHelpStream(path);
if(in==null) {
rsp.sendError(SC_NOT_FOUND);
return;
@@ -487,10 +525,10 @@ public abstract class Descriptor> implements Saveable {
in.close();
}
- private InputStream getHelpStream() {
+ private InputStream getHelpStream(String suffix) {
Locale locale = Stapler.getCurrentRequest().getLocale();
- String base = clazz.getName().replace('.', '/') + "/help";
+ String base = clazz.getName().replace('.', '/') + "/help"+suffix;
InputStream in;
in = clazz.getClassLoader().getResourceAsStream(base + '_' + locale.getLanguage() + '_' + locale.getCountry() + '_' + locale.getVariant() + ".html");
@@ -516,10 +554,7 @@ public abstract class Descriptor> implements Saveable {
}
public static List toList( T... values ) {
- final ArrayList r = new ArrayList();
- for (T v : values)
- r.add(v);
- return r;
+ return new ArrayList(Arrays.asList(values));
}
public static >
@@ -625,4 +660,4 @@ public abstract class Descriptor> implements Saveable {
throw new AssertionError();
}
}
-}
+}
\ No newline at end of file
diff --git a/core/src/main/java/hudson/model/Slave.java b/core/src/main/java/hudson/model/Slave.java
index d735316ade203a749682ae506adad53526e4d9bf..1af08b103172dd8fea8b5c8b6e42cca87c5e5f84 100644
--- a/core/src/main/java/hudson/model/Slave.java
+++ b/core/src/main/java/hudson/model/Slave.java
@@ -27,21 +27,18 @@ import hudson.FilePath;
import hudson.Launcher;
import hudson.Launcher.RemoteLauncher;
import hudson.Util;
-import hudson.slaves.ComputerLauncher;
-import hudson.slaves.RetentionStrategy;
-import hudson.slaves.CommandLauncher;
-import hudson.slaves.JNLPLauncher;
-import hudson.slaves.SlaveComputer;
-import hudson.slaves.DumbSlave;
+import hudson.slaves.*;
import hudson.model.Descriptor.FormException;
import hudson.remoting.Callable;
import hudson.remoting.VirtualChannel;
import hudson.tasks.DynamicLabeler;
import hudson.tasks.LabelFinder;
import hudson.util.ClockDifference;
+import hudson.util.FormFieldValidator.NonNegativeInteger;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.DataBoundConstructor;
+import org.kohsuke.stapler.WebMethod;
import org.apache.commons.io.IOUtils;
import javax.servlet.ServletException;
@@ -391,6 +388,15 @@ public abstract class Slave extends Node implements Serializable {
return this;
}
+ public abstract SlaveDescriptor getDescriptor();
+
+ public static abstract class SlaveDescriptor extends NodeDescriptor {
+ public void doCheckNumExecutors() throws IOException, ServletException {
+ new NonNegativeInteger().process();
+ }
+ }
+
+
//
// backwrad compatibility
//
diff --git a/core/src/main/java/hudson/slaves/DumbSlave.java b/core/src/main/java/hudson/slaves/DumbSlave.java
index d1d0ad2b6f2e5b0386ab08147fe478c1722b2044..a5927c54f9d24952f8c4c5e7364a4d3897747817 100644
--- a/core/src/main/java/hudson/slaves/DumbSlave.java
+++ b/core/src/main/java/hudson/slaves/DumbSlave.java
@@ -25,12 +25,8 @@ package hudson.slaves;
import hudson.model.Descriptor.FormException;
import hudson.model.Slave;
-import hudson.util.FormFieldValidator.NonNegativeInteger;
import org.kohsuke.stapler.DataBoundConstructor;
-import javax.servlet.ServletException;
-import java.io.IOException;
-
/**
* Default {@link Slave} implementation for computers that do not belong to a higher level structure,
* like grid or cloud.
@@ -47,16 +43,12 @@ public final class DumbSlave extends Slave {
return DescriptorImpl.INSTANCE;
}
- public static final class DescriptorImpl extends NodeDescriptor {
+ public static final class DescriptorImpl extends SlaveDescriptor {
public static final DescriptorImpl INSTANCE = new DescriptorImpl();
public String getDisplayName() {
return Messages.DumbSlave_displayName();
}
-
- public void doCheckNumExecutors() throws IOException, ServletException {
- new NonNegativeInteger().process();
- }
}
static {
diff --git a/core/src/main/resources/hudson/model/Slave/help/launcher.jelly b/core/src/main/resources/hudson/model/Slave/help/launcher.jelly
new file mode 100644
index 0000000000000000000000000000000000000000..01f8c4c467c15312158a1455ebe77029422feb24
--- /dev/null
+++ b/core/src/main/resources/hudson/model/Slave/help/launcher.jelly
@@ -0,0 +1,40 @@
+
+
+
+
+
+ Controls how Hudson starts this slave.
+
+
+
+ - ${d.displayName}
+ -
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/src/main/resources/hudson/slaves/CommandLauncher/help.jelly b/core/src/main/resources/hudson/slaves/CommandLauncher/help.jelly
new file mode 100644
index 0000000000000000000000000000000000000000..8eb19203d6b7ccc9b13ef1aab71f791ada67740f
--- /dev/null
+++ b/core/src/main/resources/hudson/slaves/CommandLauncher/help.jelly
@@ -0,0 +1,29 @@
+
+
+
+ Starts a slave by having Hudson execute a command from the master.
+ Use this when the master is capable of remotely executing a process
+ on a slave, such as through ssh/rsh.
+
\ No newline at end of file
diff --git a/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries.jelly b/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries.jelly
index b89b79821dda405e1fe9846bed6d062b674a4be6..9d5ba795195c94dc3fdaa5db28a973a9de316638 100644
--- a/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries.jelly
+++ b/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries.jelly
@@ -48,7 +48,7 @@ THE SOFTWARE.
+ help="${descriptor.getHelpFile('launcher')}">
+
+
+ Starts a slave by launching an agent program through
+ JNLP.
+ The launch in this case is initiated by the slave,
+ although it is possible to start a launch without GUI, for example
+ as a Windows service.
+
\ No newline at end of file