jenkins 重用代理而无需多次声明它

vcudknz3  于 2023-05-28  发布在  Jenkins
关注(0)|答案(2)|浏览(129)

我尝试在一个jenkinsfile中定义一个agent,但是在多个阶段中使用它,而不需要为每个阶段完全声明它。可以看出,我使用了一个stage来确定要使用哪个docker镜像,然后在agent语句中设置一个global,这很好,如果我在每个stage中放置agent语句,它就可以按预期工作。然而,如果我需要修改代理的args语句或类似语句,这似乎是无效的,并且不太可维护。我想做类似下面的事情:

def imageURI = ""
def myagent = docker {
    image "$imageURI"
    args "--user 1000:1000 --name ${env.BUILD_NUMBER}_${env.jobName}"
}
pipeline {
    agent none
    stages {
        stage ("Once use agent") {
            agent {
                docker {
                    image "python:3.5-apline"
                }
            }
            steps {
                script {
                    imageURI = sh "command to get image URI"
            }
        }
        stage ("Build" ) {
            agent = myagent
            steps {
                sh "build code"
            }
        stage ( "Run Unit Test" ) {
            parallel {
                stage ( "UT 1" ) {
                    agent = myagent
                    steps {
                        sh "run unit test 1"
                    }
                }
                stage ( "UT 2" ) {
                    agent = myagent
                    steps {
                        sh "run unit test 2"
                    }
                }
            }
        }
    }
}

通过评论中的建议,我走得更远了。但是现在代理的图像字符串在设置之前就被评估了。下面,我需要一些方法来设置图像变量或一种方法来推迟变量的评估

def imageURI = ""
 
pipeline {
    agent {
        docker {
            image "$imageURI"
            args "--user 1000:1000 --name ${env.BUILD_NUMBER}_${env.jobName}"
        }
    }
    stages {
        stage ("Once use agent") {
            agent {
                docker {
                    image "python:3.5-apline"
                }
            }
            steps {
                script {
                    imageURI = sh "command to get image URI"
            }
        }
        stage ("Build" ) {
            steps {
                sh "build code"
            }
        stage ( "Run Unit Test" ) {
            parallel {
                stage ( "UT 1" ) {
                    steps {
                        sh "run unit test 1"
                    }
                }
                stage ( "UT 2" ) {
                    steps {
                        sh "run unit test 2"
                    }
                }
            }
        }
    }
}
ig9co6j1

ig9co6j11#

正如您所正确注意到的,当管道开始执行时,该变量进行计算。要在管道执行之前准备好它,您可以运行脚本化和声明性管道的组合。this answer中概述了实现方法,其中包括一个工作示例和输出。
在你的情况下,类似这样的东西会起作用:

def imageURI = null
echo "imageURI should be Null: $imageURI"

node() {
    stage("Define imageURI") {
        imageURI = sh "command to get image URI"
        echo "imageURI is now $imageURI"
    }
}

pipeline {
    agent {
        docker {
            image "$imageURI"
            args "--user 1000:1000 --name ${env.BUILD_NUMBER}_${env.jobName}"
        }
    }
j2qf4p5b

j2qf4p5b2#

在我的例子中,需要为docker代理设置许多属性,但所有属性的值在管道启动之前都是已知的。Docker代理需要在多个阶段使用,但不是所有阶段。为了避免在多个地方复制docker代理的所有属性,我在返回map的buildAgentConfig()方法中定义了一次属性。然后在每个阶段中,我将使用Docker代理的agent块定义为docker(buildAgentConfig())。最终管道的简化版本如下所示:

pipeline {
    agent any

    stages {
        stage('Init') {
            steps {
                sh '''#!/bin/bash
                    some command
                '''
            }
        }

        stage('test') {
            agent {
                docker(buildAgentConfig())
            }
            steps {
                sh '''#!/bin/bash
                   ./gradlew test
                '''
            }
        }

        stage('build') {
            when {
                anyOf {
                    branch 'master'
                    branch 'main'
                }
            }
            agent {
                docker(buildAgentConfig())
            }
            steps {
                sh '''#!/bin/bash
                   ./gradlew build -x test
                '''
            }
        }
    }
}

def buildAgentConfig() {
    [
        label: 'somelabel',
        image: 'myprivateregistry.com/openjdk:11.0-jdk',
        registryUrl: 'myprivateregistry.com',
        registryCredentialsId: 'some-credentials-id',
        args: '-v /var/lib/jenkins/.gradle/:/home/jenkins/.gradle/' +
              ' --env GRADLE_USER_HOME=/home/jenkins/.gradle/'
        reuseNode: true,
    ]
}

相关问题