Jenkins声明性管道工作 - 如何在奴隶之间分配并行步骤?

时间:2018-06-12 07:07:42

标签: jenkins-pipeline jenkins-declarative-pipeline

我正在运行一个Declarative Pipeline,其中一个步骤运行(非常长)的集成测试。我正在尝试将我的测试分成几个较小的测试并在几个节点上并行运行。我有8个这样的小测试,我有8个节点(在标签下),所以我想让每个测试在一个单独的节点上运行。不幸的是,两个测试 - 当在同一节点上运行时 - 相互干扰,因此都失败了。

我需要能够先获取可用节点列表,然后并行运行较小的测试,每个节点之一;如果没有足够的节点,其中一个较小的测试需要等到节点完成。

然而,发生的情况是,当按标签要求节点时,两个较小的测试通常会获得相同的节点,因此两者都失败了。节点配置为最多运行3个执行程序,否则整个系统将停止运行,因此我无法更改。

我对较小测试的当前配置是:

    stage('Integration Tests') {
        when {
            expression {params.TESTS_INTEGRATION}
        }
        parallel {
            stage('Test1') {
                agent {node {label 'my_builder'}}
                steps {
                    script {
                        def shell_script = getShellScript("Test1")
                        sh "${shell_script}"
                    }
                }
            }

我可以从这样的标签中获取可用的从属列表:

pipeline {
stages {
    // ... other stages here ...
    stage('NodeList'){
        steps {
            script {
                def nodes =  getNodeNames('my_builder')
                free_nodes = []
                for (def element = 0; element < nodes.size(); element++) {
                    usenode = nodes[element]
                    try { 
                      // Give it 5 seconds to run the nodetest function
                        timeout(time: 5, unit: 'SECONDS') { 
                            node(usenode) { 
                                nodetest() 
                                free_nodes += usenode
                            } 
                        }
                    } catch(err) { 

                    }
                }
                println free_nodes
            }
        }
    }

哪里

def getNodeNames (String label) {
    def lgroup = Jenkins.instance.getLabel(label)
    def nodes = lgroup.getNodes()
    def result = []
    if (nodes.size() > 0) {
        for (def element = 0; element < nodes.size(); element++) {
            result += nodes[element].getNodeName()
        }
    }
    return result
}

def nodetest() { 
  sh('echo alive on \$(hostname)') 
}

如何以编程方式从free_nodes数组中获取节点名称并指示阶段使用它?

1 个答案:

答案 0 :(得分:1)

我已经明白了,所以对于未来的人们来说:

事实证明,您可以在Declarative Pipeline中运行Scripted Pipeline,如下所示:

Actual: 8.123456e+27
Expected: 8123456342700123300640123456

脚本可以做任何事情,包括......运行管道!

这是脚本:

pipeline {
    stage('SomeStage') {
        steps {
            script {
                // ... your scripted pipeline here
            }
        }
    }