Fix container entrypoint known issue about accessing CI/CD variables in the entrypoint for Kubernetes runners
Problem to solve
It is known that there is a known issue for runners using Kubernetes executor about accessing CI/CD variables from the entrypoint (as stated in https://docs.gitlab.com/runner/executors/kubernetes.html#container-entrypoint-known-issues). This could pose a breaking change for several workflows, requiring effort on adapting scripts.
It can be reproduced with the following code snippets and environment variables:
First, to create a couple of CI/CD environment variables under the GitLab UI (ENV_1
and ENV_2
with random values).
Second, to have a repository with the following files:
.
├── Dockerfile
├── entrypoint.sh
├── .gitlab-ci.yml
└── test.sh
with the following content:
Dockerfile
FROM <any-image-with-bash>
COPY test.sh /etc/profile.d/test.sh
COPY entrypoint.sh /
ENV BASH_ENV /etc/profile.d/test.sh
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
test.sh
echo "Running BASH_ENV script"
set -x
if [[ ! -z "${ENV_1}" && ! -z "${ENV_2}" ]]; then
echo "Env variables ENV_1 and/or ENV_2 defined!"
else
echo_error "Env variables ENV_1 and/or ENV_2 not defined!"
fi
set +x
entrypoint.sh
echo "Running entrypoint script"
set -x
if [[ ! -z "${ENV_1}" && ! -z "${ENV_2}" ]]; then
echo_info "Env variables ENV_1 and/or ENV_2 are defined!"
else
echo_error "Env variables ENV_1 and/or ENV_2 not defined!"
fi
set +x
env | grep ENV_
exec "$@"
And finally, the .gitlab-ci.yml
file:
.test:
image: <the resulting image from the above Dockerfile>'
script:
- echo $0
- env | grep ENV_
- "[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'"
- "shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'"
# Executes the job in a Docker+machine executor runner
test_old:
extends: .test
tags:
- docker-machine-executor-runner
# Executes the job in a Kubernetes+executor runner
# This case will not honor the entrypoint
test_new:
extends: .test
tags:
- k8s-runner
# Executes the job in a Kubernetes+executor runner
# This case, will honor the entrypoint
test_new_honor:
extends: .test
variables:
FF_KUBERNETES_HONOR_ENTRYPOINT: 1
tags:
- k8s-runner
If we run these jobs, it will be observed that the way environment variables are injected differs between the Docker+machine executor runners and the Kubernetes+executor runners.
Below are output for the corresponding jobs demonstrating it:
Docker+machine executor job output:
…
Executing "step_script" stage of the job script
Running BASH_ENV script
Env variables ENV_1 and/or ENV_2 are defined!
Running entrypoint script
Env variables ENV_1 and/or ENV_2 are defined!
$ echo $0
/usr/bin/bash
$ env | grep ENV_
ENV_1=[MASKED]
ENV_2=[MASKED]
Not interactive
Not login shell
Kubernetes+executor job output (regardless whether the entrypoint is honored or not):
...
Preparing environment
Running BASH_ENV script
Env variables ENV_1 and/or ENV_2 are not defined!
Executing “step_script” stage of the job script
Running BASH_ENV script
Env variables ENV_1 and/or ENV_2 are not defined!
Running BASH_ENV script
Env variables ENV_1 and/or ENV_2 are not defined!
$ echo $0
/scripts-168621-32120588/step_script
$ env | grep ENV_
ENV_1=[MASKED]
ENV_2=[MASKED]
Not interactive
Not login shell
What we extract from here, is that:
-
BASH_ENV
it is executed prior the environment variables are injected in the Kubernetes runners’ job. - While it is not the case for Docker+machine executor runners, where the
BASH_ENV
is executed WITH the environment variables already injected.
Proposal
Proposal goes for having a similar behaviour as the Docker+machine executor runners for Kubernetes+executor runners, thus obtaining a similar job output as the Docker+machine executor runners one showed above, i.e., thus having the environment variables defined and injected at the containers entrypoint, solving the limitation.