为什么当 dockerized 阶段更新该变量时 Jenkins 共享库 env 对象不更新 HOME

问题描述 投票:0回答:1

在共享库中使用

env
对象时,
env.HOME
值不会随 dockerized 阶段而变化。当 shell 步骤执行时,其
HOME
指向正确的值。

在下面的情况下,我期望

env.HOME == sh(script:'echo $HOME', returnStdout: true).trim()
并且它在 agent 阶段 实现,但不在 dockerized 阶段

解决这个问题很简单(使用withEnv来设置,在shell命令中使用

~
$HOME
从shell而不是groovy层拉回家)

我只是想知道背后的原因。

/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() }
   }

结果

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
jenkins-shared-libraries
1个回答
0
投票

愚蠢的我,答案出现在一些失眠期间。 HOME 环境变量是由包含的操作系统本身设置的,因此 Jenkins 及其共享库无法知道它是什么。

/etc/passwd 和镜像 Dockerfile 中

USER
的设置决定了 HOME。 HOME 中的任何配置文件或 rc 文件都会添加额外的环境变量。

从库设计者的角度来看,限制此类损害的方法是:

  • 使用 shell 时青睐 shell 特定环境选项
    • 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
  • 使用图像时,通过
    -e ${HOME}:HOME
  • 控制 HOME

我还建议尽可能使用与代理操作系统结构一致的映像,但如果您的共享库被数百或数千个构建作业使用,您无法知道会出现这种情况,最好降低风险.

© www.soinside.com 2019 - 2024. All rights reserved.