Commit 4c8d45d4 authored by Emeric Verschuur's avatar Emeric Verschuur

Add gitlab service support

parent 6e4a84a7
......@@ -17,18 +17,18 @@
# Print an error message and exit with error status 1
print_critical() {
>&2 printf "\e[91m[ERROR] %s\e[0m\n" "$@"
>&2 printf "\e[91m[CRIT] %s\e[0m\n" "$@"
exit 1
}
# Print an error message
print_error() {
>&2 printf "\e[91m[ERROR] %s\e[0m\n" "$@"
>&2 printf "\e[91m[ERRO] %s\e[0m\n" "$@"
}
# Print a warning message
print_warning() {
>&2 printf "\e[93m[WARNING] %s\e[0m\n" "$@"
>&2 printf "\e[93m[WARN] %s\e[0m\n" "$@"
}
# Print a note message
......@@ -338,7 +338,7 @@ citbx_export() {
# Add docker run arguments
citbx_docker_run_add_args() {
CITBX_DOCKER_RUN_ARGS+=("$@")
CITBX_JOB_DOCKER_RUN_ARGS+=("$@")
}
# Load bashopts
......@@ -448,6 +448,8 @@ case "$command" in
-d "Run a shell instead of run the default command (override CITBX_COMMAND option)"
bashopts_declare -n CITBX_JOB_SHELL -l shell -t string -v "$CITBX_DEFAULT_JOB_SHELL" \
-d "Use a specific shell to run the job"
bashopts_declare -n CITBX_WAIT_FOR_SERVICE_START -l wait-srv-started -t number -v 0 \
-d "Wait for service start (time in seconds)"
CITBX_DOCKER_USER=${CITBX_DOCKER_USER:-root}
# Load job
......@@ -584,7 +586,7 @@ fi
# Git SHA1
CI_COMMIT_REF_NAME=${CI_COMMIT_REF_NAME:-$(cd $CI_PROJECT_DIR && git rev-parse --abbrev-ref HEAD)}
CITBX_DOCKER_RUN_ARGS+=(-e CI_COMMIT_REF_NAME="$CI_COMMIT_REF_NAME")
CITBX_JOB_DOCKER_RUN_ARGS+=(-e CI_COMMIT_REF_NAME="$CI_COMMIT_REF_NAME")
# Add variable to the environment list
CITBX_ENV_EXPORT_LIST+=(CI_JOB_NAME CI_REGISTRY CI_PROJECT_DIR)
......@@ -606,8 +608,10 @@ case "$CITBX_JOB_EXECUTOR" in
if [ -z "$CITBX_DOCKER_IMAGE" ] || [ "$CITBX_DOCKER_IMAGE" == "null" ]; then
print_critical "No image property found in .gitlab-ci.yml for the job $CI_JOB_NAME"
fi
CITBX_ID=$(head -c 8 /dev/urandom | od -t x8 -An | grep -oE '\w+')
CITBX_DOCKER_PREFIX="citbx-$CITBX_ID"
if [ -f "$HOME/.docker/config.json" ]; then
CITBX_DOCKER_RUN_ARGS+=(-v $HOME/.docker/config.json:/root/.docker/config.json:ro)
CITBX_JOB_DOCKER_RUN_ARGS+=(-v $HOME/.docker/config.json:/root/.docker/config.json:ro)
fi
CITBX_JOB_SHELL=${CITBX_JOB_SHELL:-"/bin/sh"}
if [ "$CITBX_UID" -eq 0 ] || [ "$CITBX_DOCKER_USER" != "root" ]; then
......@@ -618,7 +622,7 @@ case "$CITBX_JOB_EXECUTOR" in
fi
else
if [ -f "$HOME/.docker/config.json" ]; then
CITBX_DOCKER_RUN_ARGS+=(-v $HOME/.docker/config.json:$HOME/.docker/config.json:ro)
CITBX_JOB_DOCKER_RUN_ARGS+=(-v $HOME/.docker/config.json:$HOME/.docker/config.json:ro)
fi
CITBX_COMMANDS="
useradd -o -u $CITBX_UID -s /bin/sh -d $HOME -M ci-user;
......@@ -633,10 +637,8 @@ case "$CITBX_JOB_EXECUTOR" in
"
fi
print_info "Running the job $CI_JOB_NAME into the $CITBX_DOCKER_IMAGE docker container..."
if [ -n "$CITBX_DOCKER_USER" ]; then
CITBX_DOCKER_RUN_ARGS+=(-u "$CITBX_DOCKER_USER")
CITBX_JOB_DOCKER_RUN_ARGS+=(-u "$CITBX_DOCKER_USER")
fi
# Compute the environment variables
......@@ -647,18 +649,104 @@ case "$CITBX_JOB_EXECUTOR" in
CITBX_PRE_COMMANDS=()
# Entrypoint override management
if [ -n "$CITBX_DOCKER_ENTRYPOINT" ]; then
CITBX_DOCKER_RUN_ARGS+=(--entrypoint "$CITBX_DOCKER_ENTRYPOINT")
CITBX_JOB_DOCKER_RUN_ARGS+=(--entrypoint "$CITBX_DOCKER_ENTRYPOINT")
for e in "${CITBX_DOCKER_ENTRYPOINT[@]:1}"; do
CITBX_PRE_COMMANDS+=("$e")
done
fi
# hook executed on exit
executor_docker_exit_hook() {
test -n "$CITBX_DOCKER_PREFIX" || print_critical "Assert: empty CITBX_DOCKER_PREFIX"
for d in $(docker ps -a --filter "label=$CITBX_DOCKER_PREFIX" -q); do
docker rm -f $d > /dev/null 2>&1 || true
done
}
trap executor_docker_exit_hook EXIT SIGINT SIGTERM
wait_before_run_job=0
# Start a service
start_docker_service() {
local args=()
local image=$1
local name=$2
local ip
args+=(--name "$CITBX_DOCKER_PREFIX-$name" --label "$CITBX_DOCKER_PREFIX")
shift 2
if [ -n "$1" ]; then
args+=(--entrypoint "$1")
shift
fi
print_info "Starting service $name..."
docker run -d "${args[@]}" "${CITBX_DOCKER_RUN_ARGS[@]}" "$image" "$@"
# Get container IP and add --add-host options
ip=$(docker inspect $CITBX_DOCKER_PREFIX-$name | jq -r .[0].NetworkSettings.Networks.bridge.IPAddress)
CITBX_JOB_DOCKER_RUN_ARGS+=(--add-host "$name:$ip")
wait_before_run_job=$CITBX_WAIT_FOR_SERVICE_START
}
# Start services
for p in '."'"$CI_JOB_NAME"'"' ''; do
for s in $([ "$(gitlab_ci_query -r "$p.services | type")" != "array" ] \
|| seq 0 $(($(gitlab_ci_query -r "$p.services | length") - 1))); do
unset service_image service_alias service_commands
service_commands=()
case "$(gitlab_ci_query -r "$p.services[$s] | type")" in
object)
# Read the service name/image property
if [ "$(gitlab_ci_query -r "$p.services[$s].name | type")" == "string" ]; then
service_image=$(gitlab_ci_query -r "$p.services[$s].name")
else
print_critical "$s: property 'name' not found"
fi
# Read entrypoint property
if [ "$(gitlab_ci_query -r "$p.services[$s].entrypoint | type")" == "array" ]; then
for i in $(seq 0 $(gitlab_ci_query -r "$p.services[$s].entrypoint | length - 1")); do
service_commands+=("$(gitlab_ci_query -r "$p.services[$s].entrypoint[$i]")")
done
fi
# Read command property
if [ "$(gitlab_ci_query -r "$p.services[$s].command | type")" == "array" ]; then
for i in $(seq 0 $(gitlab_ci_query -r "$p.services[$s].command | length - 1")); do
service_commands+=("$(gitlab_ci_query -r "$p.services[$s].command[$i]")")
done
fi
# Read service alias property
if [ "$(gitlab_ci_query -r "$p.services[$s].alias | type")" == "string" ]; then
service_alias="$(gitlab_ci_query -r "$p.services[$s].alias")"
else
service_alias="$(echo "$service_image" | sed -E 's/:[^:\/]+//g' | sed -E 's/[^a-zA-Z0-9\._-]/__/g')"
fi
# Start service
start_docker_service "$service_image" "$service_alias" "${service_commands[@]}"
;;
string)
service_image=$(gitlab_ci_query -r "$p.services[$s]")
# Start service
start_docker_service "$service_image" "$(echo "$service_image" | sed -E 's/:[^:\/]+//g' | sed -E 's/[^a-zA-Z0-9\._-]/__/g')"
;;
*)
;;
esac
done
done
# Wait time
if [ $wait_before_run_job -gt 0 ]; then
print_note "Waiting $wait_before_run_job seconds before run the job..."
sleep $wait_before_run_job
fi
print_info "Running the job $CI_JOB_NAME into the $CITBX_DOCKER_IMAGE docker container..."
# Run the docker
exec docker run --rm -ti -e CI=true -e GITLAB_CI=true -v /var/run/docker.sock:/var/run/docker.sock \
docker run --rm -ti --name="$CITBX_DOCKER_PREFIX-build" --hostname="$CITBX_DOCKER_PREFIX-build" \
-e CI=true -e GITLAB_CI=true -v /var/run/docker.sock:/var/run/docker.sock \
-v "$CI_PROJECT_DIR:$CI_PROJECT_DIR:rw" -w "$CI_PROJECT_DIR" "${CITBX_DOCKER_RUN_ARGS[@]}" \
--label "$CITBX_DOCKER_PREFIX" "${CITBX_JOB_DOCKER_RUN_ARGS[@]}" \
-e DOCKER_RUN_EXTRA_ARGS="$(bashopts_get_def bashopts_extra_args)" \
"${bashopts_extra_args[@]}" $CITBX_DOCKER_IMAGE "${CITBX_PRE_COMMANDS[@]}" sh -c "$CITBX_COMMANDS"
exit 1
;;
*)
print_critical "Invalid or unsupported '$CITBX_JOB_EXECUTOR' executor"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment