如何保留ENTRYPOINT但替换gitlab管道中docker镜像的CMD

hkmswyz6  于 2023-05-22  发布在  Docker
关注(0)|答案(1)|浏览(178)

我有以下Dockerfile:

FROM ubuntu:latest

# Prepare the operating system
RUN apt-get update && \
apt-get install --yes openjdk-11-jre

# Copy the CNES pluging
COPY ./src/sonar-cnes-report-4.1.3.jar /opt/cnes-report/sonar-cnes-report-4.1.3.jar

WORKDIR /opt/cnes-report

ENTRYPOINT [ "java", "-jar", "sonar-cnes-report-4.1.3.jar" ]
CMD [ "-h" ]

从这个镜像运行一个容器可以按照我想要的方式工作。例如:docker run <image>给我的帮助:

user@server:~/workspace$ docker run 8215b6dcc57b
usage: java -jar cnesreport.jar [-a <arg>] [-b <arg>] [-c] [-d <arg>] [-e] [-f] [-h] [-l <arg>] [-m] [-n <arg>] [-o <arg>] [-p
       <arg>] [-r <arg>] [-s <arg>] [-t <arg>] [-v] [-w] [-x <arg>]
Generate editable reports for SonarQube projects.

 -a,--author <arg>                 Name of the report writer.
 -b,--branch <arg>                 Branch of the targeted project. Requires Developer Edition or
                                   sonarqube-community-branch-plugin. Default: usage of main branch.
 -c,--disable-conf                 Disable export of quality configuration used during analysis.
 -d,--date <arg>                   Date for the report. Format: yyyy-MM-dd. Default: current date.
 -e,--disable-spreadsheet          Disable spreadsheet generation.
 -f,--disable-csv                  Disable CSV generation
 -h,--help                         Display this message.
 -l,--language <arg>               Language of the report. Values: en_US, fr_FR. Default: en_US.
 -m,--disable-markdown             Disable Markdown generation
 -n,--template-markdown <arg>      Path to the report template in markdown. Default: usage of internal template.
 -o,--output <arg>                 Output path for exported resources.
 -p,--project <arg>                SonarQube key of the targeted project.
 -r,--template-report <arg>        Path to the report template. Default: usage of internal template.
 -s,--server <arg>                 Complete URL of the targeted SonarQube server.
 -t,--token <arg>                  SonarQube token of the SonarQube user who has permissions on the project.
 -v,--version                      Display current version.
 -w,--disable-report               Disable report generation.
 -x,--template-spreadsheet <arg>   Path to the spreadsheet template. Default: usage of internal template.

Please report issues at https://github.com/cnescatlab/sonar-cnes-report/issues

如果我传递一个额外的参数,那就很好地覆盖了图像的CMD部分。例如:docker run 8215b6dcc57b -v给我这个:

user@server:~/workspace$ docker run 8215b6dcc57b -v
Current version: 4.1.3
user@server:~/workspace$

或者为项目生成实际报告也是可行的:docker run 8215b6dcc57b -t <mytoken> -s https://<sqserver> -f -m -p winformsapp2 -b develop
我想在gitlab-ci文件中使用此图像,并覆盖图像的CMD部分。我试过这个gitlab-ci.yml:

cnes:
  stage: report
  image: 
    name: "<mydockerregistry>/cnes-report-generator:v1.0.0"
  script:
    - -v

但这会失败,并出现以下错误:

[ERROR] Please provide a project with the -p argument, you can also use -h argument to display help.

经过一番研究,我发现了这篇文章,所以我试了一下。我修改了我的gitlab-ci.yml:

cnes:
  stage: report
  image: 
    name: "<mydockerregistry>/cnes-report-generator:v1.0.0"
    entrypoint: ["/bin/bash"]
  script:
    - java -jar sonar-cnes-report-4.1.3.jar -v

但这一个错误与以下:

/usr/bin/sh: /usr/bin/sh: cannot execute binary file

我该怎么做呢?理想情况下,我希望图像在命令行和gitlab管道中都可用,但如果我需要做出选择,gitlab管 prop 有优先权。理想情况下,image/container已经有了'java -jar xyz.jar'命令,所以我只需要在gitlab-ci.yml文件中添加-t -s -p参数。

kkbh8khc

kkbh8khc1#

为什么自定义ENTRYPOINT在GitLab CI中不起作用

您遇到的问题是GitLab CI希望您的映像没有入口点或入口点等效于/bin/bash -c。一般来说,在使用GitLab CI的docker镜像时,不应该偏离这一点。
即使我们想滥用ENTRYPOINT,另一个问题是CI配置中的script部分实际上并没有作为命令参数传递。GitLab会将自己的命令传递给你的容器,以发现合适的shell二进制文件,然后使用它来使用stdin中的文本,stdin是一个eval命令,它会传递给/bin/bash -c,其中部分包含你的before_script:/script:代码。
如果你想看到这一点,你可以运行这个配置:

# examples to expose inner-machinery of docker executor...

show-container-command:
  image:
    name: ubuntu
    entrypoint: ["/bin/bash", "-c", "echo $@"]
    # echo the command passed to the job container by the executor
  script:
    - echo does not matter -- will not appear in command

show-stdin-script:
  image:
    name: ubuntu
    entrypoint: ["/bin/bash", "-c", "while read line; do echo \"$line\"; done < /dev/stdin"]
    # this will show the crafted script the executor passes to stdin
    # warning: may expose secret env variables!
  script:  # script steps will appear in the command passed via stdin
    - echo "first line"
    - echo "second line"

这些作业的输出将帮助您了解GitLab CI docker executor实际发生的情况(并演示为什么您不能使用自己的入口点)。

你应该怎么做

所有这些都是为了说明:您当前的入口点将无法与GitLab CI一起使用。使用此映像的最佳方法是覆盖入口点并写出完整的命令,例如。script:中的java ... -v

cnes:
  stage: report
  image: 
    name: "<mydockerregistry>/cnes-report-generator:v1.0.0"
    entrypoint: [""]
  script:
    - java -jar /opt/cnes-report/sonar-cnes-report-4.1.3.jar -v

使用更方便

如果您想让此映像的用户更轻松地执行此操作,可以在映像中包含一个 Package 器脚本:

#!/usr/bin/env bash

# /usr/local/bin/generate-cnes-report

set -eou pipefail

exec java -jar /opt/cnes-report/sonar-cnes-report-4.1.3.jar "$@"

然后你的dockerfile可能会做这样的事情:

# ...
# copy the wrapper script to a location on PATH, ensuring executable bit is set
COPY --chmod=755 generate-cnes-report /usr/local/bin/generate-cnes-report
ENTRYPOINT ["generate-cnes-report"]
# ...

然后你的GitLab CI可能看起来像这样:

cnes:
  stage: report
  image: 
    name: "<mydockerregistry>/cnes-report-generator:v1.0.0"
    entrypoint: [""]
  script:
    - generate-cnes-report -v

相关问题