如果具有给定标签的给定节点正在运行另一个作业,则阻止该作业运行 [英] Block a job from running if given node(s) with a given label(s) is/are running another job(s)

查看:205
本文介绍了如果具有给定标签的给定节点正在运行另一个作业,则阻止该作业运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Jenkins中,如果作业B正在使用 Build blocker plugin (构建阻止程序插件)运行,我们可以封锁作业A.

In Jenkins, we can block a job A if job B is running using Build blocker plugin.

类似地或某种方式,我想要一份工作,例如: another_dumb_job 不要运行/(等待,然后坐下队列中),如果任何个正在进行的作业正在任何用户选择的从服务器上运行,直到这些从服务器再次空闲.

Similarly or in some fashion, I would like a job, for ex: another_dumb_job to NOT run / (wait and let it sit in queue) if there are any in-progress jobs running on any user selected slave(s) until those slaves are free again.

例如:我不想运行一个作业(它将离线/在线删除一堆奴隶,使用下游作业或通过调用一些groovy/scriptler脚本),直到这些奴隶中的任何一个拥有正在执行的当前/正在进行的作业?

For ex: I don't want to run a Job (which will delete bunch of slaves either offline/online -- using a downstream job or via calling some groovy/scriptler script) until any of those slave(s) have active/in-progress job(s) running on them?

最终目标是优雅地删除Jenkins节点从站,即先将节点/从站标记为OFFLINE,然后再完成任何现有作业(在从站上运行),然后再删除从站.

The end goal is to delete Jenkins node slaves gracefully i.e. the node/slave is marked OFFLINE first, then any existing jobs (running on a slave are complete) and then the slaves get deleted.

推荐答案

要删除所有脱机节点,请调整以下脚本,并仅在isOffline()为true或isOnline()为false的从属服务器上运行doDelete().如果要删除所有节点(请小心),请不要使用以下 if 语句:

For deleting all offline nodes, tweak the script below and run doDelete() only on slaves where isOffline() is true or isOnline() is false. If you want to delete all nodes (be careful) then don't use the the following if statement:

if ( aSlave.name.indexOf(slaveStartsWith) == 0) {

我也忽略(如果您要始终忽略删除该奴隶).可以增强使用从属列表忽略的功能.

I'm also ignoring a slave (if you want to ALWAYS ignore a slave from getting deleted). It can be enhanced to use a list of slaves to ignore.

无论如何,以下脚本会优雅地删除以给定名称开头的所有Jenkins节点从属服务器(以便您拥有更多控制权),并且它将标记为离线(尽快),但仅在之后给定从站上的所有正在运行的作业都已完成.以为我应该在这里分享.

Anyways, the following script will gracefully delete any Jenkins node slaves which starts with a given name (so that you have more control) and it'll mark offline (asap) but delete it only after any running job(s) on that given slave(s) is/are complete. Thought I should share here.

使用Jenkins Scriptler插件,可以导入/上传/运行此脚本:

Using Jenkins Scriptler Plugin, one can import/upload/run this script: https://github.com/gigaaks/jenkins-scripts/blob/7eaf41348e886db108bad9a72f876c3827085418/scriptler/disableSlaveNodeStartsWith.groovy

/*** BEGIN META {
  "name" : "Disable Jenkins Hudson slaves nodes gracefully for all slaves starting with a given value",
  "comment" : "Disables Jenkins Hudson slave nodes gracefully - waits until running jobs are complete.",
  "parameters" : [ 'slaveStartsWith'],
  "core": "1.350",
  "authors" : [
    { name : "GigaAKS" }, { name : "Arun Sangal" }
  ]
} END META**/

// This scriptler script will mark Jenkins slave nodes offline for all slaves which starts with a given value.
// It will wait for any slave nodes which are running any job(s) and then delete them.
// It requires only one parameter named: slaveStartsWith and value can be passed as: "swarm-".

import java.util.*
import jenkins.model.*
import hudson.model.*
import hudson.slaves.*

def atleastOneSlaveRunnning = true;
def time = new Date().format("HH:mm MM/dd/yy z",TimeZone.getTimeZone("EST"))

while (atleastOneSlaveRunnning) {

 //First thing - set the flag to false.
 atleastOneSlaveRunnning = false; 
 time = new Date().format("HH:mm MM/dd/yy z",TimeZone.getTimeZone("EST"))

 for (aSlave in hudson.model.Hudson.instance.slaves) {

   println "-- Time: " + time;
   println ""
   //Dont do anything if the slave name is "ansible01"
   if ( aSlave.name == "ansible01" ) {
        continue;
   }  
   if ( aSlave.name.indexOf(slaveStartsWith) == 0) {
       println "Active slave: " + aSlave.name; 

       println('\tcomputer.isOnline: ' + aSlave.getComputer().isOnline());
       println('\tcomputer.countBusy: ' + aSlave.getComputer().countBusy());
       println ""
       if ( aSlave.getComputer().isOnline()) {
            aSlave.getComputer().setTemporarilyOffline(true,null);
            println('\tcomputer.isOnline: ' + aSlave.getComputer().isOnline());    
            println ""
       }
       if ( aSlave.getComputer().countBusy() == 0 ) {
            time = new Date().format("HH:mm MM/dd/yy z",TimeZone.getTimeZone("EST"))
            println("-- Shutting down node: " + aSlave.name + " at " + time);
            aSlave.getComputer().doDoDelete(); 
       } else {
            atleastOneSlaveRunnning = true;  
       }
  }
 }
 //Sleep 60 seconds  
 if(atleastOneSlaveRunnning) { 
   println ""
   println "------------------ sleeping 60 seconds -----------------"
   sleep(60*1000); 
   println ""   
 } 
}

现在,我可以创建一个自由样式的jenkins作业,使用脚本脚本在Build操作中,并使用上述脚本以给定名称(作业参数传递到脚本脚本)开始优雅地删除奴隶.

Now, I can create a free-style jenkins job, use Scriptler script in Build action and use the above script to gracefully delete slaves starting with a given name (job parameter getting passed to scriptler script).

如果您足够快地收到以下错误消息,则表示您在 job 中运行或调用了 Scriptler脚本(如上所示). >将作业限制为,使其在非主节点(又称为节点/从属计算机)上运行.脚本程序脚本是 SYSTEM Groovy脚本,即它们必须在 Jenkins master的JVM 上运行才能访问所有Jenkins资源/对其进行调整.要解决以下问题,您可以创建一个作业(限制它在主服务器上运行,即Jenkins主JVM),该作业将仅接受脚本编写器脚本的一个参数,并从第一个作业中调用该作业(作为触发项目/作业并阻止直到作业完成):

If you are fast enough to get the following error message, that means, you ran or called the Scriptler script (as shown above) in a job and restricted that job to run on a non-master aka node/slave machine. Scriptler Scripts are SYSTEM Groovy scripts i.e. they must run on Jenkins master's JVM to access all Jenkins resources/tweak them. To fix the following issue, you can create a job (restrict it to run on master server i.e. Jenkins master JVM) which will just accept one parameter for the scriptler script and call this job from the first job (as Trigger a project/job and block until the job is complete):

21:42:43 Execution of script [disableSlaveNodesWithPattern.groovy] failed - java.lang.NullPointerException: Cannot get property 'slaves' on null objectorg.jenkinsci.plugins.scriptler.util.GroovyScript$ScriptlerExecutionException: java.lang.NullPointerException: Cannot get property 'slaves' on null object
21:42:43    at org.jenkinsci.plugins.scriptler.util.GroovyScript.call(GroovyScript.java:131)
21:42:43    at hudson.remoting.UserRequest.perform(UserRequest.java:118)
21:42:43    at hudson.remoting.UserRequest.perform(UserRequest.java:48)
21:42:43    at hudson.remoting.Request$2.run(Request.java:328)
21:42:43    at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:72)
21:42:43    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
21:42:43    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
21:42:43    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
21:42:43    at java.lang.Thread.run(Thread.java:745)
21:42:43 Caused by: java.lang.NullPointerException: Cannot get property 'slaves' on null object

即 如果您在作业中运行了Scriptler脚本构建步骤(而不是在MASTER Jenkins机器/JVM上运行),则将出现上述错误并解决该错误,请创建作业" disableSlaveNodesStartsWith ",然后限制它在主服务器(更安全的一侧)上运行,并调用Scriptler脚本并将参数传递给作业/脚本.

i.e. If you have Scriptler script build step running in a job (which is not running on a MASTER Jenkins machine/JVM), then the above error will come and to solve it, create a job "disableSlaveNodesStartsWith" and restrict it to run on master (safer side) and calling Scriptler script and pass parameter to the job/script.

现在,从另一个工作中,将此工作称为:

Now, from the other job, call this job:

这篇关于如果具有给定标签的给定节点正在运行另一个作业,则阻止该作业运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆