当前位置: 首页 > 面试题库 >

使用Jenkins声明性管道为dockerfile代理设置构建args

郗俊能
2023-03-14
问题内容

我正在使用声明性管道语法在Docker容器中执行一些CI工作。

我注意到,用于Jenkins的Docker插件使用主机中jenkins用户的用户ID和组ID运行一个容器(即,如果jenkins用户具有用户ID
100和组ID 111,它将运行管道以创建带有命令docker run -u 100:111 ...)。

我遇到了一些问题,因为该容器将以不存在的用户运行(特别是我遇到了用户没有主目录的问题)。所以我想到了创建一个Dockerfile来接收用户ID和组ID作为构建参数,并在容器内创建一个合适的jenkins用户。Dockerfile看起来像这样:

FROM ubuntu:trusty
ARG user_id
ARG group_id

# Add jenkins user
RUN groupadd -g ${group_id} jenkins
RUN useradd jenkins -u ${user_id} -g jenkins --shell /bin/bash --create-home
USER jenkins

...

dockerfile代理具有一个additionalBuildArgs属性,因此我可以在主机中读取jenkins用户的用户ID和组ID并将其作为构建参数发送,但我现在遇到的问题是似乎无法执行这些命令在指定代理之前在声明性管道中进行操作。我希望我的Jenkinsfile是这样的:

// THIS WON'T WORK
def user_id = sh(returnStdout: true, script: 'id -u').trim()
def group_id = sh(returnStdout: true, script: 'id -g').trim()

pipeline {
  agent {
    dockerfile {
      additionalBuildArgs "--build-arg user_id=${user_id} --build-arg group_id=${group_id}"
    }
  }
  stages {
    stage('Foo') {
      steps {
        ...
      }
    }
    stage('Bar') {
      steps {
        ...
      }
    }
    stage('Baz') {
      steps {
        ..
      }
    }
    ...
  }
}

我有什么办法可以做到这一点?我也尝试过将管道指令包装在节点内,但管道必须位于文件的根目录。


问题答案:

正如您所发现的那样,我验证了尝试在没有节点的情况下分配user_id和group_id无效的方法,但这对我来说是有效的,可以分配这些值并稍后访问它们:

def user_id
def group_id
node {
  user_id = sh(returnStdout: true, script: 'id -u').trim()
  group_id = sh(returnStdout: true, script: 'id -g').trim()
}

pipeline {
  agent { label 'docker' }
  stages {
    stage('commit_stage') {
      steps {
        echo 'user_id'
        echo user_id
        echo 'group_id'
        echo group_id
      }
    }
  }
}

希望这些也能在您的additionalBuildArgs声明中起作用。

在评论中,您指出了在使用声明的管道之前先找出声明性管道之外的user_id和group_id的方法最有可能的关键缺陷:发现其user_id的从属不一定与之匹配用于启动基于docker的构建的slave。我没有办法解决这个问题,同时还保持声明性的Jenkinsfile约束。



 类似资料:
  • 问题内容: 我想通过Jenkins声明性管道设置构建名称和描述,但是找不到正确的方法。我尝试在管道之后使用环境支架,在代理支架中使用节点支架,等等。我总是会收到语法错误。 我的Jenkinsfile的最新版本如下: 错误是: 理想情况下,我希望能够从build.properties文件或Jenkins构建日志中读取MY_PROJECT和MY_VERSION_NUMBER。关于该要求的任何指导也将不

  • 我刚开始使用Jenkins声明性管道。在我支持一些类似的项目时,我考虑将类似的管道步骤(甚至阶段)放入可重用的构建块中。这些区块应保持在一个中心点,然后由单独的管道包括在内(例如:干燥)。 我将共享库视为脚本化管道的一个选项,但我不确定它是否也适用于声明性管道。 你知道在Jenkins声明性管道中使用像构建块这样的东西的方法吗? 举例说明: 如果您有一个用于Maven项目的标准管道(例如Sprin

  • 问题内容: 我正在尝试用一个使用Jenkins管道插件并从项目存储库加载a的新任务替换当前使用旧式Jenkins作业被黑客入侵的当前构建管道。 遗留作业所做的一件事是使用Description setter插件将构建说明设置为包含Mercurial哈希,用户名和当前版本,以便轻松查找构建。 有没有办法用Jenkins管道插件复制/模拟这种行为? 问题答案: 只是想通了。管道作业公开具有可写属性的全

  • 我想从Jenkins声明性管道中设置构建名称和描述,但是找不到正确的方法。我尝试在管道后使用环境括号,在代理括号中使用节点括号,等等。我总是得到语法错误。 我的Jenkinsfile的最后版本是这样的: 错误是: 理想情况下,我希望能够从构建中读取MY_PROJECT和MY_VERSION_NUMBER。属性文件,或从Jenkins构建日志。对于该要求的任何指导也将不胜感激。 更新 根据我下面的回

  • 我有几个不同repo的Jenkins声明性管道,它们触发数据库刷新,以及依赖于数据库的单元测试。这些Jenkins作业是从GitHub中的pull请求触发的。 为了避免资源冲突,我需要防止这些作业同时运行——无论是在每个项目内还是在各个项目之间。 “油门并发构建”插件似乎就是为此而构建的。 我已经安装了插件,并配置了如下类别: 我在Jenkins文件中添加了“throttle”选项,其中一个存储库

  • 当我在jenkins中运行多分支管道代码时,我收到以下的以下错误: java.lang.NoSuchMethodError:在步骤中找不到这样的DSL方法“管道”[archive,bat,build,catchError,checkout,deleteDir,dir,echo,emailext,EmailExtrecients,error,fileExists,getContext,git,inp