【问题标题】:Reusing workspace across multiple nodes in parallel stages在并行阶段跨多个节点重用工作空间
【发布时间】:2021-07-26 13:07:27
【问题描述】:

我在我的 Jenkins 管道脚本中设置了并行阶段,这些阶段在单独的节点(AWS EC2 实例)上执行测试

例如

stage('E2E-PR') {
    parallel {
        stage('Cypress Tests 1') {
            agent { label 'aws_slave_cypress' }
            steps {
                runE2eTests()
            }
        }
        stage('Cypress Tests 2') {
            agent { label 'aws_slave_cypress' }
            steps {
                runE2eTests()
            }
        }
    }
}

我想重新使用从管道开始时使用的父节点生成的签出 repo\生成的工作空间,而不是每个并行阶段都签出它自己的副本。

我遇到了一种使用顺序阶段的方法,并在阶段内嵌套阶段以跨多个阶段共享工作区,我尝试如下

parallel {
    stage('Cypress Tests') {
        agent { label 'aws_slave_cypress' }
        stages {
            stage('Cypress 1') {
                steps {
                    runE2eTests()
                }
            }
            stage('Cypress 2') {
                steps {
                    runE2eTests()
                }
            }
        }
    }
}

但我可以从我的 Jenkins 构建输出中看到,只有一个 aws 实例被启动并用于我的两个嵌套阶段,这并没有给我带来并行性的好处。

我也遇到过 stash\unstash 命令,但我读过这些命令应该用于小文件而不是大目录\整个存储库?

让我在多个节点上使用相同最初生成的工作区的并行阶段的正确方法是什么?这可能吗?

谢谢

【问题讨论】:

  • 您能否提供更多信息,说明您为什么要这样做? (浅浅地)克隆一个 git repo 与存储和取消存储文件没有什么不同。
  • 所以用于测试的从代理,只需要能够引用一些测试文件,所以我可以使用 stash\unstash 的方法考虑一下。

标签: jenkins jenkins-pipeline


【解决方案1】:

我可以分享一些关于我们公司类似情况的信息: 我们有一个用于 UI 测试的自动化回归套件,需要在多台不同的机器(Win32、Win64、Mac 等)上执行。套件配置由包含所有相关环境参数和 URL 的配置文件控制。
Job 允许用户选择将要执行的套件(和 git 分支),选择将在其上执行套件的标签(代理),并选择这些套件将使用的环境配置。

流程是怎样的:

  1. 根据用户输入生成配置文件并保存(存储)它。
  2. 并行处理所有给定标签:使用浅克隆克隆套件存储库 -> 复制配置文件 (unsatsh) -> 运行测试 -> 保存(存储)测试的输出。
  3. 收集所有测试的输出(unstash),将它们组合成一个报告,发布报告并通知用户。

管道本身(简化)如下所示:

pipeline {
    agent any
    parameters {
         extendedChoice(name: 'Agents', ...)
    }
    stages {
        stage('Create Config') {
            steps {
                // create the config file called config.yaml
                ...
                stash name: 'config' , includes: 'config.yaml'
            }
        }
        stage('Run Tests') {
            steps {
                script {
                    parallel params.Agents.collectEntries { agent ->
                        ["Running on ${agent}": {
                            stage(agent) {
                                node(agent) {
                                    println "Executing regression tests on ${agent}"
                                    stage('Clone Tests') {
                                        // Git - shallow clone the automation tests
                                    }
                                    stage('Update Config') {
                                        unstash 'config'
                                    }
                                    stage('Run Suite') {
                                        catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
                                            // Run the tests
                                        }
                                    }
                                    stage('Stash Results'){
                                        stash name: agent , includes: 'results.json'
                                    }
                                }
                            }
                        }]
                    }
                }
            }
        }
        stage('Combine and Publish Report') {
            steps {
                // Unstash all results from each agent to the same folder
                params.Agents.each { agent ->
                    dir(agent){
                        unstash agent
                    }
                }
                // Run command to combine the results and generated the HTML report
                // Use publishHTML to publish the HTML report to Jenkins
            }
        }
    }
    post{
        // Notify users
    }
}

如您所见,用于处理相对较小的文件,如配置文件和测试结果文件(小于 1M)stash 和 unstash 快​​速且非常易于使用并提供极大的灵活性,但是当您将它们用于更大的文件,然后它们开始使系统过载。
关于测试本身,最终您必须将文件复制到不同代理中的每个工作区,如果您的测试未打包,则从存储库中浅层克隆它们可能是最有效且易于使用的方法。

如果您的测试可以轻松打包,例如 python 包,那么您可以创建一个不同的 CI 管道,将它们归档为每个代码更改的包,然后您的自动化管道可以将它们与 pip 或所以并避免克隆存储库的需要。
当您在容器中运行测试时也是如此,因为您可以创建一个 CI 来准备一个已包含测试的映像,然后只需在管道中使用该映像,而无需再次克隆它。
如果您的 Git 服务器有点慢,您可以随时使用 zip 或类似的存档器将测试打包到 CI 中,将它们上传到 S3(使用 aws-steps)或等效的并在自动化管道执行期间下载它们 - 但在大多数情况下,这不会提供任何性能优势。

【讨论】:

    【解决方案2】:

    例如,我想您需要在 post 步骤将生成的文件发送到 s3。在管道的第一步下载这些文件。

    想想存储,你需要在 jenkins 代理之间共享。

    【讨论】:

      猜你喜欢
      • 2020-02-17
      • 2023-02-02
      • 2018-05-21
      • 1970-01-01
      • 1970-01-01
      • 2023-01-31
      • 1970-01-01
      • 2011-01-30
      • 1970-01-01
      相关资源
      最近更新 更多