【问题标题】:Iterating Jenkins groovy map, with multiple sets迭代 Jenkins groovy 地图,有多个集合
【发布时间】:2018-08-06 14:49:36
【问题描述】:

我想就 Jenkins groovy 管道寻求帮助,从这里复制: Is it possible to create parallel Jenkins Declarative Pipeline stages in a loop?

我希望 几个 组变量在地图下传递,用于并行运行下的 几个 阶段。但是,只有最后一组(地图底部的方括号)会为我的地图注册。

并行阶段运行时,映射成功迭代,但仅使用最后一组(当前为install_Stage(it)),忽略其他组。这意味着我得到了一个并行显示四个"stage: install ${product}" 阶段的管道,仅此而已。根据下面的代码,我想获得四个阶段(网络设置、恢复和安装)的三个并行:

#!groovy

@Library('ci_builds')

def products = ["A", "B", "C", "D"]

def parallelStagesMap = products.collectEntries {

    switch (it) {
        case "A":
            static_ip_address = "10.100.100.6"; static_vm_name = "install-vm1"; version = "14.1.60"
            break
        case "B":
            static_ip_address = "10.100.100.7"; static_vm_name = "install-vm2"; version = "15.1"
            break
        case "C":
            static_ip_address = "10.100.100.8"; static_vm_name = "install-vm3"; version = "15.1"
            break
        case "D":
            static_ip_address = "10.100.100.9"; static_vm_name = "install-vm4"; version = "15.2"
            break
        default:
            static_ip_address = "The product name is not on the switch list - please enter an ip address"
            version = "The product name is not on the switch list - please enter a version"
            break
    }

    ["${it}" : network_reg(it)]

    ["${it}" : revert_to_snapshot_Stage(it)]

    ["${it}" : install_Stage(it)]

}

def network_reg(product) {
return {
    stage("stage: setup network for ${product}") {
        echo "setting network on ${static_vm_name} with ${static_ip_address}."
        sh script: "sleep 15"
    }
}
}

def revert_to_snapshot_Stage(product) {
return {
    stage("stage: revert ${product}") {
        echo "reverting ${static_vm_name} for ${product} on ${static_ip_address}."
        sh script: "sleep 15"
    }
}
}


def install_Stage(product) {
return {
    stage("stage: install ${product}") {
        echo "installing ${product} on ${static_ip_address}."
        sh script: "sleep 15"
    }
}
}

pipeline {
agent any

stages {
    stage('non-parallel env check') {
        steps {
            echo 'This stage will be executed first.'
        }
    }

    stage('parallel stage') {
        steps {
            script {
                parallel parallelStagesMap
            }
        }
    }
}
}

network_reg 和 revert_to_snapshot_Stage 不会运行(除非我将它们放在最后一组而不是 ["${it}" : install_Stage(it)] ,在这种情况下,只有一个并行阶段是运行)

我不介意使用不同的方法来运行多个映射定义,但其他诸如:How to define and iterate over map in Jenkinsfile 不允许完整的多变量映射(超过键+值对)

任何帮助将不胜感激,谢谢!

【问题讨论】:

    标签: jenkins groovy jenkins-pipeline jenkins-groovy


    【解决方案1】:

    我假设您有类似的问题,例如我曾尝试动态构建并行分支以进行并行执行。

    有两件事非常重要:

    1. 制作循环变量的副本(在您的情况下:it)并仅在并行分支内使用该副本;如果您不是所有分支(闭包)都将引用相同的变量,当然该变量将具有相同的值。这尤其适用于闭包。另见:http://groovy-lang.org/closures.html

    2. 不要使用collectEntries{}。坚持使用 java 风格的循环,因为 groovy 循环在大多数情况下都不能正常工作。一些.each{} 构造可能已经工作,但如果有疑问,请切换到java 循环。另见:Impossibility to iterate over a Map using Groovy within Jenkins Pipeline

    以下精简示例对我有用。我相信您可以根据自己的需要进行调整。

    def products = ["A", "B", "C", "D"]
    def parallelStagesMap = [:]
    
    // use java-style loop
    for (def product: products) {
        // make a copy to ensure that each closure will get it's own variable
        def copyOfProduct = product
        parallelStagesMap[product] = {echo "install_Stage($copyOfProduct)"}
    }
    
    echo parallelStagesMap.toString()
    
    pipeline {
    agent any
        stages {
            stage('parallel stage') {
                steps {
                    script {
                        parallel parallelStagesMap
                    }
                }
            }
        }
    }
    
    1. 如果它仍然不起作用:检查是否存在并升级您的 Pipeline: Groovy 插件,因为它们通常会解决很多问题,这些问题通常在 groovy 中有效,但不会在管道中。

    您可能需要检查以下相关问题,其中还包含一个最小示例: Currying groovy CPS closure for parallel execution

    【讨论】:

    • 在 Jenkins 版本中不起作用。 2.113 和管道:Groovy 2.45(2018 年 2 月 14 日):-(而且我无法轻松升级(其他一些人使用的暂存环境)。这对您在另一个版本上有用吗?其他框架?
    • 尝试在我的本地 Jenkins 上执行此操作我不得不说我不再确定您想要实现什么。正如现在所写的那样,collectEntries 将始终返回["${it}" : install_Stage(it)]。其他人在什么情况下会被退回?
    • 在最终确定您的代码 sn-p 中存在多个问题后更新了我的答案。我还删除了 switch 语句和其他方法 - 我很确定您可以在需要的地方添加它们。
    • “groovy 循环在大多数情况下都无法正常工作” - 好吧,没有什么新鲜事,叹息。感谢一百万的 java 循环,就像一个魅力
    猜你喜欢
    • 2023-03-28
    • 2015-08-23
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 2017-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多