如果给定节点具有给定标签 is/are 运行 另一个作业,则阻止来自 运行 的作业

Block a job from running if given node(s) with a given label(s) is/are running another job(s)

在 Jenkins 中,如果作业 B 正在 运行ning,我们可以使用 Build blocker 插件.

阻止作业 A

类似地或以某种方式,我想要一份工作,例如:another_dumb_jobNOT 运行 /(等待并让它排队)如果 any 正在进行的作业 运行ning 在 任何用户选择的奴隶直到这些奴隶再次空闲。

例如:我不想 运行 一个作业(这将删除一堆奴隶 offline/online -- 使用下游作业或通过调用一些 groovy/scriptler 脚本) 直到这些奴隶中的任何一个有 active/in-progress 工作 运行ning 在他们身上?

最终目标是优雅地删除 Jenkins 节点从站,即首先将 node/slave 标记为离线,然后是任何现有作业(从站上的 运行ning 已完成),然后删除从站.

要删除所有离线节点,请调整下面的脚本并 运行 仅在 isOffline() 为真或 isOnline() 为假的从站上执行 doDelete()。如果要删除所有节点(小心),请不要使用以下 if 语句:

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

我也在忽略 一个奴隶(如果你想总是忽略一个奴隶被删除)。可以增强使用要忽略的从​​属列表。

无论如何,以下脚本将优雅地删除任何以给定名称开头的 Jenkins 节点从属(以便您拥有更多控制权)并且它会标记为离线(尽快)但仅在给定从属 is/are 上的任何 运行ning 作业完成后才删除它。觉得我应该在这里分享。

使用 Jenkins Scriptler 插件,可以 import/upload/run 这个脚本: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 ""   
 } 
}

现在,我可以创建一个 free-style jenkins 作业,在构建操作中使用 Scriptler script 并使用上面的脚本优雅地删除以给定名称开头的从属(作业参数传递给脚本程序脚本).

如果你足够快得到以下错误信息,这意味着,你运行或调用Scriptler脚本(如上所示) 35=]工作和限制工作运行在non-master又名node/slave 机。 Scriptler 脚本是 SYSTEM Groovy 脚本 即它们必须 运行 在 Jenkins master 的 JVM 上才能访问所有 J​​enkins resources/tweak 他们。要解决以下问题,您可以创建一个作业(将其限制为 运行 在主服务器 上,即 Jenkins 主 JVM),它只接受脚本程序脚本的一个参数并调用这个作业来自第一个作业(作为触发器 a project/job 并阻塞直到作业完成):

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.run(Request.java:328)
21:42:43    at hudson.remoting.InterceptingExecutorService.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 脚本构建步骤 运行ning(在 MASTER Jenkins machine/JVM 上不是 运行ning),那么上面的错误就会出现并解决它,创建一个作业“disableSlaveNodesStartsWith”并将其限制为 运行 在主机上(更安全的一面)并调用 Scriptler 脚本并将参数传递给 job/script.

现在,从其他作业调用此作业: