首页 > 解决方案 > 如何使用 parallel[:] 步骤并行运行具有不同参数的相同作业

问题描述

我有一个需要触发“测试”作业的管道脚本。主要参数(字符串)是 SETUP_DESCRIPTION,我从我正在创建的 json 文件中使用它。每个服务器可以有不同数量的输出取决于服务器资源(有些有 2 个设置,有些有 3 个)。

代码如下所示:

#!/usr/bin/env groovy
import hudson.model.Result
import hudson.model.Run
import groovy.json.JsonSlurperClassic
import jenkins.model.CauseOfInterruption.UserInterruption
import org.jenkinsci.plugins.workflow.steps.FlowInterruptedException

def projectProperties = [
buildDiscarder(
logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '14', numToKeepStr: '')
),
parameters([
string(defaultValue: '', description: '', name: 'SERVER_NAME'),
string(defaultValue: 'Ubuntu_17.10_x86_64_kvm', description: '', name: 'KVM_TEMPLATE'),
string(defaultValue: 'test@test.com'', description: 'mailing list', name: 'SW_MAIL'),
choice(choices: ['no', 'eth', 'ib'], description: '', name: 'SIMX_SERVER'),
choice(choices: ['cib', 'cx3pro', 'cx4', 'cx4lx', 'cx5', 'cx6'], description: '', name: 'SIMX_BOARD'),
choice(choices: ['os_install', 'provision', 'add_jks_slave', 'add_to_noga', 'tests'], description: '', name: 'RUN_STAGE')
]),
[$class: 'RebuildSettings', autoRebuild: false, rebuildDisabled: false],
[$class: 'ThrottleJobProperty',
categories: [],
limitOneJobWithMatchingParams: true,
maxConcurrentPerNode: 5,
maxConcurrentTotal: 5,
paramsToUseForLimit: '',
throttleEnabled: true,
throttleOption: 'project'
],
]
properties(projectProperties)

def build_sanity (SETUP_DESCRIPTION) {

                    IMAGE = "linux/upstream_devel-x86_64"
                    CLOUD_IP = "dev-l-vrt-storage"
                    TAGS = "test_new_setup"

                if ("$SETUP_DESCRIPTION" != "b2b x86-64 cib cloud_test") {
                    DATA_BASE = "b2b_eth_drivertest_mini_reg_db.json"
                    LINK_LAYER =  "eth"
                }
                else {
                    DATA_BASE = "b2b_ib_drivertest_mini_reg_db.json"
                    LINK_LAYER =  "ib"
                }

            build job: 'SANITY_TESTS/new_cloud_setup_GENERAL_SANITY_CHECK2', propagate: false
            parameters:
            [string(name: 'SETUP_DESCRIPTION', value: "${SETUP_DESCRIPTION}"),
            string(name: 'DATA_BASE', value: "${DATA_BASE}"),
            string(name: 'LINK_LAYER', value: "${LINK_LAYER}"),
            string(name: 'IMAGE', value: "${IMAGE}"),
            string(name: 'CLOUD_IP', value: "${CLOUD_IP}"),
            string(name: 'TAGS', value: "${TAGS}")]
}
try {
ansiColor('xterm') {
timestamps {
node('cloud-slave1'){

            stage('Test Setups') {
               if (params.RUN_STAGE == 'os_install' || params.RUN_STAGE == 'provision' || params.RUN_STAGE == 'add_jks_slave' || params.RUN_STAGE == 'add_to_noga' || params.RUN_STAGE == 'tests') {

                 def stepsForParrallel = [:]
                 def NOGA_DESCRIPTION_LIST = sh (
                    script: "curl -X GET 'https://noga.mellanox.com/app/server/php/rest_api/?api_cmd=get_resources&pattern=${params.SERVER_NAME}&resource_type=Setup&group_name=Yaron&sub_group=Cloud'",
                    returnStdout: true
                    ).trim()

                @NonCPS
                def JSON = new groovy.json.JsonSlurperClassic().parseText(NOGA_DESCRIPTION_LIST)
                def DESCRIPTION_LIST = JSON.data.each{
                    SETUP_NAME = "${it.NAME}"
                    SETUP_DESCRIPTION = "${it.DESCRIPTION}"
                    println "${it.DESCRIPTION}" // PRINT ALL DECRIPTIONS INSIDE DATA

                    stepsForParrallel["${it.NAME}"] = {
                    build_sanity(SETUP_DESCRIPTION)
                    }

              }
              parallel stepsForParrallel
             }
            }
        }
    }
}
}catch (exc) {
def recipient = "${SW_MAIL}"
def subject = "${env.JOB_NAME} (${env.BUILD_NUMBER}) Failed"
def body = """
It appears that build ${env.BUILD_NUMBER} is failing, please check HW or network stability:
${env.BUILD_URL}
"""
mail subject: subject,
to: recipient,
replyTo: recipient,
from: 'cloud-host-provision@mellanox.com',
body: body

throw exc

1)当我像上面的代码一样运行它时build_sanity调用一次并执行(而不是预期的3次)。

2)当我build_sanity在测试阶段获取函数内容并在 ech 循环内运行它时,它按预期运行 3 次,但没有按预期选择不同的参数。

标签: jenkinsgroovyparallel-processing

解决方案


所以我设法弄清楚了。

1)我有 println 一些参数,看到我的函数没有收到变量,所以我改变了构建作业:部分并解决了这个问题。

2)我在舞台部分也有问题。我将“并行运行”放在每个循环中,使其运行多次。所以我把它放下一个 } 并解决了循环问题

如果将来有人遇到此类问题,这是功能代码+阶段

def build_sanity (SETUP_DESCRIPTION) {

              if ("$SETUP_DESCRIPTION" != "b2b x86-64 cib cloud_test") {
                  DATA_BASE = "b2b_eth_drivertest_mini_reg_db.json"
                  LINK_LAYER =  "eth"
              }
              else {
                  DATA_BASE = "b2b_ib_drivertest_mini_reg_db.json"
                  LINK_LAYER =  "ib"
              }
                  IMAGE = "linux/upstream_devel-x86_64"
                  CLOUD_IP = "dev-l-vrt-storage"
                  TAGS = "test_new_setup"

              build job: 'SANITY_TESTS/new_cloud_setup_GENERAL_SANITY_CHECK',
              parameters: [
              string(name: 'SETUP_DESCRIPTION', value: "${SETUP_DESCRIPTION}"),
              string(name: 'DATA_BASE', value: "${DATA_BASE}"),
              string(name: 'LINK_LAYER', value: "${LINK_LAYER}"),
              string(name: 'IMAGE', value: "${IMAGE}"),
              string(name: 'TAGS', value: "${TAGS}"),
              ]

}

阶段('测试设置'){ if (params.RUN_STAGE == 'os_install' || params.RUN_STAGE == 'provision' || params.RUN_STAGE == 'add_jks_slave' || params.RUN_STAGE == 'add_to_noga' || params.RUN_STAGE == '测试') {

                 def stepsForParrallel = [:]
                 def NOGA_DESCRIPTION_LIST = sh (
                    script: "curl -X GET 'https://noga.mellanox.com/app/server/php/rest_api/?api_cmd=get_resources&pattern=${params.SERVER_NAME}&resource_type=Setup&group_name=Yaron&sub_group=Cloud'",
                    returnStdout: true
                    ).trim()

                @NonCPS
                def JSON = new groovy.json.JsonSlurperClassic().parseText(NOGA_DESCRIPTION_LIST)
                def DESCRIPTION_LIST = JSON.data.each{
                def SETUP_NAME = "${it.NAME}"

                    stepsForParrallel["${it.NAME}"] = {
                    build_sanity("${it.DESCRIPTION}")
               }
              }
             parallel stepsForParrallel
             }
            } 

推荐阅读