我有3个节点:A,B,C
在每个节点上,我都设置了一个具有自己的根目录的 Jenkins 代理它们都有以下标签:test && database && mysql
我想在所有 3 个节点上并行运行作业,以清理它们上的工作区文件夹为了实现这一点,我编写了这个 Jenkins 脚本
def labels = "test && mysql && database"
def getNodesName(labels){
def targets = []
def nodes = Jenkins.instance.getLabel(labels).getNodes()
for(node in nodes){
targets.add(node.getNodeName())
}
return targets
}
def nodes = getNodesName(labels)
def cleanWSTasks(targets){
tasks = [:]
for(target in targets){
tasks[target] = {
node(target){
script {
cleanWs()
}
}
}
}
return tasks
}
pipeline{
agent none
stages{
stage ('Clean Workspace'){
steps{
script{
parallel cleanWSTasks(nodes)
}
}
}
}
}
所以我想在cleanWsTasks函数中使用node(target(,我已经告诉Jenkins只在我想要的特定目标节点上限制任务的执行。这样所有 3 个节点将同时开始清理自己的工作区。
但是,我看到的是只有 1 个节点拿起了清理工作区的任务,并且它执行了 3 次。
例如,它显示:
在节点 A 上运行...
清理工作区..
在节点 A 上运行...
清理工作区..
在节点 A 上运行...
清理工作区..
我在代码中做错了什么?请帮忙。
步骤工作正常,您遇到的问题与您如何定义任务有关。在 for 循环中,您将分配此闭包:
{
node(target){
script {
cleanWs()
}
}
到tasks[target]
.
评估闭包中的代码。因此,即使您在 for 循环中分配node(target)
,target
的值也不会在 parallel tasks
运行之前得到评估,也就是执行闭包时。这发生在 for 循环完成运行之后,因此 target
的值是节点列表中最后一个节点的名称。
一个简单的解决方法是在 for 循环中创建一个等于 target 的变量,并在闭包中使用它,因为您将强制在 for 循环内进行target
评估,而不是在闭包运行时进行。那看起来像这样:
def cleanWSTasks(targets){
tasks = [:]
for(target in targets){
def thisTarget = target
tasks[thisTarget] = {
node(thisTarget){
script {
cleanWs()
}
}
}
}
return tasks
}