Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Persist a user-requested offline status for a slave across
restarts. Previously slaves would come back online if the server
was restarted while they were marked 'temporarily offline'.

I believe this also addresses JENKINS-7934 and JENKINS-7805
which look like duplicates.
  • Loading branch information
nparry authored and abayer committed Feb 4, 2011
1 parent d990fbb commit a88920a
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
11 changes: 11 additions & 0 deletions core/src/main/java/hudson/model/Computer.java
Expand Up @@ -509,6 +509,7 @@ public void setTemporarilyOffline(boolean temporarilyOffline) {
public void setTemporarilyOffline(boolean temporarilyOffline, OfflineCause cause) {
offlineCause = temporarilyOffline ? cause : null;
this.temporarilyOffline = temporarilyOffline;
getNode().setTemporaryOfflineCause(offlineCause);
Hudson.getInstance().getQueue().scheduleMaintenance();
}

Expand Down Expand Up @@ -563,6 +564,16 @@ protected void setNode(Node node) {
this.nodeName = null;

setNumExecutors(node.getNumExecutors());
if (this.temporarilyOffline) {
// When we get a new node, push our current temp offline
// status to it (as the status is not carried across
// configuration changes that recreate the node).
// Since this is also called the very first time this
// Computer is created, avoid pushing an empty status
// as that could overwrite any status that the Node
// brought along from its persisted config data.
node.setTemporaryOfflineCause(this.offlineCause);
}
}

/**
Expand Down
42 changes: 42 additions & 0 deletions core/src/main/java/hudson/model/Node.java
Expand Up @@ -25,6 +25,7 @@
package hudson.model;

import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import hudson.Extension;
import hudson.ExtensionPoint;
import hudson.FilePath;
import hudson.FileSystemProvisioner;
Expand All @@ -37,9 +38,11 @@
import hudson.security.ACL;
import hudson.security.AccessControlled;
import hudson.security.Permission;
import hudson.slaves.ComputerListener;
import hudson.slaves.NodeDescriptor;
import hudson.slaves.NodeProperty;
import hudson.slaves.NodePropertyDescriptor;
import hudson.slaves.OfflineCause;
import hudson.util.ClockDifference;
import hudson.util.DescribableList;
import hudson.util.EnumConverter;
Expand All @@ -51,6 +54,7 @@
import java.util.HashSet;
import java.util.Set;
import java.util.List;
import java.util.logging.Logger;

import org.kohsuke.stapler.Stapler;
import org.kohsuke.stapler.export.ExportedBean;
Expand All @@ -68,6 +72,9 @@
*/
@ExportedBean
public abstract class Node extends AbstractModelObject implements Describable<Node>, ExtensionPoint, AccessControlled {

private static final Logger LOGGER = Logger.getLogger(Node.class.getName());

/**
* Newly copied slaves get this flag set, so that Hudson doesn't try to start this node until its configuration
* is saved once.
Expand Down Expand Up @@ -165,6 +172,41 @@ public final VirtualChannel getChannel() {
*/
protected abstract Computer createComputer();

/**
* Let Nodes be aware of the lifecycle of their own {@link Computer}.
*/
@Extension
public static class InternalComputerListener extends ComputerListener {
@Override
public void onOnline(Computer c, TaskListener listener) {
Node node = c.getNode();

// At startup, we need to restore any previously in-effect temp offline cause.
// We wait until the computer is started rather than getting the data to it sooner
// so that the normal computer start up processing works as expected.
if (node.temporaryOfflineCause != null && node.temporaryOfflineCause != c.getOfflineCause()) {
c.setTemporarilyOffline(true, node.temporaryOfflineCause);
}
}
}

private OfflineCause temporaryOfflineCause;

/**
* Enable a {@link Computer} to inform its node when it is taken
* temporarily offline.
*/
void setTemporaryOfflineCause(OfflineCause cause) {
try {
if (temporaryOfflineCause != cause) {
temporaryOfflineCause = cause;
Hudson.getInstance().save(); // Gotta be a better way to do this
}
} catch (java.io.IOException e) {
LOGGER.warning("Unable to complete save, temporary offline status will not be persisted: " + e.getMessage());
}
}

/**
* Return the possibly empty tag cloud for the labels of this node.
*/
Expand Down

0 comments on commit a88920a

Please sign in to comment.