代码之家  ›  专栏  ›  技术社区  ›  MaratC

Jenkins声明性管道作业-如何在从属服务器之间分配并行步骤?

  •  2
  • MaratC  · 技术社区  · 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 回复  |  直到 7 年前
        1
  •  1
  •   MaratC    8 年前

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

    事实证明,您可以在声明性管道中运行脚本化管道,如下所示:

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

    剧本可以做任何事,包括。。。运行管道!

    script {
        def builders = [:]
        def nodes =  getNodeNames('my_label')
        // let's find the free nodes
        String[] 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) { 
                // do nothing
            }
        }
        println free_nodes
    
        def tests = params.TESTS_LIST.split(',')
    
        for(int i = 0; i < tests.length; i++) {
            // select the test to run
            def the_test = tests[i]
            // select on which node to run it
            def the_node = free_nodes[i % free_nodes.length]
    
            // here comes the scripted pipeline: prepare steps
            builders[the_test] = {
                // run on the selected node
                node(the_node) {
                    // lock the resource with the name of the node so two tests can't run there at the same time
                    lock(the_node) {
                        // name the stage
                        stage(the_test) {
                            println "Running on ${NODE_NAME}"
                            def shell_script = getShellScript("${the_test}")
                            sh "${shell_script}"
                        }
                    }
                }
            }
        }
        // run the steps in parallel
        parallel builders
    }
    
    推荐文章