Commit 5a03f66f authored by Stephane Bausseron's avatar Stephane Bausseron

Merge branch 'feature-pipeline' into 'master'

Pipeline feature

Closes #10

See merge request !30
parents 66e83ab7 24c04ae0
Pipeline #29187726 passed with stages
in 5 minutes and 10 seconds
......@@ -43,3 +43,9 @@ CITBX_DOCKER_DEFAULT_DNS=(208.67.222.123 208.67.220.123)
#CITBX_DOCKER_DEFAULT_DNS=(9.9.9.9)
# * Google
#CITBX_DOCKER_DEFAULT_DNS=(8.8.8.8 8.8.4.4)
#
# Default selected pipeline name
#CITBX_DEFAULT_PIPELINE_NAME="my custom pipeline"
#
# To disable the default global pipeline
#CITBX_DISABLE_DEFAULT_GLOBAL_PIPELINE="true"
image: ubuntu:16.04
variables:
GLOBAL_TEST_VAR: "scope: global"
after_script:
- echo "job ${CI_JOB_NAME} end"
job-minimal:
stage: build
tags:
- docker
script:
- echo "Hello world"
job-with-before-after-script:
stage: build
tags:
- docker
before_script:
- echo "executed before"
script:
- echo "script"
"on several"
- echo "lines"
- cat <<< $(echo 'hi!')
after_script:
- echo "executed after"
job-advanced:
image: ubuntu:16.04
stage: build
tags:
- docker
variables:
JOB_TEST_VAR: "${CI_JOB_NAME} - ${GLOBAL_TEST_VAR}"
script:
- ci-scripts/run-job-script.sh
job-test-services-mysql:
stage: build
variables:
MYSQL_DATABASE: test
MYSQL_ROOT_PASSWORD: password
image: mysql
services:
- mysql
tags:
- docker
script:
- printf "Waiting for mysql";
TIME_SEC_MAX=60;
while ! mysql -h mysql -u root -ppassword test -e '' > /dev/null 2>&1 ;
do printf "."; ((TIME_SEC_MAX--)) || (printf " timeout!\n"; exit 1); sleep 1; done;
printf " done!\n"
- mysql -h mysql -u root -ppassword test -e 'SHOW VARIABLES LIKE "%version%";'
job-test-services-postgres:
stage: build
image: postgres:9.4
services:
- name: postgres:9.4
alias: db-postgres
entrypoint: ["docker-entrypoint.sh"]
command: ["postgres"]
tags:
- docker
script:
- printf "Waiting for postgres";
TIME_SEC_MAX=60;
while ! psql -h db-postgres -U postgres -c '' > /dev/null 2>&1 ;
do printf "."; ((TIME_SEC_MAX--)) || (printf " timeout!\n"; exit 1); sleep 1; done;
printf " done!\n"
- psql -h db-postgres -U postgres -c 'select version();'
job-test-deps:
stage: test
tags:
- docker
script:
- echo "Simple job to test dependencies"
dependencies:
- job-with-before-after-script
- job-advanced
##################################################
# ### PACKAGE BUILD ### #
##################################################
......@@ -142,7 +57,7 @@ build-package-rel-rpm: *build-package-rel
script: ["ci-scripts/run-job-script.sh"]
test-package-deb-dev-ubuntu-18.04:
image: ubuntu:16.04
image: ubuntu:18.04
dependencies: ["build-package-dev-deb"]
<<: *test-package-template
<<: *package-channel-dev
......@@ -158,11 +73,11 @@ test-package-rpm-dev-fedora-27:
<<: *package-channel-dev
test-package-deb-rel-ubuntu-18.04:
image: ubuntu:16.04
image: ubuntu:18.04
dependencies: ["build-package-rel-deb"]
<<: *test-package-template
<<: *package-channel-rel
test-package-deb-rel-ubuntu-14.04:
test-package-deb-rel-ubuntu-16.04:
image: ubuntu:16.04
dependencies: ["build-package-rel-deb"]
<<: *test-package-template
......
# Changelog
## 5.3.0
* [ci-toolbox] Update ci-toolbox.sh CITBX_VERSION from VERSION file
* [wrapper] Improve bash completion mode detection when the local ci-toolbox/ci-toolbox.sh file is used (useful during development process)
* [bashopts] Update version with the fix of enumeration type to support values with spaces
* [ci-toolbox] Move job run part into citbx_run_job
* [ci-toolbox] Rewrite Gitlab-CI file treatment parts like image, services and scripts objects
* [ci-toolbox] Add pipeline feature
* [tests] Add the test suite (tests/run-testsuite.sh)
## 5.2.1
* [ci-toolbox] Fix CITBX_VERSION_REQ_MIN test to prevent recursive 'ci-toolbox setup' call
* [wrapper] Improve existing file detection (file command not enough reliable)
......
......@@ -10,12 +10,13 @@ Cette boîte à outils peut être utilisée pour
* [Le projet](#le-projet)
* [Installation de l'outil ci-toolbox](#installation-de-loutil-ci-toolbox)
* [Installation et configuration des prérequis](#installation-et-configuration-des-prérequis)
* [Mise à jours de l'outil ci-toolbox](#mise-à-jours-de-loutil-ci-toolbox)
* [Mise à jour de l'outil ci-toolbox](#mise-à-jour-de-loutil-ci-toolbox)
* [Intégration optionnelle du composant run-job-script.sh dans une arborescence projet](#intégration-optionnelle-du-composant-run-job-scriptsh-dans-une-arborescence-projet)
* [Cas d'utilisation : Tâche de pipeline Gitlab standard](#cas-dutilisation--tâche-de-pipeline-gitlab-standard)
* [Exécuter une tâche spécifique localement](#exécuter-une-tâche-spécifique-localement)
* [Première solution : utiliser l'outil gitlab-runner](#première-solution--utiliser-loutil-gitlab-runner)
* [La seconde solution : la commande ci-toolbox](#la-seconde-solution--la-commande-ci-toolbox)
* [Commande pipeline](#commande-pipeline)
* [Écrire une tâche ou un module en utilisant le composant run-job-script.sh](#Écrire-une-tâche-ou-un-module-en-utilisant-le-composant-run-job-scriptsh)
* [Écrire une tâche](#Écrire-une-tâche)
* [Écriture d'un module](#Écriture-dun-module)
......@@ -112,6 +113,7 @@ Cette boîte à outils est capable de le faire :
* démarrer une tâche de type script ou `docker` avec les paramètres appropriés (image, etc.)
* lancer une tâche du pipeline localement sans avoir à valider un enregistrement (`git commit`)
* Lancer des pipelines (voir [Commande pipeline](#commande pipeline))
Fonctions additionnelles pour une utilisation avancée (avec l'utilisation de `run-job-script.sh`) :
......@@ -127,6 +129,39 @@ Les limites connues de la boîte à outils :
* Applicable uniquement pour les types d'exécuteur de tâche Gitlab `docker` et `shell`
## Commande pipeline
La commande pipeline (`ci-toolbox pipeline [arguments...]`) permet de :
* lancer le pipeline par défaut qui reprend la liste de toutes les tâches présentes dans le fichier `.gitlab-ci.yml` en utilisant la commande `ci-toolbox pipeline`
* lancer un pipeline spécifique/sur mesure en utilisant la commande `ci-toolbox pipeline -n <nom du pipeline>`
Les pipelines spécifiques doivent être spécifiés dans le fichier `.ci-pipelines.yml` en utilisant le format suivant :
```YAML
pipeline simple:
- tâche 1
- tâche 2
- tâche 5
pipeline avancé:
- tâche 3
- tâche 5
- name: tâche 2
arguments:
argument-1: "valeur 1"
argument-2: ["première valeur", "deuxième valeur"]
```
Le document YAML est un objet composé de la manière suivante :
* chaque clé correspond à un nom de pipeline
* chaque valeur est un tableau contenant la liste des tâches
Chaque tâche peut être représentée par :
* Une chaine de caractère contenant le nom de la tâche
* Un objet contenant un camp `name` et `arguments` ave la liste des arguments
Un exemple de fichier `.ci-pipelines.yml` est disponible [ici](tests/.ci-pipelines.yml)
## Écrire une tâche ou un module en utilisant le composant run-job-script.sh
En plus de pouvoir lancer une tâche du pipeline, (comme la tâche [job-minimal](#job-minimal)), vous pouvez utiliser le composant `run-job-script.sh` pour écrire les scripts de celle-ci avec une structure modulaire comme c'est le cas pour la tâche d'exemple [job-advanced](#job-advanced)
......
......@@ -16,6 +16,7 @@ This toolbox can be used to
* [Run a specific job locally](#run-a-specific-job-locally)
* [First solution: using gitlab-runner tool](#first-solution-using-gitlab-runner-tool)
* [Second solution: Use ci-toolbox command](#second-solution-use-ci-toolbox-command)
* [Pipeline command](#pipeline-command)
* [Write a job or a module script using the run-job-script.sh component](#write-a-job-or-a-module-script-using-the-run-job-scriptsh-component)
* [Write a job](#write-a-job)
* [Write a module](#write-a-module)
......@@ -111,7 +112,8 @@ In addition you have to:
This tool is able to:
* Start a docker executor with the suitable parameters (image, etc.)
* Run job without having to commit the local changes
* Run job without having to commit the local changes (using the command `ci-toolbox <my_job_name> [args...]`)
* Run pipelines (see [Pipeline command](#pipeline-command))
Additional advanced ci-toolbox tool functionalities (using `run-job-script.sh`):
......@@ -127,6 +129,39 @@ Know limitations:
* Only applicable for docker and shell executor
## Pipeline command
The pipeline command (`ci-toolbox pipeline [arguments...]`) can be used to:
* run the default pipeline with whole the jobs founds in the .gitlab-ci.yml using the command `ci-toolbox pipeline`
* run a custom/specific pipeline using the command `ci-toolbox pipeline -n <my_pipeline_name>`
The custom pipelines must be specified into the file `.ci-pipelines.yml` using the following format:
```YAML
simple custom pipeline:
- my job 1
- my job 2
- my job 5
advanced custom pipeline:
- my job 3
- my job 5
- name: my job 2
arguments:
argument-1: "custom value"
argument-2: ["1st custom value", "2nd custom value"]
```
The YAML document is an object containing the pipelines where:
* each key is corresponding to the pipeline name
* each value is an array of jobs
Each jobs can be represented by:
* A string containing the job name
* An object containing a `name` and `arguments` with the custom argument list
An example of `.ci-pipelines.yml` can be found [here](tests/.ci-pipelines.yml)
## Write a job or a module script using the run-job-script.sh component
In addition, to run a classical job (like [job-minimal](#job-minimal)), you can use the `run-job-script.sh` component to write a job into a modular format (Job parts, modules, ...) like the [job-advanced](#job-advanced) job example.
......
......@@ -59,10 +59,12 @@ job_main() {
print_critical "Unsupported package type: '$pkgtype'"
;;
esac
mkdir -p artifacts
mkdir -p artifacts build
sed -E 's/^(CITBX_VERSION=).*$/\1'"$(cat VERSION)"'/g' ci-toolbox/ci-toolbox.sh > build/ci-toolbox.sh
chmod +x build/ci-toolbox.sh
fpm_args+=(
packaging/root/=/
ci-toolbox/ci-toolbox.sh=/usr/lib/ci-toolbox/ci-toolbox.sh
build/ci-toolbox.sh=/usr/lib/ci-toolbox/ci-toolbox.sh
ci-scripts/common.sh=/usr/lib/ci-toolbox/common.sh
.ci-toolbox.properties=/etc/ci-toolbox/ci-toolbox.properties.default
ci-toolbox/env-setup/=/usr/lib/ci-toolbox/env-setup/
......@@ -72,3 +74,7 @@ job_main() {
)
fpm "${fpm_args[@]}"
}
job_after() {
rm -rf build
}
......@@ -67,11 +67,16 @@ job_main() {
echo -n "Waiting for docker daemon"
until [ -e /var/run/docker.sock ]; do sleep 1; echo -n "."; done
print_info "### STEP3 ### job-* exec"
for j in $(ci-toolbox | grep '^ job-'); do
print_info "### JOB ### Running job $j..."
sudo -u test-user env HOME="$TEST_USER_HOME" ci-toolbox $j
done
print_info "### STEP4 ### run pipeline"
sudo -u test-user env \
CITBX_SEARCH_PATH=ci-toolbox/ \
CI_CONFIG_PATH="tests/.gitlab-ci.yml" \
CITBX_PIPELINES_CONFIG_PATH="tests/.ci-pipelines.yml" \
CITBX_SCRIPTS_DIR=tests/ci-scripts \
ci-toolbox pipeline
print_info "### STEP5 ### run testsuite"
sudo -u test-user env HOME="$TEST_USER_HOME" ./tests/run-testsuite.sh
}
job_after() {
......
# Copyright 2017 Emeric Verschuur <emeric@mbedsys.org>
# Copyright 2017-2018 Emeric Verschuur <emeric@mbedsys.org>
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
......@@ -19,7 +19,7 @@
set -e
BASHOPTS_VERSION=2.1.0
BASHOPTS_VERSION=2.1.1
bashopts_exit_handle() {
local err=$?
......@@ -256,7 +256,7 @@ bashopts_declare() {
-l) options[long_opt]=$1; shift;;
-d) options[description]=$1; shift;;
-t) options[type]=$1; shift;;
-e) options_enum_values+=($1); shift;;
-e) options_enum_values+=("$1");shift;;
-m) options[method]=$1; shift;;
-k) options[check]=$1; shift;;
-s) options[setting]="true";;
......@@ -280,7 +280,7 @@ bashopts_declare() {
if [ ${#options_enum_values[@]} -lt 2 ]; then
bashopts_log C "bashopts_declare: ${options[name]} enumeration need at least two elements (two '-e <val>' calls at least)"
fi
options[enum_values]="$(IFS=$'\n'; echo "${options_enum_values[*]}")"
options[enum_values]="$(printf "%s\n" "${options_enum_values[@]}")"
;;
s|str|string)
options[type]="string"
......@@ -387,9 +387,12 @@ bashopts_math_min() {
# join array element
bashopts_join_by() {
local IFS="$1"
shift || bashopts_log C "Usage: bashopts_join_by <character> [elt1 [elt2...]]"
echo "$*"
local sep="$1"
shift || bashopts_log C "Usage: bashopts_join_by <separator> [elt1 [elt2...]]"
printf "%s" "$1"
test $# -gt 1 || return 0
shift
printf "$sep%s" "$@"
}
# dump an option value by its name
......
......@@ -15,7 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
CITBX_VERSION=5.2.1
CITBX_VERSION=$(cat $(dirname $0)/../VERSION)
CITBX_TOOL_DIR=$(dirname $(readlink -f $0))
if [ -f "$CITBX_TOOL_DIR/ci-toolbox.properties" ]; then
......@@ -44,6 +44,9 @@ eval "$(sed -E 's/^([^=]+)=(.*)$/OS_RELEASE_INFO[\1]=\2/g' /etc/os-release)"
# YAML to JSON convertion
citbx_yaml2json() {
if [ ${#CITBX_MISSING_PKGS[@]} -ne 0 ]; then
print_critical "System setup required (command 'ci-toolbox setup')"
fi
cat "$@" | python3 -c 'import sys, yaml, json; json.dump(yaml.load(sys.stdin), sys.stdout)'
}
......@@ -61,19 +64,12 @@ if [ "$CITBX_GIT_LFS_SUPPORT_ENABLED" == "true" ] && ! git lfs version > /dev/nu
CITBX_MISSING_PKGS+=("git-lfs")
fi
if [ -n "$CI_PROJECT_DIR" ]; then
if [ ! -f $CI_PROJECT_DIR/.gitlab-ci.yml ]; then
print_warning "$CI_PROJECT_DIR/.gitlab-ci.yml file not found"
fi
if [ ${#CITBX_MISSING_PKGS[@]} -eq 0 ]; then
GITLAB_CI_JSON=$(citbx_yaml2json $CI_PROJECT_DIR/.gitlab-ci.yml)
else
print_warning "System setup required (command 'ci-toolbox setup')"
fi
fi
citbx_gitlab_ci_query() {
jq "$@" <<< "$GITLAB_CI_JSON"
jq "$@" <<< "$CITBX_GITLAB_CI_JSON"
}
citbx_pipelines_query() {
jq "$@" <<< "$CITBX_PIPELINES_JSON"
}
# Check environment and run setup
......@@ -116,7 +112,6 @@ citbx_check_env() {
# Get the job list
citbx_job_list() {
local prefix outcmd arg
prefix='[^\.]'
outcmd='print $0'
if ! arglist=$(getopt -o "f:p:s" -n "citbx_list " -- "$@"); then
print_critical "Usage citbx_list: [options]" \
......@@ -136,67 +131,10 @@ citbx_job_list() {
*) print_critical "Fatal error";;
esac
done
citbx_gitlab_ci_query -r 'paths | select(.[-1] == "script") | .[0]' \
printf "%s\n" "${CITBX_JOB_LIST[@]}" \
| gawk 'match($0, /^'"$prefix"'(.*)$/, f) {'"$outcmd"'}'
}
# fetch YAML variables
citbx_gitlab_ci_variables() {
local node=$1
local value
test -n "$node" \
|| print_critical "Usage: citbx_gitlab_ci_variables <node path>"
local node_type="$(citbx_gitlab_ci_query -r "$node | type")"
case "$node_type" in
null)
return 1
;;
object)
for k in $(citbx_gitlab_ci_query -r "$node | keys[]"); do
if ! [[ "$(citbx_gitlab_ci_query -r "${node}.$k | type")" =~ ^(string|number)$ ]]; then
print_critical "Invalid $node variable (type=$(citbx_gitlab_ci_query -r "${node}.$k | type"): $k). Only strings and numbers are supported."
fi
value="$(citbx_gitlab_ci_query "${node}.$k")"
eval "$k=$value"
CITBX_JOB_VARIABLE_LIST+=($k)
CITBX_DOCKER_RUN_ARGS+=(-e "$(eval "echo $k=$value")")
done
;;
*)
print_critical "Invalid $node type"
;;
esac
}
# put YAML (array or string) node script content indo CITBX_YAML_SCRIPT_ELTS
citbx_gitlab_ci_script() {
local node=$1
local line
test -n "$node" \
|| print_critical "Usage: citbx_gitlab_ci_script <node path>"
local script_type="$(citbx_gitlab_ci_query -r "$node | type")"
case "$script_type" in
null)
return 1
;;
string)
CITBX_YAML_SCRIPT_ELTS+=(citbx_gitlab_ci_query -r "${node}")
;;
array)
for i in $(seq 0 $(($(citbx_gitlab_ci_query "$node | length")-1))); do
line=$(citbx_gitlab_ci_query -r "${node}[$i]")
if [ "$(citbx_gitlab_ci_query -r "${node}[$i] | type")" != "string" ]; then
print_critical "Invalid $node line: $line"
fi
CITBX_YAML_SCRIPT_ELTS+=("$line")
done
;;
*)
print_critical "Invalid $node type"
;;
esac
}
# Run job dependencies
citbx_run_job_dependencies() {
local job_dependency_tree
......@@ -274,6 +212,451 @@ citbx_docker_run_add_args() {
CITBX_JOB_DOCKER_RUN_ARGS+=("$@")
}
citbx_run_job() {
# Fetch git submodules
if [ "$GIT_SUBMODULE_STRATEGY" != "none" ]; then
GIT_SUBMODULE_ARGS=()
case "$GIT_SUBMODULE_STRATEGY" in
normal)
;;
recursive)
GIT_SUBMODULE_ARGS+=("--recursive")
;;
*)
print_critical "Invalid value for GIT_SUBMODULE_STRATEGY: $GIT_SUBMODULE_STRATEGY"
;;
esac
print_info "Fetching git submodules..."
git submodule --quiet sync "${GIT_SUBMODULE_ARGS[@]}"
git submodule update --init "${GIT_SUBMODULE_ARGS[@]}"
fi
if [ "$CITBX_GIT_CLEAN" == "true" ]; then
git clean -fdx
if [ "$GIT_SUBMODULE_STRATEGY" != "none" ]; then
git submodule --quiet foreach "${GIT_SUBMODULE_ARGS[@]}" git clean -fdx
fi
fi
# Run job dependencies first (if asked)
if [ "$CITBX_RUN_JOB_DEPENDENCIES" == "true" ]; then
citbx_run_job_dependencies
fi
# Login to the registry if needed
if [ -n "$CI_REGISTRY" ] \
&& ( ( [ -z "$(jq -r '."auths"."'$CI_REGISTRY'" | select(.auth != null)' $HOME/.docker/config.json 2> /dev/null)" ] \
&& [ "$CITBX_DOCKER_LOGIN_MODE" == "auto" ] ) \
|| [ "$CITBX_DOCKER_LOGIN_MODE" == "enabled" ] ); then
print_info "You seem to be not authenticated against the gitlab docker registry" \
"> You can disable this feature by using --docker-login=disabled" \
"> Or force this feature permanently by setting CITBX_DEFAULT_DOCKER_LOGIN_MODE into $CI_PROJECT_DIR/.ci-toolbox.properties" \
"Please enter your gitlab user id and password:"
docker login $CI_REGISTRY
fi
# Compute commands from before_script script and after_script
# ### Script part: BEGIN ###
CITBX_JOB_SCRIPT_PARTS+=('
print_info() {
printf "\033[1m\033[92m%s\033[0m\n" "$@"
}
print_error() {
printf "\033[1m\033[91m%s\033[0m\n" "$@"
}
print_cmd() {
printf "\033[1m\033[92m$ %s\033[0m\n" "$@"
}
')
if [ "$CITBX_DEBUG_SCRIPT_ENABLED" == "true" ]; then
CITBX_JOB_SCRIPT_PARTS+=('set -x')
fi
# ### Script part ###
CITBX_JOB_SCRIPT_PARTS+=('
set -e
__citbx_on_job_exit__() {
local __job_exit_code__=$?
(
set -e
print_info "Running after script..."
'"$(
# Extract the job specific or global after_script property content
# and put it into the job exit function to be executed after the main part
citbx_gitlab_ci_query -r '
if ."'"$CI_JOB_NAME"'".after_script != null then
."'"$CI_JOB_NAME"'".after_script
elif .after_script != null then
.after_script
else [] end | map([@sh "print_cmd \(.)", "\(.)"])
| if (. | length) != 0 then (. | add | join("\n")) else "" end
')"'
)
if [ $__job_exit_code__ -eq 0 ]; then
print_info "Job succeeded"
else
print_error "ERROR: Job failed: exit code $__job_exit_code__"
fi
}
trap __citbx_on_job_exit__ EXIT SIGHUP SIGINT SIGQUIT SIGABRT SIGKILL SIGALRM SIGTERM
'"$(
# Extract the content of job specific or global before_script property
# following by the job script property content
citbx_gitlab_ci_query -r '[
if ."'"$CI_JOB_NAME"'".before_script != null then
."'"$CI_JOB_NAME"'".before_script
elif .before_script != null then
.before_script
else [] end, ."'"$CI_JOB_NAME"'".script]
| add | map([@sh "print_cmd \(.)", "\(.)"])
| if (. | length) != 0 then (. | add | join("\n")) else "" end'
)")
CITBX_JOB_SCRIPT="'${CITBX_JOB_SCRIPT_PARTS[*]//\'/\'\\\'\'}'"
# Git SHA1
CI_COMMIT_REF_NAME=${CI_COMMIT_REF_NAME:-$(cd $CI_PROJECT_DIR && git rev-parse --abbrev-ref HEAD)}
CITBX_JOB_DOCKER_RUN_ARGS+=(-e CI_COMMIT_REF_NAME="$CI_COMMIT_REF_NAME")
# If not set, fill the CI_SERVER_TLS_CA_FILE with local CA certificates
if ! [[ -v CITBX_TLS_CA_SEARCH_DIR_LIST ]]; then
CITBX_TLS_CA_SEARCH_DIR_LIST=("/usr/local/share/ca-certificates/")
fi
if ! [[ -v CI_SERVER_TLS_CA_FILE ]]; then
CI_SERVER_TLS_CA_FILE="$(
for dir in "${CITBX_TLS_CA_SEARCH_DIR_LIST[@]}"; do
test ! -d "$dir" \
|| find "$dir" -iregex '.*\.\(pem\|crt\)$' -exec openssl x509 -in '{}' \;
done
)"
fi
# Add variable to the environment list
citbx_export CI_JOB_NAME \
CI_REGISTRY \
CI_PROJECT_DIR \
CI_SERVER_TLS_CA_FILE \
CITBX_SCRIPTS_DIR \
CITBX_MODULES_DIR \
CITBX_JOBS_DIR
if [ "$CITBX_DEBUG_SCRIPT_ENABLED" == "true" ]; then
citbx_before_script="set -x"
citbx_after_script="set +x"
else
citbx_before_script=""
citbx_after_script=""
fi
# Run the job setup hooks
for hook in $citbx_job_stage_setup; do
$citbx_before_script
$hook
$citbx_after_script
done
CITBX_SCRIPT_COMMON='
_which() {
for p in $(echo "$PATH" | tr : \ ); do
if [ -x "$p/$1" ]; then
echo "$p/$1"
return 0
fi
done
return 1
}
if ! SHELL="$(_which bash || _which sh)"; then
echo shell not found
exit 1
fi
'
case "$CITBX_JOB_EXECUTOR" in
shell)
print_info "Running the job \"$CI_JOB_NAME\" into the shell..."
(
unset CITBX
export GITLAB_CI=true
for e in ${CITBX_ENV_EXPORT_LIST[@]}; do
export $e
done
for e in "${CITBX_JOB_VARIABLE_LIST[@]}"; do
export $e
done
# Shell selector (like the gitlab-runner one) will try to find bash, otherwise sh
eval "$CITBX_SCRIPT_COMMON"'$SHELL -c '"$CITBX_JOB_SCRIPT"
)
;;
docker)
# Setup docker environment
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"
case "$CITBX_DOCKER_AUTH_CONFIG_MODE" in
environment)
citbx_export DOCKER_AUTH_CONFIG
;;
mount-ro|mount-rw)
if [ -f "$HOME/.docker/config.json" ]; then
CITBX_JOB_DOCKER_RUN_ARGS+=(-v
$HOME/.docker/config.json:$HOME/.docker/config.json:${CITBX_DOCKER_AUTH_CONFIG_MODE##mount-})
if [ "$CITBX_UID" -ne 0 ]; then
CITBX_DOCKER_SCRIPT_PARTS+=("
# Fix permission on the $HOME/.docker
chown $CITBX_UID:$CITBX_UID $HOME/.docker
")
fi
fi
;;
esac
CITBX_DOCKER_SCRIPT_PARTS+=("$CITBX_SCRIPT_COMMON"'
# PATH environment variable propagation
echo "ENV_PATH PATH=$PATH" >> /etc/login.defs
echo "ENV_SUPATH PATH=$PATH" >> /etc/login.defs
')
if [ "$CITBX_UID" -ne 0 ]; then
CITBX_USER=$USER
if [ "$CITBX_DOCKER_USER" == "root" ]; then
CITBX_DOCKER_SCRIPT_PARTS+=('
# _adduser <name> <uid> <home>
if _which useradd > /dev/null 2>&1; then
_adduser() {
useradd -o -u $2 -s /bin/sh -d $3 -M $1
}
elif _which busybox > /dev/null 2>&1; then
_adduser() {
busybox adduser -u $2 -s /bin/sh -h $3 -H -D $1
}
else
echo "[!!] No usual tool found to add an user"
exit 1
fi
# _adduser2group <user> <group>
if _which usermod > /dev/null 2>&1; then
_adduser2group() {
usermod -a -G $2 $1
}
elif _which busybox > /dev/null 2>&1; then
_adduser2group() {
addgroup $1 $2 > /dev/null
}
else
echo "[!!] No usual tool found to add an user to a group"
exit 1
fi
# Add the user
_adduser '"$CITBX_USER"' '"$CITBX_UID"' '"$HOME"'
# Fix rights on HOME directory
chown '"$CITBX_UID"':'"$CITBX_UID"' '"$HOME"'
# Add user to the suitable groups
for group in '"${CITBX_USER_GROUPS[*]}"'; do
if grep -q ^$group /etc/group; then
_adduser2group '"$CITBX_USER"' $group
fi
done
# Add sudoers suitable rule
if [ -f /etc/sudoers ]; then
sed -i "/^'"$CITBX_USER"' /d" /etc/sudoers
echo "'"$CITBX_USER"' ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
fi
')
fi
else
CITBX_USER=root
fi
# Shell selector (like the gitlab-runner one) will try to find bash, otherwise sh
CITBX_DOCKER_SCRIPT_PARTS+=('su '"$CITBX_USER"' -s "$SHELL"')
if [ "$CITBX_RUN_SHELL" != "true" ]; then
CITBX_DOCKER_SCRIPT_PARTS+=("-c $CITBX_JOB_SCRIPT")
fi
if [ -n "$CITBX_DOCKER_USER" ]; then
CITBX_JOB_DOCKER_RUN_ARGS+=(-u "$CITBX_DOCKER_USER")
fi