如果具有给定标签的给定节点正在运行另一个作业,则阻止作业运行

时间:2016-01-20 21:04:51

标签: jenkins block jenkins-plugins restrict slave

在Jenkins,如果作业B使用构建拦截器插件运行,我们可以阻止作业A.

enter image description here

同样地或以某种方式,我想要一份工作,例如: another_dumb_job 不运行 /(等等让它坐下在队列中)如果在任何用户选择的从属设备上运行任何正在进行的作业,直到这些从属设备再次空闲。

例如:我不想运行一个Job(它将删除一堆奴隶,无论是离线/在线 - 使用下游作业还是通过调用一些groovy / scriptler脚本),直到任何一个奴隶(s) )是否有正在运行的/正在进行的工作?

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

1 个答案:

答案 0 :(得分:1)

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

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

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

无论如何,以下脚本将正常删除以给定名称开头的任何Jenkins节点从属(以便您拥有更多控制权)并且它将离线标记(尽快)但删除它只有在给定的从属设备上的任何正在运行的作业完成之后。以为我应该在这里分享。

使用Jenkins Scriptler插件,可以导入/上传/运行此脚本: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动作中使用Scriptler script并使用上面的脚本优雅地删除以给定名称开始的从属(作业参数传递给脚本编写器脚本)。

如果您足够快以获得以下错误消息,则表示您在作业 Scriptler脚本(如上所示) >限制该作业到在非主又名节点/从机上运行。 Scriptler Scripts是 SYSTEM Groovy脚本,即它们必须在 Jenkins master的JVM 上运行才能访问所有Jenkins资源/调整它们。要解决以下问题,您可以创建一个作业(限制它在主服务器上运行即Jenkins master JVM),该作业只接受脚本程序脚本的一个参数并从第一个作业调用此作业( as触发项目/作业并阻止直到作业完成):

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 "并限制它在master(更安全的一面)上运行并调用Scriptler脚本并将参数传递给作业/脚本。

现在,从另一份工作中,打电话给这份工作:

enter image description here

相关问题