Peter Kahn
Peter Kahn

Reputation: 13046

Why doesn't the Jenkins shared library env object update HOME when dockerized stage updates that variable

When using env object in shared library, env.HOME value doesn't shift with a dockerized stage. When a shell step executes, its HOME points to the correct value.

In the case below, I'd expect env.HOME == sh(script:'echo $HOME', returnStdout: true).trim() and it does on the agent stage but not in the dockerized stage.

This is trivial to work around (use withEnv to set, use ~ or $HOME in shell commands to pull home from shell not groovy layer)

I'd just like to know the why behind it.

/vars/foo.groovy

def info() {
 println "Stage: ${env.STAGE_NAME}, env.HOME: ${env.HOME}
 sh 'echo HOME=$HOME'
}

# Jenkinsfile
...
stages {
  stage('agent') {
   steps {
     script { foo.info() }
   }
  }
  stage('dockerized') {
    agent {
    docker {
      image runnerImage
      reuseNode true
    }
   }
   steps {
     script { foo.info() }
   }

result

Stage: agent, HOME: /home/ec2-user
echo HOME=/home/ec2-user
 HOME=/home/ec2-user

Stage: agent, HOME: /home/ec2-user
echo HOME=/home/jenkins
 HOME=/home/jenkins

Upvotes: 0

Views: 69

Answers (1)

Peter Kahn
Peter Kahn

Reputation: 13046

Silly me, the answer appear during some insomnia. The HOME environment variable was set by the contain's operating system itself and therefore Jenkins and its shared library could not know what it was.

The /etc/passwd and setting of USER in the image's Dockerfile determines HOME. Any profile or rc files in HOME would add additional env variables.

The ways to limit the damage of this class from a library designer point of view are:

  • when using shell favor shell specific environment options
    • sh "ls ${env.HOME}" // bad idea, the HOME may not match container's idea
    • sh 'ls $HOME' // better, resolution from shell not Gstring
    • sh "ls ~" // ~ auto resolves to $HOME within shell
  • when using images, control the the HOME via -e ${HOME}:HOME

I'd also recommend using images what follow suit aligned with the agent OS structure when possible but if your shared library is used by 100s or 1000s of build jobs, you cannot know this will be the case and it is better to reduce the risk.

Upvotes: 0

Related Questions