如何将并行作业限制为声明式管道中的特定代理

How to restrict parallel jobs to particular agents in Declarative Pipeline

我有 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 的变量并在闭包中使用它,因为你将强制 target 的计算发生在你的 for 循环中,而不是闭包运行的时间。 看起来像这样:

def cleanWSTasks(targets){
    tasks = [:]
    for(target in targets){
        def thisTarget = target
        tasks[thisTarget] = {
            node(thisTarget){
                script {
                    cleanWs()
                }
            }
        }
    }
    return tasks
}