【问题标题】:Jenkins pipeline (parallel && dynamically)?詹金斯管道(并行&&动态)?
【发布时间】:2018-01-10 07:02:39
【问题描述】:

问题

我有与 Jenkins 2.89.2 一起使用的简单并行管道(参见代码)。此外,我使用参数,现在希望能够通过在作业执行之前提供参数来自动增加/减少 deployVM A..Z 阶段的数量。

如何通过提供参数来动态构建管道?

目前研究过:

代码

我想要的伪代码——动态生成:

pipeline {

    agent any

    parameters {
        string(name: 'countTotal', defaultValue: '3')
    }

    stages {

       stage('deployVM') {

        def list = [:]
        for(int i = 0; i < countTotal.toInteger; i++) {
            list += stage("deployVM ${i}") {
                steps {
                    script {
                        sh "echo p1; sleep 12s; echo phase${i}"
                    }

                }
            }
        }

        failFast true
        parallel list
       }

   }

}

到目前为止我的代码 - 并行执行但是静态的:

pipeline {

    agent any
    stages {

       stage('deployVM') {
        failFast true
        parallel {
            stage('deployVM A') {
                steps {
                    script {
                        sh "echo p1; sleep 12s; echo phase1"
                    }

                }
            }
            stage('deployVM B') {
                steps {
                    script {
                        sh "echo p1; sleep 20s; echo phase2"
                    }

                }
            }
        }
       }

   }

}

【问题讨论】:

  • 我建议使用scripted pipeline,这样更灵活。
  • 我阅读了这篇文章,但不知道如何在此处应用它。你能举个例子吗?文档真的很少。

标签: jenkins jenkins-pipeline


【解决方案1】:

虽然问题假设使用声明性管道,但我建议使用scripted pipeline,因为它更灵活。
你的任务可以这样完成

properties([
    parameters([
        string(name: 'countTotal', defaultValue: '3')
    ])
])

def stages = [failFast: true]
for (int i = 0; i < params.countTotal.toInteger(); i++) {
    def vmNumber = i //alias the loop variable to refer it in the closure
    stages["deployVM ${vmNumber}"] = {
        stage("deployVM ${vmNumber}") {
            sh "echo p1; sleep 12s; echo phase${vmNumber}"
        }
    }
}

node() {
    parallel stages
}

还可以查看snippet generator,它允许您生成一些脚本化的管道代码。

【讨论】:

  • 你能帮忙看看我的问题吗(因为下面的答案导致一个班轮格式不好),提前谢谢:)
  • 这是一个很好的技巧。它帮助了我非常感谢。
  • 天哪!我在关闭中挣扎了好几个小时。
【解决方案2】:

@Vitalii

我写了类似的代码片段,但是不幸的是,所有三个元素都被循环显示最后一个,不确定它是否与 groovy / jenkinsfile 本身有关,某些 clouse / 参考因错误使用而中断

我的目的是将任务分发到特定的工作节点

node_candicates = ["worker-1", "worder-2", "worker-3"]

def jobs = [:]
for (node_name in node_candidates){
    jobs["run on $node_name"] = {             // good
        stage("run on $node_name"){           // all show the third 
            node(node_name){                  // all show the third 
                print "on $node_name"
                sh "hostname"
            }
        }
    }
}    
parallel jobs

如果我扩展/解释循环,而不是循环遍历它,那就完全没问题了,就像

parallel worker_1: {
    stage("worker_1"){
        node("worker_1"){
            sh """hostname ; pwd """
            print "on worker_1"
        }
    }
},  worker_2: {
    stage("worker_2"){
        node("worker_2"){
            sh """hostname ; pwd """
            print "on worker_2"
        }
    }
},  worker_3: {
    stage("worker_3"){
        node("worker_3"){
            sh """hostname ; pwd """
            print "on worker_3"
        }
    }
}

【讨论】:

  • 发生这种情况是因为您创建的所有闭包都绑定到同一个变量node_name。这就是为什么在我的原始答案中创建了 vmNumber 额外变量的原因。你可以在这里阅读更多内容blog.freeside.co/2013/03/29/…
  • 您介意将此作为单独的问题发布吗?将您的问题发布到答案部分会违反 SO 规则。
  • @viyalii,这正是我担心的,所以在这样的功能/ml语言中,变量实际上并不是变量,感谢您提供的信息和链接,我应该能够完成我的脚本,我猜不费心创建一个单独的线程?以防万一其他人有类似问题可以看到这个,这可以关闭?
  • 当然,如果您认为这种方式组织得更好并给您链接,我会删除它并创建另一个问题?
【解决方案3】:

使用声明式管道也可以实现这一点。

关注我的回答HERE

在上面的链接答案中,我使用了Var.collectEntries,但也可以使用map

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-09
    • 2018-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 2017-05-24
    相关资源
    最近更新 更多