Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fix JENKINS-8196

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...
commit a88920aab7b1e35c24b4adb7a297bd04d35ed9a3 1 parent d990fbb
Nathan Parry authored February 03, 2011 abayer committed February 04, 2011
11  core/src/main/java/hudson/model/Computer.java
@@ -509,6 +509,7 @@ public void setTemporarilyOffline(boolean temporarilyOffline) {
509 509
     public void setTemporarilyOffline(boolean temporarilyOffline, OfflineCause cause) {
510 510
         offlineCause = temporarilyOffline ? cause : null;
511 511
         this.temporarilyOffline = temporarilyOffline;
  512
+        getNode().setTemporaryOfflineCause(offlineCause);
512 513
         Hudson.getInstance().getQueue().scheduleMaintenance();
513 514
     }
514 515
 
@@ -563,6 +564,16 @@ protected void setNode(Node node) {
563 564
             this.nodeName = null;
564 565
 
565 566
         setNumExecutors(node.getNumExecutors());
  567
+        if (this.temporarilyOffline) {
  568
+            // When we get a new node, push our current temp offline
  569
+            // status to it (as the status is not carried across
  570
+            // configuration changes that recreate the node).
  571
+            // Since this is also called the very first time this
  572
+            // Computer is created, avoid pushing an empty status
  573
+            // as that could overwrite any status that the Node
  574
+            // brought along from its persisted config data.
  575
+            node.setTemporaryOfflineCause(this.offlineCause);
  576
+        }
566 577
     }
567 578
 
568 579
     /**
42  core/src/main/java/hudson/model/Node.java
@@ -25,6 +25,7 @@
25 25
 package hudson.model;
26 26
 
27 27
 import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
  28
+import hudson.Extension;
28 29
 import hudson.ExtensionPoint;
29 30
 import hudson.FilePath;
30 31
 import hudson.FileSystemProvisioner;
@@ -37,9 +38,11 @@
37 38
 import hudson.security.ACL;
38 39
 import hudson.security.AccessControlled;
39 40
 import hudson.security.Permission;
  41
+import hudson.slaves.ComputerListener;
40 42
 import hudson.slaves.NodeDescriptor;
41 43
 import hudson.slaves.NodeProperty;
42 44
 import hudson.slaves.NodePropertyDescriptor;
  45
+import hudson.slaves.OfflineCause;
43 46
 import hudson.util.ClockDifference;
44 47
 import hudson.util.DescribableList;
45 48
 import hudson.util.EnumConverter;
@@ -51,6 +54,7 @@
51 54
 import java.util.HashSet;
52 55
 import java.util.Set;
53 56
 import java.util.List;
  57
+import java.util.logging.Logger;
54 58
 
55 59
 import org.kohsuke.stapler.Stapler;
56 60
 import org.kohsuke.stapler.export.ExportedBean;
@@ -68,6 +72,9 @@
68 72
  */
69 73
 @ExportedBean
70 74
 public abstract class Node extends AbstractModelObject implements Describable<Node>, ExtensionPoint, AccessControlled {
  75
+
  76
+    private static final Logger LOGGER = Logger.getLogger(Node.class.getName());
  77
+
71 78
     /**
72 79
      * Newly copied slaves get this flag set, so that Hudson doesn't try to start this node until its configuration
73 80
      * is saved once.
@@ -166,6 +173,41 @@ public final VirtualChannel getChannel() {
166 173
     protected abstract Computer createComputer();
167 174
 
168 175
     /**
  176
+     * Let Nodes be aware of the lifecycle of their own {@link Computer}.
  177
+     */
  178
+    @Extension
  179
+    public static class InternalComputerListener extends ComputerListener {
  180
+        @Override
  181
+        public void onOnline(Computer c, TaskListener listener) {
  182
+            Node node = c.getNode();
  183
+
  184
+            // At startup, we need to restore any previously in-effect temp offline cause.
  185
+            // We wait until the computer is started rather than getting the data to it sooner
  186
+            // so that the normal computer start up processing works as expected.
  187
+            if (node.temporaryOfflineCause != null && node.temporaryOfflineCause != c.getOfflineCause()) {
  188
+                c.setTemporarilyOffline(true, node.temporaryOfflineCause);
  189
+            }
  190
+        }
  191
+    }
  192
+
  193
+    private OfflineCause temporaryOfflineCause;
  194
+
  195
+    /**
  196
+     * Enable a {@link Computer} to inform its node when it is taken
  197
+     * temporarily offline.
  198
+     */
  199
+    void setTemporaryOfflineCause(OfflineCause cause) {
  200
+        try {
  201
+            if (temporaryOfflineCause != cause) {
  202
+                temporaryOfflineCause = cause;
  203
+                Hudson.getInstance().save(); // Gotta be a better way to do this
  204
+            }
  205
+        } catch (java.io.IOException e) {
  206
+            LOGGER.warning("Unable to complete save, temporary offline status will not be persisted: " + e.getMessage());
  207
+        }
  208
+    }
  209
+
  210
+    /**
169 211
      * Return the possibly empty tag cloud for the labels of this node.
170 212
      */
171 213
     public TagCloud<LabelAtom> getLabelCloud() {

0 notes on commit a88920a

Please sign in to comment.
Something went wrong with that request. Please try again.