Fix container entrypoint known issue about accessing CI/CD variables in the entrypoint for Kubernetes runners
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
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_ENVit 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_ENVis 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.