1

使用 kubernetes-plugin Parallelise 声明式 Jenkinsfile 当每个阶段使用相同的容器时,如何并行运行阶段?(例如:sonar_qube 分析和单元测试都在 Maven 容器上运行。

我在 Jenkinsfile 中尝试了以下内容:

def label = "my-build-${UUID.randomUUID().toString()}"

podTemplate(label: label, containers: [
  containerTemplate(name: 'maven', image: 'maven:3.5.3-jdk-8-alpine', command: 'cat', ttyEnabled: true),
  containerTemplate(name: 'maven2', image: 'maven:3.5.3-jdk-8-alpine', command: 'cat', ttyEnabled: true),
],
volumes: [
  hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'),
  hostPathVolume(mountPath: '/root/.m2/repository', hostPath: '/root/.m2'),
  hostPathVolume(mountPath: '/tmp', hostPath: '/tmp')
]) {

node(label) {
    def myRepo = checkout scm
    def gitCommit = myRepo.GIT_COMMIT
    def gitBranch = myRepo.GIT_BRANCH

    def didFail = false
    def throwable = null

    try {        
        stage('Tests In Parallel') {
            parallel StaticCodeAnalysis: {
                container('maven'){
                    withSonarQubeEnv('sonarqube-cluster') {
                      // requires SonarQube Scanner for Maven 3.2+
                      sh " mvn help:evaluate -Dexpression=settings.localRepository"

                      sh "mvn clean"
                      sh "mvn compiler:help jar:help resources:help surefire:help clean:help install:help deploy:help site:help dependency:help javadoc:help spring-boot:help org.jacoco:jacoco-maven-plugin:prepare-agent"
                      sh "mvn org.jacoco:jacoco-maven-plugin:prepare-agent package sonar:sonar -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$SONAR_AUTH_TOKEN -Dsonar.exclusions=srcgen/**/* -Dmaven.test.skip=true"
                    }
                }
            }, unitTests: {
                container('maven2') {
                  sh "mvn clean package"

                  junit allowEmptyResults: true, testResults: '**/surefire-reports/*.xml'
                }
            },
            failFast: true
        }       
    } catch (e) {
        didFail = true
        throwable = e
    } finally {
        sh "rm -rf /tmp/${label}"
    }
    if (didFail) {
        echo "Something went wrong."
        error throwable
    }        

  }
}

一切似乎都正常,在蓝海 UI 上,我可以看到两个阶段同时正确运行。但是,当 parralell 阶段中的一个阶段完成时,另一个阶段会因“java.lang.NoClassDefFoundError”而失败,因为这些类肯定已经被使用过并且该阶段正在运行。

它几乎看起来像一个旋转的所有奴隶都使用相同的工作区目录,即:/home/jenkins/workspace/job_name/

maven 命令创建文件夹 - /home/jenkins/workspace/job_name/target/classes - 但是当您看到失败时,它会询问已使用的容器是否从类文件夹中获取了所有内容。

4

0 回答 0