Search code examples
dockerjenkins-pipeline

Jenkins pipeline DSL with docker-workflow-plugin .inside doesn't allow setting/modification of PATH via withEnv


Problem

I want to modify the path in a docker container to control tool selection without the need to modify existing pipeline code. I've a shared library and client builds call runAnsible which then runs pipeline DSL within a docker container via the docker-workflow-plugin.

However, when I use withEnv docker.inside, I cannot modify path

docker.inside() {
   withEnv("PATH=${env.PATH}:/ansible2.10/bin") {
    sh 'echo PATH=$PATH'
   }
 }

When results in PATH= the old path value and not containing my modification. According to JENKINS-45916 that's not a bug but how it works and we all we told - don't do that, use different images etc

So, what options do I have to alter the path beyond making a bunch of very similar images with different paths?


Solution

  • Docker workflow plugin allows args to be passed to the docker run command which creates the container. These args are just a string and its integrity appears respected by the pluign whereas withEnv has some kind of filter in this context.

    Therefore, this works but it does assume that I know or can determine the original path. I could run the container without path modification and use a sh(script: 'echo $PATH', returnStdout: true).trim() via docker.inside to get the knownOriginalPath in an earlier step to fee the code below

    // hardcoded because I own the image or have determined what the image's path normally is
    def knownOriginalPath="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    
    // my change to the path - in this case, a custom tool location used because I don't want to have to modify a bunch of existing pipeline code.
    def pathModification="/ansible2.10/bin"
    def desiredPath="${pathModification}:${knownOriginalPath}"
    
    
        docker.withRegistry(...) {
           // for now, the plugin seems to respect the integrity of the inside option string.
            docker.image(..)inside("-e PATH=${desiredPath}") {
                sh 'echo PATH = $PATH'        
            }
        }