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

仅使用列表中的最后一项使用声明性管道执行并行阶段

  •  1
  • thclpr  · 技术社区  · 8 年前

    我不确定我在这里做错了什么,因为目前当我尝试在列表上迭代时,阶段的创建似乎很好,但在执行shellscript时,使用的值始终是列表的最后一项:

    工作管道:

    pipeline {
        agent any
        stages {
            stage('set servers') {
                steps {
                    script {
                        my_list = ['server1','server-2','server-3']
                    }
                }
            }
            stage('Execute then') {
                parallel {
                    stage('shouter') {
                        steps {            
                            script {
                                shouter = [:]
                                script {
                                    for(i in my_list) {
                                        shouter["${i}"] = {
                                            echo "standupandshout.sh ${i}"
                                        }
                                    }
                                }                            
                                parallel shouter
                            }
                        }
                    }
                }
            }
        }
    }
    

    输出:

    enter image description here

    控制台输出:

    Replayed #4
    Running in Durability level: MAX_SURVIVABILITY
    [Pipeline] node
    Running on Jenkins in /var/lib/jenkins/workspace/test
    [Pipeline] {
    [Pipeline] stage
    [Pipeline] { (set servers)
    [Pipeline] script
    [Pipeline] {
    [Pipeline] }
    [Pipeline] // script
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] stage
    [Pipeline] { (Execute then)
    [Pipeline] parallel
    [Pipeline] [shouter] { (Branch: shouter)
    [Pipeline] [shouter] stage
    [Pipeline] [shouter] { (shouter)
    [Pipeline] [shouter] script
    [Pipeline] [shouter] {
    [Pipeline] [shouter] script
    [Pipeline] [shouter] {
    [Pipeline] [shouter] }
    [Pipeline] [shouter] // script
    [Pipeline] [shouter] parallel
    [Pipeline] [server1] { (Branch: server1)
    [Pipeline] [server-2] { (Branch: server-2)
    [Pipeline] [server-3] { (Branch: server-3)
    [Pipeline] [server1] echo
    [server1] standupandshout.sh server-3
    [Pipeline] [server1] }
    [Pipeline] [server-2] echo
    [server-2] standupandshout.sh server-3
    [Pipeline] [server-2] }
    [Pipeline] [server-3] echo
    [server-3] standupandshout.sh server-3
    [Pipeline] [server-3] }
    [Pipeline] [shouter] // parallel
    [Pipeline] [shouter] }
    [Pipeline] [shouter] // script
    [Pipeline] [shouter] }
    [Pipeline] [shouter] // stage
    [Pipeline] [shouter] }
    [Pipeline] // parallel
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] }
    [Pipeline] // node
    [Pipeline] End of Pipeline
    Finished: SUCCESS
    

    所需输出:

    [Pipeline] [server1] echo
    [server1] standupandshout.sh server-1
    [Pipeline] [server1] }
    [Pipeline] [server-2] echo
    [server-2] standupandshout.sh server-2
    [Pipeline] [server-2] }
    [Pipeline] [server-3] echo
    [server-3] standupandshout.sh server-3
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   thclpr    8 年前

    这是由于groovy闭包以及它们所包含的代码得到计算时造成的。 http://blog.freeside.co/2013/03/29/groovy-gotcha-for-loops-and-closure-scope/

    当闭包运行时,绑定到变量i的值是它在循环的最终迭代上的值,而不是创建闭包的迭代上的值。闭包的作用域引用了i,在执行任何闭包时,i是5。

    循环体的局部变量的行为与此不同,显然是因为每个闭包范围都包含对不同变量的引用

    这就是为什么你的舞台名称是可以的,但你的价值不是。

    解决方案是什么?我们应该一直使用。每个而不是一个for循环?嗯,我有点喜欢循环,在许多情况下,可能会有内存利用率的差异(不要认为这意味着循环“更好”或“更高效”)。

    如果您只需在 封闭体一切正常

    def fns = []
    for (i in (1..5)) {
        def myi = i
        def isq = i * i
        fns << {->
            println "$myi squared is $isq"
        }
    }
    fns.each { it() }
    

    所以这应该是可行的:

    script {
      shouter = [:]
      for(i in my_list) {
        def val = i
        shouter["${i}"] = {
          echo "standupandshout.sh ${val}"
        }
      }
      parallel shouter
    }