Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-43077

withEnv does not set some environment variables

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Major Major
    • docker-workflow-plugin
    • None
    • Jenkins 2.32.3
      BlueOcean 1.0.0-rc1

      I don't believe this is a duplicate of JENKINS-28317 but I haven't been able to figure out if I have that version of the plugin installed on my jenkins, because I'm not sure what plugin that applies to.

       

      I had a `withEnv` section that looked like:

      def flowContext(cl) {
          withEnv([
              'npm_config_cache=npm-cache',
              'npm_config_registry=http://npm.artifactory.mycompany.com/artifactory/api/npm/npm',
              'http_proxy=http://proxy.mycompany.com:8080',
              'https_proxy=http://proxy.mycompany.com:8080',
              'HTTP_PROXY=http://proxy.mycompany.com:8080',
              'HTTPS_PROXY=http://proxy.mycompany.com:8080',
              'PROXY_HOST=proxy.mycompany.com',
              'PROXY_PORT=8080',
              'no_proxy=.mycompany.com'
          ]) {
              credentialsContext(cl)
          }
      }
      
      def credentialsContext(cl) {
          withCredentials([
              usernamePassword(
                  credentialsId: 'service-account-user-pass',
                  passwordVariable: 'SVC_PASS',
                  usernameVariable: 'SVC_USER'
              ),
              usernamePassword(
                  credentialsId: 'github-auth-token',
                  passwordVariable: 'GITHUB_TOKEN',
                  usernameVariable: 'GITHUB_USERNAME'
              ),
              usernamePassword(
                  credentialsId: 'service-account-maven-artifactory-token',
                  passwordVariable: 'ARTIFACTORY_USER',
                  usernameVariable: 'ARTIFACTORY_TOKEN'
              ),
              usernamePassword(
                  credentialsId: 'service-account-maven-artifactory-password',
                  passwordVariable: 'ARTIFACTORY_USER',
                  usernameVariable: 'ARTIFACTORY_PASSWORD'
              ),
              string(credentialsId: 'slack-webhook', variable: 'SLACK_WEBHOOK_URL'),
              string(credentialsId: 'tracker-token', variable: 'TRACKER_TOKEN')
      
          ]) {
              cl()
          }
      }
      

      The credentials context is another function that exports a few credentials into the environment.
      All of the credentials would be there, but not all of the environment variables.

      This would be executed within a docker container like so:

          stage('Node Build') {
              docker.image(ciNode).inside() {
                  //Do the node installs in parallel, because the npm install is the slowest part, and we can use lots of cpu
                  parallel(
                      "Root Npm Install/Build": {
                          flowContext {
                              sh('env')
                              sh('npm install')
                              sh('gulp')
                          }
                      },
                      "webapp/static Install/Build": {
                          flowContext {
                              echo "Due to bug: https://issues.jenkins-ci.org/browse/JENKINS-33510"
                              sh('cd src/main/webapp/static && npm install')
                              sh('cd src/main/webapp/static && grunt prod')
                          }
                      },
                      failFast: true
                  )
              }
          }
      
      

      The sh('env') command within the flowContext would never show the no_proxy environment variable. I eventually gave up on trying to get it set in the Jenkinsfile, and instead put it in the root container image.

          [JENKINS-43077] withEnv does not set some environment variables

          Jesse Glick added a comment -

          Sounds like a bug but I have no idea offhand where. Would need to narrow it down into a minimal, self-contained reproduction case. (Is withCredentials necessary? Image.inside?)

          Jesse Glick added a comment - Sounds like a bug but I have no idea offhand where. Would need to narrow it down into a minimal, self-contained reproduction case. (Is withCredentials necessary? Image.inside ?)

          Seems we have the same issue for http_proxy, https_proxy and no_proxy env var setted in environement or withEnv.

          is it possible to have some news about this issue?

          Thanks.

           

          Aurélie Vache added a comment - Seems we have the same issue for http_proxy, https_proxy and no_proxy env var setted in environement or withEnv. is it possible to have some news about this issue? Thanks.  

          I'm hitting this as well, and hopefully can show it here:

          properties properties: [ // This is ugly https://stackoverflow.com/a/35471196
            parameters([
              string(defaultValue: '', description: 'RPM Release tag (e.g. "beta"). Usually left blank.', name: 'RPM_Release'),
            ]),
          ]
          // ... later ...:
                  // Start the actual build
                  // Workaround for JENKINS-43077 (as is any RR to get cleaned up later)
                  def RR=""
                  if (params.RPM_Release.trim())
                    RR="export RPM_RELEASE=${params.RPM_Release.trim()};"
                  prereq_image.inside("--volumes-from tools_arm_cs:ro --name ${env.BUILD_TAG}-C${OS}") {
                    withEnv(["RPM_RELEASE=${params.RPM_Release.trim()}"]) {
                      sh """
                        ${RR}
                        make -C releng driver
                        cd releng; make cdk # cdk-all
                        """
                    } // env
                  } // inside() container
          

          If I comment out that "RR" line, make isn't getting RPM_RELEASE set properly.

          If it matters, this is all within a closure that is going into a map for parallel and lives within a timestamps block.

          Aaron D. Marasco added a comment - I'm hitting this as well, and hopefully can show it here: properties properties: [ // This is ugly https://stackoverflow.com/a/35471196 parameters([ string(defaultValue: '', description: ' RPM Release tag (e.g. "beta" ). Usually left blank. ', name: ' RPM_Release'), ]), ] // ... later ...: // Start the actual build // Workaround for JENKINS-43077 (as is any RR to get cleaned up later) def RR="" if (params.RPM_Release.trim()) RR= "export RPM_RELEASE=${params.RPM_Release.trim()};" prereq_image.inside( "--volumes-from tools_arm_cs:ro --name ${env.BUILD_TAG}-C${OS}" ) { withEnv([ "RPM_RELEASE=${params.RPM_Release.trim()}" ]) { sh """ ${RR} make -C releng driver cd releng; make cdk # cdk-all """ } // env } // inside() container If I comment out that " RR " line, make isn't getting RPM_RELEASE set properly. If it matters, this is all within a closure that is going into a map for parallel and lives within a timestamps block.

          Jesse Glick added a comment -

          Probably a duplicate.

          Jesse Glick added a comment - Probably a duplicate.

          If it helps, I'm even hitting this now in a non-Docker environment.

          One call tree is: try => stage => parallel closure => node => timestamps => lock.

          Aaron D. Marasco added a comment - If it helps, I'm even hitting this now in a non-Docker environment. One call tree is: try => stage => parallel closure => node => timestamps => lock.

          Alexander Volanis added a comment - - edited

          I believe I identified the faulting code in the docker-workflow-plugin but I fail too see why this apparently intentional environment reduction is performed.

          Here: https://github.com/jenkinsci/docker-workflow-plugin/blob/master/src/main/java/org/jenkinsci/plugins/docker/workflow/WithContainerStep.java#L134

          and here: https://github.com/jenkinsci/docker-workflow-plugin/blob/master/src/main/java/org/jenkinsci/plugins/docker/workflow/WithContainerStep.java#L289

          If I am reading this correctly docker containers executing pipeline will have none of the slave environment showing in the container environment.

          I can understand PATH removal, it makes sense. But what if I am actively trying to override any environment that happens to be on the slave host with a direct withEnv call?

          Why am I prevented from actually making this choice?

          Would this be better logically to remove only if it has the same value not just the same key?

           

          Alexander Volanis added a comment - - edited I believe I identified the faulting code in the docker-workflow-plugin but I fail too see why this apparently intentional environment reduction is performed. Here:  https://github.com/jenkinsci/docker-workflow-plugin/blob/master/src/main/java/org/jenkinsci/plugins/docker/workflow/WithContainerStep.java#L134 and here:  https://github.com/jenkinsci/docker-workflow-plugin/blob/master/src/main/java/org/jenkinsci/plugins/docker/workflow/WithContainerStep.java#L289 If I am reading this correctly docker containers executing pipeline will have none of the slave environment showing in the container environment. I can understand PATH removal, it makes sense. But what if I am actively trying to override any environment that happens to be on the slave host with a direct withEnv call? Why am I prevented from actually making this choice? Would this be better logically to remove only if it has the same value not just the same key?  

          Jesse Glick added a comment -

          what if I am actively trying to override any environment that happens to be on the slave host with a direct withEnv call?

          withEnv inside withDockerContainer should work for that case I guess.

          Would this be better logically to remove only if it has the same value not just the same key?

          Possibly.

          In general, if you have any sort of subtle issues with withDockerContainer, my recommendation is simply not to use it. More transparent and reliable to just use sh 'docker run …' commands where you can precisely control the behavior according to Docker documentation.

          Jesse Glick added a comment - what if I am actively trying to override any environment that happens to be on the slave host with a direct withEnv call? withEnv inside withDockerContainer should work for that case I guess. Would this be better logically to remove only if it has the same value not just the same key? Possibly. In general, if you have any sort of subtle issues with withDockerContainer , my recommendation is simply not to use it. More transparent and reliable to just use sh 'docker run …' commands where you can precisely control the behavior according to Docker documentation.

          I'm facing this issue, I'm not running a docker but I cannot set my http_proxy 

          My code

          withEnv(["BOTO_CONFIG=${HOME}/xxxxx",
          "http_proxy=xxx"])

          { sh("env | grep -i proxy") }

           

          Logs

          + + env
          grep -i proxy
          NO_PROXY=localhost,......
          https_proxy=http://xxxx
          socks_proxy=xxxx{{}}
          ftp_proxy=ftp://xxxx{{}}
          proxy_test=http://xxxx{{}}
          AUTO_PROXY=http://xxxx{{}}
          HTTP_PROXY=http://xxxx{{}}

          Selma Ben Said added a comment - I'm facing this issue, I'm not running a docker but I cannot set my http_proxy  My code withEnv(["BOTO_CONFIG=${HOME}/xxxxx", "http_proxy=xxx"]) { sh("env | grep -i proxy") }   Logs + + env grep -i proxy NO_PROXY=localhost,...... https_proxy= http://xxxx socks_proxy= xxxx {{}} ftp_proxy=ftp:// xxxx {{}} proxy_test=http:// xxxx {{}} AUTO_PROXY=http:// xxxx {{}} HTTP_PROXY=http:// xxxx {{}}

          David Navrkal added a comment - - edited

          It will be almost 5 years and still not fixed, increasing priority since now in 2022 is still not possible to unset or change proxy setting when running Jenkins pipeline using docker image for just one step, e.g. by running:

          pipeline {
            agent {
              docker {
                image '<some docker image with already setup proxy env variables>'
                args '-u 0:0'
              }
            }
            stages {
              stage ('Prove withEnv can\'t change existing proxy setting in <some docker image with already setup proxy env variables>') {
                steps {
                  withEnv([
                  'http_proxy=',
                  'https_proxy=',
                  'no_proxy=',
                  'HTTP_PROXY=',
                  'HTTPS_PROXY=',
                  'NO_PROXY='
                  ]) {
                    sh(
                      label: "Prove that proxy setting from docker image can't be overwritten or unset by withEnv",
                      // This will print original proxy setting in docker image, completely unaffected by withEnv pipeline step...
                      script: 'env | grep -i proxy || true'
                    )
                  }
                }
              }
            }
          }
          

          David Navrkal added a comment - - edited It will be almost 5 years and still not fixed, increasing priority since now in 2022 is still not possible to unset or change proxy setting when running Jenkins pipeline using docker image for just one step, e.g. by running: pipeline { agent { docker { image '<some docker image with already setup proxy env variables>' args '-u 0:0' } } stages { stage ( 'Prove withEnv can\' t change existing proxy setting in <some docker image with already setup proxy env variables>') { steps { withEnv([ 'http_proxy=' , 'https_proxy=' , 'no_proxy=' , 'HTTP_PROXY=' , 'HTTPS_PROXY=' , 'NO_PROXY=' ]) { sh( label: "Prove that proxy setting from docker image can't be overwritten or unset by withEnv" , // This will print original proxy setting in docker image, completely unaffected by withEnv pipeline step... script: 'env | grep -i proxy || true ' ) } } } } }

          David Navrkal added a comment - - edited

          Only working workaround in pipelines running in docker images is to use something like this:

          sh(
            label: "Workaround to unset proxy env variables",
            script: '''
              unset http_proxy https_proxy no_proxy HTTP_PROXY HTTPS_PROXY NO_PROXY
              env | grep -i proxy  || true
              # Your commands which needs to have unset proxy env variables
            '''
          )
          

          David Navrkal added a comment - - edited Only working workaround in pipelines running in docker images is to use something like this: sh( label: "Workaround to unset proxy env variables" , script: ''' unset http_proxy https_proxy no_proxy HTTP_PROXY HTTPS_PROXY NO_PROXY env | grep -i proxy || true # Your commands which needs to have unset proxy env variables ''' )

            Unassigned Unassigned
            beepdog David Kowis
            Votes:
            6 Vote for this issue
            Watchers:
            12 Start watching this issue

              Created:
              Updated: