Java 詹金斯如何查找给定的奴隶是否正在运行作业

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27142674/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 03:53:21  来源:igfitidea点击:

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

javagroovyjenkins

提问by NotAgain says Reinstate Monica

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.

我有这个独特的要求来检查给定的节点是否正在运行作业。我正在考虑使用 groovy,因为它看起来是最简单的选择。

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

在从另一个项目开始构建之前,如何通过 Jenkins 中的脚本或插件检查从属设备是否在线

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 APIfunction 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.

我正在考虑使用API函数setAcceptingTasks(false)将 slave 标记为正在运行作业,以便下次我使用isAcceptingTasks()查询时,我得到 false,因此不会在该 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.

taskAccepted()taskCompleted()浮现在脑海中。 一旦任务被接受,我可以将 setAcceptingTasks 调用为 false,并在任务完成后再次将 isAcceptingTasks 设置为 true。

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.

但我不确定这些函数采用的参数,例如执行程序和任务。这些函数调用在哪里适合一个 groovy 脚本。

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.

编辑:每个从站上的执行程序数为 1。

采纳答案by NotAgain says Reinstate Monica

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.

这是我能够做到的hackish方式。我改变了我的工作流程来查找可用的空闲从站,而不是查找从站是否忙,然后检查下一个从站是否空闲。这个 groovy 脚本计算 Slave 上繁忙的 executors 的数量。它不断轮询,直到找到一个忙碌的执行器数量为零的在线从站。我讨厌投票,并会要求知识渊博的成员提供建议,以某种方式插入基于 Jenkins 事件的通知。

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.

这作为作业运行,并在找到合适的从站后立即返回。Return 0 在 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.

如果有更好的方法,请参与。我对这种必须进行的连续投票并不满意。我也不是执行者的专家。所以如果有任何缺陷,请纠正我。

回答by Raman Tretyak

To get the name of the node, that is running the current build, just use System.getenv("NODE_NAME")

要获取正在运行当前构建的节点的名称,只需使用 System.getenv("NODE_NAME")

When a Jenkins job executes, it sets some environment variables..

当 Jenkins 作业执行时,它会设置一些环境变量。

You may find these variables very useful. Check this link

您可能会发现这些变量非常有用。检查此链接

回答by prudviraj

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"]'