Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jenkins How to find if a given slave is running a Job

I have this unique requirement to check if the given node is running a job or not. I am thinking of using groovy as it looks easiest option.

I have found this answer to be useful.

How can I check via a script or a plugin in Jenkins whether a slave is online before starting a build from another project on it

It allows me to find if the slave is online or not. Next step for me is to check if it is running a job.

I was considering using the API function setAcceptingTasks(false) to mark slave as running a Job so that when next time I query using isAcceptingTasks(), I get false and hence do not launch job on that slave.

But I would rather have the slave mark itself.

taskAccepted() and taskCompleted() come to mind. I can call the setAcceptingTasks to false once task is accepted and on completion of tasks set isAcceptingTasks to true once again.

But I am not sure of the arguments these functions take e.g executor and task. And where do these function calls fit in a groovy script.

I am not sure if my assumption of task is equivalent to a job is true or not.

This is what I have got till now:

import hudson.model.*
def requiredNodes = ['Slave1', 'Slave2', 'Slave3'];
def status = 0;
for (node in requiredNodes) 
{
      println "Searching for $node";
      slave = Hudson.instance.slaves.find({it.name == node});
      if (slave != null)
       {
        computer = slave.getComputer();
        if (computer.isOffline())
         {
           println "Error! $node is offline.";
           status = 1;
         }
         else 
         {
           println "OK: $node is online";
           if(computer.isAcceptingTasks())
           {
              //Launch job
           }
         }
       }
       else 
       {
         println "Slave $node not found!";
         status = 1;
       }
}
status;

EDIT: Number of executors on each slave is 1.

like image 346
NotAgain says Reinstate Monica Avatar asked Nov 26 '14 06:11

NotAgain says Reinstate Monica


2 Answers

Here is the hackish way I was able to do it. I changed my workflow to find the available free slave rather than finding if a slave was busy and then checking the next one to see it is free. This groovy script counts the number of busy executors on the Slave. It polls continuously till it finds an online slave with zero number of busy executors. I hate polling and will request knowledgeable members to chip in with suggestions to somehow plug into Jenkins event based notification.

import hudson.FilePath
import hudson.model.Node
import hudson.model.Slave
import jenkins.model.Jenkins
import groovy.time.*

Jenkins jenkins = Jenkins.instance
def jenkinsNodes =jenkins.nodes
while(1)
{
    for (Node node in jenkinsNodes) 
    {
        sleep(1000)
        // Make sure slave is online
        if (!node.getComputer().isOffline()) 
        {           
            //Make sure that the slave busy executor number is 0.
            if(node.getComputer().countBusy()==0)
            {
                println "'$node.nodeName' can take jobs !!!"
                return 0
            }
            else
            {
                println "$node.nodeName' is busy !!!"
            }
        }
        else
        {
            println "'$node.nodeName' is offline !!!" 
        }
    }
    sleep(1000)
}

This runs as job and returns as soon as it finds a suitable slave. Return 0 is a success in Jenkins.

If there is any better way of doing it please chip in. I am not really happy with this continuous polling I have to to. Also I am not an expert on executors. So any flaws if there, please correct me.

like image 132
NotAgain says Reinstate Monica Avatar answered Sep 21 '22 07:09

NotAgain says Reinstate Monica


Let me propose a very simple and efficient way

Each node stores the information related to if it example : idle or not , offline or not etc

You can get those details using below command

curl -X GET --silent -u jenkins_user:${jenkins_pwd} "http://your_jenkins_url:8080/computer/node_name/api/json"

or directly from browser

http://your_jenkins_url:8080/computer/node_name/api/jso

This result provides valuable information related to slave.

If you want narrow down the search to a specific thing like , is the slave idle or not then you can append it with below logic

curl -X GET --silent -u jenkins_user:${jenkins_pwd} "http://jenkins_domanin:8080/computer/node_name/api/json" | python -c 'import json,sys,os;obj=json.load(sys.stdin);print obj["idle"]'
like image 34
prudviraj Avatar answered Sep 19 '22 07:09

prudviraj