使用Jenkins声明性管道为dockerfile代理设置构建args [英] Setting build args for dockerfile agent using a Jenkins declarative pipeline

查看:301
本文介绍了使用Jenkins声明性管道为dockerfile代理设置构建args的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using the declarative pipeline syntax to do some CI work inside a docker container.

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

I've noticed that the Docker plugin for Jenkins runs a container using the user id and group id of the jenkins user in the host (ie if the jenkins user has user id 100 and group id 111 it would run the pipeline creating a container with the command docker run -u 100:111 ...).

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

I had some problems with this, as the container will run with a non existing user (particularly I ran into some issues with the user not having a home dir). So I thought of creating a Dockerfile that will receive the user id and group id as build arguments and creater a proper jenkins user inside the container. The Dockerfile looks like this:

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像这样:

The dockerfile agent has an additionalBuildArgs property, so I can read the user id and group id of the jenkins user in the host and send those as build aguments, but the problem I have now is that it seems that there is no way of executing those commands in a declarative pipeline before specifying the agent. I want my Jenkinsfile to be something like this:

// 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 {
        ..
      }
    }
    ...
  }
}

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

I there is any way to achieve this? I've also tried wrapping the pipeline directive inside a node, but the pipeline needs to be at the root of the file.

推荐答案

我已验证,如您所见,尝试在没有节点的情况下分配user_id和group_id无效,但这对于我分配这些值和以后的访问有效他们:

I verified that trying to assign user_id and group_id without a node didn't work, as you found, but this worked for me to assign these values and later access them:

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语句中使用.

Hopefully these will also work in your additionalBuildArgs statement.

在评论中,您指出了最有可能在使用声明性管道之前找出声明性管道之外的user_id和group_id的方法的严重缺陷:发现其user_id的从属不一定与它用来启动基于docker的构建的slave匹配.在保持声明性Jenkinsfile约束的同时,我没有任何解决方法.

In a comment, you pointed out what is most likely a critical flaw with the approach that figures out the user_id and group_id outside the declarative pipeline before using it to configure the dockerfile: the slave on which it discovers the user_id will not necessarily match up with the slave that it uses to kick off the docker-based build. i don't there is any way around this while also keeping the declarative Jenkinsfile constraint.

您可以通过使用全局代理声明来为所有阶段保证一个从属: Jenkins声明性管道:什么工作空间与一个阶段相关联?仅为管道设置了代理?

You can guarantee one slave for all stages by using a global agent declaration: Jenkins declarative pipeline: What workspace is associated with a stage when the agent is set only for the pipeline?

但是具有相同标签的多个节点引用不能保证相同的工作空间: Jenkins声明性管道:哪些工作空间与一个阶段相关联当只为管道设置代理时?

But multiple node references with the same label don't guarantee the same workspace: Jenkins declarative pipeline: What workspace is associated with a stage when the agent is set only for the pipeline?

这篇关于使用Jenkins声明性管道为dockerfile代理设置构建args的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆