如果给定节点具有给定标签 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_job到NOT 运行 /(等待并让它排队)如果 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 上才能访问所有 Jenkins 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.
现在,从其他作业调用此作业:
在 Jenkins 中,如果作业 B 正在 运行ning,我们可以使用 Build blocker 插件.
阻止作业 A类似地或以某种方式,我想要一份工作,例如:another_dumb_job到NOT 运行 /(等待并让它排队)如果 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 上才能访问所有 Jenkins 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.
现在,从其他作业调用此作业: