diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index a89857c06df9b7365e7944e777bcd828d47a3e3b..9c9bef72a391f9d014d126d026790d3ad9c8093a 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -14,7 +14,7 @@ import hudson.security.AuthorizationStrategy; import hudson.security.Permission; import hudson.util.Area; import hudson.slaves.SlaveStartMethod; -import hudson.slaves.SlaveAvailabilityStrategy; +import hudson.slaves.RetentionStrategy; import org.apache.commons.jexl.parser.ASTSizeFunction; import org.apache.commons.jexl.util.Introspector; import org.apache.commons.jelly.JellyContext; @@ -498,8 +498,8 @@ public class Functions { return SlaveStartMethod.LIST; } - public static List> getSlaveAvailabilityStrategyDescriptors() { - return SlaveAvailabilityStrategy.LIST; + public static List>> getSlaveAvailabilityStrategyDescriptors() { + return RetentionStrategy.LIST; } /** diff --git a/core/src/main/java/hudson/model/Computer.java b/core/src/main/java/hudson/model/Computer.java index f0b8ab36f340f05df7b61942c03caef83b8ca123..c311ae8e681cc8d8ed68a118d8c42315199deab6 100644 --- a/core/src/main/java/hudson/model/Computer.java +++ b/core/src/main/java/hudson/model/Computer.java @@ -2,6 +2,7 @@ package hudson.model; import hudson.EnvVars; import hudson.slaves.SlaveStartMethod; +import hudson.slaves.RetentionStrategy; import hudson.node_monitors.NodeMonitor; import hudson.remoting.Channel; import hudson.remoting.VirtualChannel; @@ -253,7 +254,7 @@ public abstract class Computer extends AbstractModelObject { /** * Returns true if all the executors of this computer is idle. */ - public boolean isIdle() { + public final boolean isIdle() { for (Executor e : executors) if(!e.isIdle()) return false; @@ -282,6 +283,14 @@ public abstract class Computer extends AbstractModelObject { return "computer/"+nodeName; } + /** + * {@link RetentionStrategy} associated with this computer. + * + * @return + * never null. + */ + public abstract RetentionStrategy getRetentionStrategy(); + /** * Expose monitoring data for the remote API. */ diff --git a/core/src/main/java/hudson/model/Hudson.java b/core/src/main/java/hudson/model/Hudson.java index 34d4e98f5a109e238026ba0e47ad48f0345a5968..e7895c1be9a2520ab7f50a195fe3a0aa0a2f55df 100644 --- a/core/src/main/java/hudson/model/Hudson.java +++ b/core/src/main/java/hudson/model/Hudson.java @@ -15,7 +15,7 @@ import hudson.Util; import static hudson.Util.fixEmpty; import hudson.XmlFile; import hudson.slaves.SlaveStartMethod; -import hudson.slaves.SlaveAvailabilityStrategy; +import hudson.slaves.RetentionStrategy; import hudson.model.Descriptor.FormException; import hudson.model.listeners.ItemListener; import hudson.model.listeners.JobListener; @@ -1524,8 +1524,8 @@ public final class Hudson extends View implements ItemGroup, Node, private Slave newSlave(StaplerRequest req, JSONObject j) throws FormException { final SlaveStartMethod startMethod = newDescribedChild(req, j, "startMethod", SlaveStartMethod.LIST); - final SlaveAvailabilityStrategy availabilityStrategy = - newDescribedChild(req, j, "availabilityStrategy", SlaveAvailabilityStrategy.LIST); + final RetentionStrategy availabilityStrategy = + newDescribedChild(req, j, "availabilityStrategy", RetentionStrategy.LIST); final Slave slave = req.bindJSON(Slave.class, j); slave.setStartMethod(startMethod); slave.setAvailabilityStrategy(availabilityStrategy); @@ -2356,6 +2356,10 @@ public final class Hudson extends View implements ItemGroup, Node, return "computer/(master)/"; } + public RetentionStrategy getRetentionStrategy() { + return RetentionStrategy.Always.INSTANCE; + } + @Override public VirtualChannel getChannel() { return localChannel; diff --git a/core/src/main/java/hudson/model/Slave.java b/core/src/main/java/hudson/model/Slave.java index 58c0175cde099b801a54365084e74d24c86555a5..88493aa9120d0168600c94df9408ad823920df48 100644 --- a/core/src/main/java/hudson/model/Slave.java +++ b/core/src/main/java/hudson/model/Slave.java @@ -5,7 +5,7 @@ import hudson.Launcher; import hudson.Launcher.RemoteLauncher; import hudson.Util; import hudson.slaves.SlaveStartMethod; -import hudson.slaves.SlaveAvailabilityStrategy; +import hudson.slaves.RetentionStrategy; import hudson.slaves.CommandStartMethod; import hudson.slaves.JNLPStartMethod; import hudson.slaves.SlaveComputer; @@ -15,7 +15,6 @@ import hudson.remoting.VirtualChannel; import hudson.tasks.DynamicLabeler; import hudson.tasks.LabelFinder; import hudson.util.ClockDifference; -import hudson.util.RingBufferLogHandler; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; @@ -27,7 +26,6 @@ import java.io.Serializable; import java.net.URL; import java.net.URLConnection; import java.util.*; -import java.util.logging.Logger; /** * Information about a Hudson slave node. @@ -68,7 +66,7 @@ public final class Slave implements Node, Serializable { /** * Slave availablility strategy. */ - private SlaveAvailabilityStrategy availabilityStrategy; + private RetentionStrategy availabilityStrategy; /** * The starter that will startup this slave. @@ -144,11 +142,11 @@ public final class Slave implements Node, Serializable { return mode; } - public SlaveAvailabilityStrategy getAvailabilityStrategy() { - return availabilityStrategy == null ? new SlaveAvailabilityStrategy.Always() : availabilityStrategy; + public RetentionStrategy getAvailabilityStrategy() { + return availabilityStrategy == null ? RetentionStrategy.Always.INSTANCE : availabilityStrategy; } - public void setAvailabilityStrategy(SlaveAvailabilityStrategy availabilityStrategy) { + public void setAvailabilityStrategy(RetentionStrategy availabilityStrategy) { this.availabilityStrategy = availabilityStrategy; } @@ -306,7 +304,7 @@ public final class Slave implements Node, Serializable { public Launcher createLauncher(TaskListener listener) { SlaveComputer c = getComputer(); - return new RemoteLauncher(listener, c.getChannel(), c.isUnix); + return new RemoteLauncher(listener, c.getChannel(), c.isUnix()); } /** diff --git a/core/src/main/java/hudson/slaves/RetentionStrategy.java b/core/src/main/java/hudson/slaves/RetentionStrategy.java new file mode 100644 index 0000000000000000000000000000000000000000..c8645d318404510ea8a88cab9f1d6ca941679386 --- /dev/null +++ b/core/src/main/java/hudson/slaves/RetentionStrategy.java @@ -0,0 +1,73 @@ +package hudson.slaves; + +import hudson.ExtensionPoint; +import hudson.model.Describable; +import hudson.model.Descriptor; +import hudson.model.Computer; +import hudson.util.DescriptorList; +import org.kohsuke.stapler.DataBoundConstructor; + +/** + * Controls when to take {@link Computer} offline, bring it back online, or even to destroy it. + * + *

+ * EXPERIMENTAL: SIGNATURE MAY CHANGE IN FUTURE RELEASES + */ +public abstract class RetentionStrategy implements Describable>, ExtensionPoint { + + /** + * This method will be called periodically to allow this strategy to decide what to do with it's owning slave. + * + * @param c + * {@link Computer} for which this strategy is assigned. This object also exposes a bunch of properties + * that the callee can use to decide what action to take. + * + * @return The number of minutes after which the strategy would like to be checked again. The strategy may be + * rechecked earlier or later that this! + */ + public abstract long check(T c); + + /** + * All registered {@link RetentionStrategy} implementations. + */ + public static final DescriptorList> LIST = new DescriptorList>( + Always.DESCRIPTOR + ); + + + /** + * {@link RetentionStrategy} that tries to keep the node online all the time. + */ + public static class Always extends RetentionStrategy { + @DataBoundConstructor + public Always() { + } + + public long check(SlaveComputer c) { + if (c.isOffline() && c.isLaunchSupported()) + c.tryReconnect(); + return 1; + } + + /** + * Convenient singleton instance, sine this {@link RetentionStrategy} is stateless. + */ + public static final Always INSTANCE = new Always(); + + public DescriptorImpl getDescriptor() { + return DESCRIPTOR; + } + + public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl(); + + private static class DescriptorImpl extends Descriptor> { + public DescriptorImpl() { + super(Always.class); + } + + public String getDisplayName() { + return "Keep this slave on-line as much as possible"; + } + } + } +} diff --git a/core/src/main/java/hudson/slaves/SlaveComputer.java b/core/src/main/java/hudson/slaves/SlaveComputer.java index 90b492f27019ae35b1efe824cc2a9b6ec748c4b9..da9826db672d2e5c8fa5a8c2e677ee7b9e00284d 100644 --- a/core/src/main/java/hudson/slaves/SlaveComputer.java +++ b/core/src/main/java/hudson/slaves/SlaveComputer.java @@ -45,7 +45,7 @@ import javax.servlet.http.HttpServletResponse; */ public final class SlaveComputer extends Computer { private volatile Channel channel; - private boolean isUnix; + private Boolean isUnix; /** * Number of failed attempts to reconnect to this node @@ -67,8 +67,11 @@ public final class SlaveComputer extends Computer { /** * True if this computer is a Unix machine (as opposed to Windows machine). + * + * @return + * null if the computer is disconnected and therefore we don't know whether it is Unix or not. */ - public boolean isUnix() { + public Boolean isUnix() { return isUnix; } @@ -232,6 +235,10 @@ public final class SlaveComputer extends Computer { closeChannel(); } + public RetentionStrategy getRetentionStrategy() { + return getNode().getAvailabilityStrategy(); + } + /** * If still connected, disconnect. */ diff --git a/core/src/main/java/hudson/slaves/SlaveReconnectionWork.java b/core/src/main/java/hudson/slaves/SlaveReconnectionWork.java index dfdb68cc039d0be1bc3705ee7cfeb5d6bd6b6688..144c0a63c0570712a0156f5c2d92e735fdbd758e 100644 --- a/core/src/main/java/hudson/slaves/SlaveReconnectionWork.java +++ b/core/src/main/java/hudson/slaves/SlaveReconnectionWork.java @@ -2,7 +2,6 @@ package hudson.slaves; import hudson.model.Computer; import hudson.model.Hudson; -import hudson.model.Queue; import hudson.triggers.SafeTimerTask; import java.util.Map; @@ -20,17 +19,11 @@ public class SlaveReconnectionWork extends SafeTimerTask { private final Map nextCheck = new WeakHashMap(); protected void doRun() { - final Queue queue = Hudson.getInstance().getQueue(); - for (Computer c : Hudson.getInstance().getComputers()) { if (!nextCheck.containsKey(c) || System.currentTimeMillis() > nextCheck.get(c)) { - boolean hasJob = !c.isIdle(); - - // TODO get only the items from the queue that can apply to this slave - SlaveAvailabilityStrategy.State state = new SlaveAvailabilityStrategy.State(queue.getItems().length > 0, hasJob); // at the moment I don't trust strategies to wait more than 60 minutes // strategies need to wait at least one minute - final long waitInMins = Math.min(1, Math.max(60, c.getAvailabilityStrategy().check(c, state))); + final long waitInMins = Math.min(1, Math.max(60, c.getRetentionStrategy().check(c))); nextCheck.put(c, System.currentTimeMillis() + 60 * 1000 * waitInMins); } } diff --git a/core/src/main/resources/hudson/model/Slave/ComputerImpl/disconnect.jelly b/core/src/main/resources/hudson/model/Slave/ComputerImpl/disconnect.jelly deleted file mode 100644 index 96f81057661f67d1744b8273f2c0ca7f64088374..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/ComputerImpl/disconnect.jelly +++ /dev/null @@ -1,12 +0,0 @@ - - - - - -

- Are you sure about disconnecting? - - - - - diff --git a/core/src/main/resources/hudson/model/Slave/ComputerImpl/log.jelly b/core/src/main/resources/hudson/model/Slave/ComputerImpl/log.jelly deleted file mode 100644 index cdaa2909407df8c51a08ff92812482fbfda1d39c..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/ComputerImpl/log.jelly +++ /dev/null @@ -1,14 +0,0 @@ - - - - - -

-        
- -
- -
-
-
-
diff --git a/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel.jelly b/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel.jelly deleted file mode 100644 index 970ec5d25708e95162a7d38ae30c374b1e2299e4..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel.jelly +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_fr.properties b/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_fr.properties deleted file mode 100644 index 50e7d1b7e375edebe8189f29630ba7df735daf4d..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_fr.properties +++ /dev/null @@ -1,6 +0,0 @@ -Back\ to\ List=Retour à la liste -Status=Statut -Build\ History=Historique des builds -Log= -System\ Information=Information système -Disconnect=Déconnection diff --git a/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_ja.properties b/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_ja.properties deleted file mode 100644 index a7bd95975c6fbf245b8ab569560ad6f09069e0e2..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_ja.properties +++ /dev/null @@ -1,6 +0,0 @@ -Back\ to\ List=\u30ea\u30b9\u30c8\u3078\u623b\u308b -Status=\u72b6\u614b -Build\ History=\u30d3\u30eb\u30c9\u5c65\u6b74 -Log=\u30ed\u30b0 -System\ Information=\u30b7\u30b9\u30c6\u30e0\u60c5\u5831 -Disconnect=\u5207\u65ad diff --git a/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_nl.properties b/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_nl.properties deleted file mode 100644 index ccd689b7b1e8f1dda7b30aabcf84147ae7cd28d0..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_nl.properties +++ /dev/null @@ -1,6 +0,0 @@ -Back\ to\ List=Terug naar de lijst -Status=Status -Build\ History=Overzicht bouwpogingen -Log=Log -System\ Information=Systeeminformatie -Disconnect=Loskoppelen diff --git a/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_pt_BR.properties b/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_pt_BR.properties deleted file mode 100644 index 2122c67a335e96bccd99f111c68ed82f6e0c560b..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_pt_BR.properties +++ /dev/null @@ -1,6 +0,0 @@ -Back\ to\ List=Voltar para a Lista -Status=Estado -Build\ History=Hist\u00F3rico de Constru\u00E7\u00F5es -Log= -System\ Information=Informa\u00E7\u00F5es do Sistema -Disconnect=Desconectar diff --git a/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_ru.properties b/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_ru.properties deleted file mode 100644 index 4f9ebfac115d4db28aabe067ba7c04a3004e37ef..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_ru.properties +++ /dev/null @@ -1,6 +0,0 @@ -Back\ to\ List=\u0412\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043a \u0441\u043f\u0438\u0441\u043a\u0443 -Status=\u0421\u0442\u0430\u0442\u0443\u0441 -Build\ History=\u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0441\u0431\u043e\u0440\u043e\u043a -Log=\u0416\u0443\u0440\u043d\u0430\u043b -System\ Information=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0441\u0438\u0441\u0442\u0435\u043c\u0435 -Disconnect=\u041e\u0442\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c diff --git a/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_tr.properties b/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_tr.properties deleted file mode 100644 index 60fbfeae5bd67d3ecfbaa70446cbb0caa6048c12..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/ComputerImpl/sidepanel_tr.properties +++ /dev/null @@ -1,6 +0,0 @@ -Back\ to\ List=Listeye D\u00f6n -Status=Durum -Build\ History=Yap\u0131land\u0131rma Ge\u00e7mi\u015fi -Log=Log -System\ Information=Sistem Bilgisi -Disconnect=Ba\u011flant\u0131y\u0131 Kes diff --git a/core/src/main/resources/hudson/model/Slave/ComputerImpl/slave-agent.jnlp.jelly b/core/src/main/resources/hudson/model/Slave/ComputerImpl/slave-agent.jnlp.jelly deleted file mode 100644 index c68ed0c3f462f368ee091477f8099e6a06c6ca37..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/ComputerImpl/slave-agent.jnlp.jelly +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - Slave Agent for ${it.displayName} - Hudson project - - - - - - - - - - - - - - - - - - - - - - - ${request.serverName} - ${rootURL}/tcpSlaveAgentListener/ - ${app.secretKey} - ${it.node.nodeName} - - - - diff --git a/core/src/main/resources/hudson/model/Slave/ComputerImpl/systemInfo.jelly b/core/src/main/resources/hudson/model/Slave/ComputerImpl/systemInfo.jelly deleted file mode 100644 index 945f16dd4614028ac9cad70ea6d1955cc26241f7..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/ComputerImpl/systemInfo.jelly +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - -

System Properties

- -

Environment Variables

- -

Thread Dump

- -

${t.key}

-
${t.value}
-
-
-
-
-