迭代 Jenkins groovy 地图,有多个集合
Iterating Jenkins groovy map, with multiple sets
我想寻求有关 Jenkins groovy 管道的帮助,从这里复制:
Is it possible to create parallel Jenkins Declarative Pipeline stages in a loop?
我想要几组变量在地图下传递,在并行下几个阶段运行。但是,只有最后一组(地图底部的方括号)为我的地图注册。
当并行阶段 运行s 时,map 迭代成功,但仅使用最后一组(当前 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)] ,在这种情况下,同样只有一个并行阶段是 运行)
我不介意 运行 几个映射定义的不同方法,但其他方法如: 不允许完整的多变量映射(超过键+值对)
任何帮助将不胜感激,谢谢!
我假设您遇到了类似的问题,就像我尝试动态构建并行分支以进行并行执行一样。
有两件事非常重要:
复制循环变量(在你的例子中:it
)并仅在并行分支内使用该副本;如果您不这样做,所有分支(闭包)都将引用完全相同的变量,该变量当然具有相同的值。这是闭包特有的。另见:http://groovy-lang.org/closures.html.
不要使用 collectEntries{}
。坚持使用 java 风格的循环,因为 groovy 循环在大多数情况下无法正常工作。一些 .each{}
构造可能已经工作,但如果有疑问,请切换到 java 循环。另见:
以下精简示例对我有用。我相信你可以根据自己的需要进行调整。
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
}
}
}
}
}
- 如果它仍然不起作用:检查是否有并升级您的
Pipeline: Groovy
插件,因为它们通常会修复很多问题,这些问题通常在 groovy 中有效,但不会在管道中。
您可能需要查看以下相关问题,其中还包含一个最小示例:
我想寻求有关 Jenkins groovy 管道的帮助,从这里复制: Is it possible to create parallel Jenkins Declarative Pipeline stages in a loop?
我想要几组变量在地图下传递,在并行下几个阶段运行。但是,只有最后一组(地图底部的方括号)为我的地图注册。
当并行阶段 运行s 时,map 迭代成功,但仅使用最后一组(当前 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)] ,在这种情况下,同样只有一个并行阶段是 运行)
我不介意 运行 几个映射定义的不同方法,但其他方法如:
任何帮助将不胜感激,谢谢!
我假设您遇到了类似的问题,就像我尝试动态构建并行分支以进行并行执行一样。
有两件事非常重要:
复制循环变量(在你的例子中:
it
)并仅在并行分支内使用该副本;如果您不这样做,所有分支(闭包)都将引用完全相同的变量,该变量当然具有相同的值。这是闭包特有的。另见:http://groovy-lang.org/closures.html.不要使用
collectEntries{}
。坚持使用 java 风格的循环,因为 groovy 循环在大多数情况下无法正常工作。一些.each{}
构造可能已经工作,但如果有疑问,请切换到 java 循环。另见:
以下精简示例对我有用。我相信你可以根据自己的需要进行调整。
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
}
}
}
}
}
- 如果它仍然不起作用:检查是否有并升级您的
Pipeline: Groovy
插件,因为它们通常会修复很多问题,这些问题通常在 groovy 中有效,但不会在管道中。
您可能需要查看以下相关问题,其中还包含一个最小示例: