26

While using the Jenkins Docker Plugin, probably because of an error, swarms cannot be launched. I didn't pay attention and at the moment I have thousands of offline nodes, that were failed to launch.

BOTTOM LINE - Is there a way to batch remove nodes (slaves) in Jenkin, clean all offline nodes or even delete all nodes? Restating the Jenkins server didn't help, and I couldn't find a way in the Jenkins API.

Will appreciate any idea, before I'm starting to write a Selenium script or something...

Many thanks!

AlonL
  • 6,100
  • 3
  • 33
  • 32

3 Answers3

39

This is the Copy>Paste>Run version of KeepCalmAndCarryOn answer. Go to manage Jenkins > Script Console > copy & paste this code > Run

for (aSlave in hudson.model.Hudson.instance.slaves) {
    if (aSlave.getComputer().isOffline()) {
        aSlave.getComputer().setTemporarilyOffline(true,null);
        aSlave.getComputer().doDoDelete();
    }
}

enter image description here

Nayana Adassuriya
  • 23,596
  • 30
  • 104
  • 147
30

There is this script with a section commented out to delete nodes.

It runs in the Jenkins script console

for (aSlave in hudson.model.Hudson.instance.slaves) {
  println('====================');
  println('Name: ' + aSlave.name);
  println('getLabelString: ' + aSlave.getLabelString());
  println('getNumExectutors: ' + aSlave.getNumExecutors());
  println('getRemoteFS: ' + aSlave.getRemoteFS());
  println('getMode: ' + aSlave.getMode());
  println('getRootPath: ' + aSlave.getRootPath());
  println('getDescriptor: ' + aSlave.getDescriptor());
  println('getComputer: ' + aSlave.getComputer());
  println('\tcomputer.isAcceptingTasks: ' + aSlave.getComputer().isAcceptingTasks());
  println('\tcomputer.isLaunchSupported: ' + aSlave.getComputer().isLaunchSupported());
  println('\tcomputer.getConnectTime: ' + aSlave.getComputer().getConnectTime());
  println('\tcomputer.getDemandStartMilliseconds: ' + aSlave.getComputer().getDemandStartMilliseconds());
  println('\tcomputer.isOffline: ' + aSlave.getComputer().isOffline());
  println('\tcomputer.countBusy: ' + aSlave.getComputer().countBusy());
  //if (aSlave.name == 'NAME OF NODE TO DELETE') {
  //  println('Shutting down node!!!!');
  //  aSlave.getComputer().setTemporarilyOffline(true,null);
  //  aSlave.getComputer().doDoDelete();
  //}
  println('\tcomputer.getLog: ' + aSlave.getComputer().getLog());
  println('\tcomputer.getBuilds: ' + aSlave.getComputer().getBuilds());
}
KeepCalmAndCarryOn
  • 8,817
  • 2
  • 32
  • 47
  • 1
    This solution is good (in the sense that if there's a node running any job(s), then it'll at least first mark the SLAVE node as OFFLINE and then wait for the job(s) to complete), great! But if we enable the "DELETE" part here then, there's a problem i.e. if any of the slave node is running any JOB(s) then, all of those jobs will be aborted (which is not good). With a little more enhancement to this script, we can make the script intelligent enough to HOLD until all slave's are free (either online/offline) and then delete them gracefully. I'll post answer shortly. – AKS Jan 21 '16 at 01:44
  • See here: http://stackoverflow.com/questions/34910485/block-a-job-from-running-if-given-nodes-with-a-given-labels-is-are-running-a for a similar solution – AKS Jan 21 '16 at 03:04
0

Thanks for the great answer.

Another way of doing it is by manually editing the '${JENKINS_HOME}/config.xml' file (and find/replace by regex, for example).

AKS
  • 16,482
  • 43
  • 166
  • 258
AlonL
  • 6,100
  • 3
  • 33
  • 32