dk: support COMPOSER_SETUP et COMPOSER_CMD

This commit is contained in:
Jephté Clain 2019-10-03 15:58:07 +04:00
parent 921caa1acc
commit c202a279dd
1 changed files with 144 additions and 52 deletions

174
dk
View File

@ -140,17 +140,36 @@ COMMANDES
Frontend pour lancer composer à l'intérieur d'un container. Les Frontend pour lancer composer à l'intérieur d'un container. Les
commandes 'ci', 'cu' et 'cs' sont respectivement des alias pour commandes 'ci', 'cu' et 'cs' sont respectivement des alias pour
'composer install', 'composer update' et 'composer shell' 'composer install', 'composer update' et 'composer shell'
Le répertoire \$HOME est monté à l'intérieur du container et le script S'il existe un fichier .composer.conf dans le répertoire du projet, il
composer.phar du projet est utilisé le cas échéant. est sourcé. Ce fichier définit des variables qui indiquent comment la
L'image utilisée pour lancer composer est indiquée par la variable commande composer est lancée. Les variables suivantes peuvent être
d'environnement COMPOSER_IMAGE et vaut par défaut: définies:
* COMPOSER_IMAGE -- Image utilisée pour lancer composer.
L'image spécifiée doit disposer de la commande 'su-exec' afin de
pouvoir lancer la commande avec l'utilisateur courant. Le répertoire
\$HOME est monté à l'intérieur du container et le script composer.phar
du projet est utilisé le cas échéant.
La valeur par défaut est:
$DEFAULT_COMPOSER_IMAGE $DEFAULT_COMPOSER_IMAGE
Cette image doit disposer de la commande 'su-exec' afin de pouvoir Spécifier 'none' pour lancer directement composer sans passer par une
lancer la commande avec l'utilisateur courant. image docker.
La commande shell est une extension qui lance un shell bash au lieu de * COMPOSER_CMD -- Chemin vers l'exécutable composer. Par défaut,
utiliser composer.phar s'il existe dans le répertoire du projet. Sinon
utiliser /usr/bin/composer
* COMPOSER_SETUP -- Liste de commandes à lancer pour configurer le
container. Dans ce cas, un container ayant pour base \$COMPOSER_IMAGE
et nommé d'après le nom du projet est préparé et les commandes
spécifiées y sont lancées. Ce container est réutilisé à chaque fois.
Ce paramétrage est utilisé pour par exemple installer certains
packages nécessaire au projet.
La commande 'shell' est une extension qui lance un shell bash au lieu de
lancer la commande composer, ce qui permet de faire des opérations plus lancer la commande composer, ce qui permet de faire des opérations plus
complexes si le besoin s'en fait sentir. NB: le shell est lancé avec complexes si le besoin s'en fait sentir. NB: le shell est lancé avec
l'utilisateur root. l'utilisateur root. La commande alternative 'ushell' lance le shell avec
le compte utilisateur.
Pour faciliter l'utilisation dans un script, les premiers arguments
peuvent être utilisés pour redéfinir les variables COMPOSER_*, e.g
$scriptname composer COMPOSER_IMAGE=none install
OPTIONS générales OPTIONS générales
(ces options sont communes à toutes les commandes) (ces options sont communes à toutes les commandes)
@ -191,19 +210,21 @@ OPTIONS build
-g, --ug, --no-update-apps -g, --ug, --no-update-apps
ne pas mettre à jour les dépôts dépendants. ces dépôts sont définis dans ne pas mettre à jour les dépôts dépendants. ces dépôts sont définis dans
le fichier update-apps.conf qui a le format suivant: le fichier update-apps.conf qui a le format suivant:
DEFAULT_DEVEL_SRCDIR=
DEFAULT_ORIGIN= DEFAULT_ORIGIN=
DEFAULT_BRANCH= DEFAULT_BRANCH=
DEFAULT_DEVEL_SRCDIR= DEFAULT_COMPOSER_ACTION=
APPS=() # liste d'applications à mettre à jour APPS=() # liste d'applications à mettre à jour
app_URL= # url du dépôt app_URL= # url du dépôt
app_DEVEL_SRCDIR= # répertoire source en mode devel app_DEVEL_SRCDIR= # répertoire source en mode devel
app_DEST= # répertoire dans lequel faire le checkout app_DEST= # répertoire dans lequel faire le checkout
app_PROFILE_ORIGIN= # origine spécifique au profil 'PROFILE' app_PROFILE_ORIGIN= # origine spécifique au profil 'PROFILE'
app_PROFILE_BRANCH= # branche spécifique au profil 'PROFILE'
app_ORIGIN= # ou... origine par défaut de la branche app_ORIGIN= # ou... origine par défaut de la branche
app_PROFILE_BRANCH= # branche spécifique au profil 'PROFILE'
app_BRANCH= # ou... branche par défaut app_BRANCH= # ou... branche par défaut
app_TYPE= # type de projet (composer par défaut) app_TYPE= # type de projet (composer|none)
app_AFTER_UPDATE=() # liste de commandes à lancer après le checkout app_AFTER_UPDATE=() # liste de commandes à lancer après le checkout
app_COMPOSER_ACTION= # action projet composer (install|update|none)
-u, --uu, --update-apps-only -u, --uu, --update-apps-only
Ne faire que la mise à jour depuis les dépôts dépendants. Ne faire que la mise à jour depuis les dépôts dépendants.
-w, --ww, --update-apps-devel -w, --ww, --update-apps-devel
@ -231,7 +252,7 @@ VARIABLES de update-apps.conf
vaut 'develop' par défaut vaut 'develop' par défaut
TYPE TYPE
vaut 'composer' par défaut si le fichier composer.json existe à la vaut 'composer' par défaut si le fichier composer.json existe à la
racine du projet. sinon vaut 'inconnu' par défaut racine du projet. sinon vaut 'none' par défaut
AFTER_UPDATE AFTER_UPDATE
Cette variable est une liste de commandes à lancer après la maj du dépôt Cette variable est une liste de commandes à lancer après la maj du dépôt
- si le chemin est absolu ou relatif, lancer la commande telle quelle - si le chemin est absolu ou relatif, lancer la commande telle quelle
@ -242,9 +263,9 @@ VARIABLES de update-apps.conf
URL= # url du dépôt URL= # url du dépôt
DEVEL_SRCDIR= # répertoire source en mode devel DEVEL_SRCDIR= # répertoire source en mode devel
DEST= # répertoire dans lequel faire le checkout DEST= # répertoire dans lequel faire le checkout
ORIGIN= # ou... origine par défaut de la branche ORIGIN= # origine de la branche
BRANCH= # ou... branche par défaut BRANCH= # branche sélectionnée dans le dépôt
TYPE= # type de projet (composer par défaut) TYPE= # type de projet (composer|none)
COMPOSER_ACTION COMPOSER_ACTION
vaut 'install' par défaut. Indique ce qu'il faut faire pour un projet de vaut 'install' par défaut. Indique ce qu'il faut faire pour un projet de
type 'composer' après avoir lancé les commandes de AFTER_UPDATE. Les type 'composer' après avoir lancé les commandes de AFTER_UPDATE. Les
@ -267,8 +288,8 @@ FONCTIONS de update-apps.conf
déploiement SRC au profil pff 'DEST' déploiement SRC au profil pff 'DEST'
- Une valeur de la forme 'DEST' force le choix du profil pff DEST quel - Une valeur de la forme 'DEST' force le choix du profil pff DEST quel
que soit le profil de déploiement que soit le profil de déploiement
- La valeur par défaut si aucun profil de déploiement ne correspond est Si aucun profil de déploiement ne correspond, le comportement par défaut
de forcer le premier profil défini" est de forcer le premier profil défini dans le projet pff"
} }
function echo_lines() { local IFS=$'\n'; echo "$*"; } function echo_lines() { local IFS=$'\n'; echo "$*"; }
@ -613,7 +634,7 @@ function build_update_apps() {
# possible de détecter le type quand on a le projet # possible de détecter le type quand on a le projet
# en cas de maj ici, mettre à jour aussi le code ci-dessous # en cas de maj ici, mettre à jour aussi le code ci-dessous
if [ -f "$DEST/composer.json" ]; then TYPE=composer if [ -f "$DEST/composer.json" ]; then TYPE=composer
else TYPE=inconnu else TYPE=none
fi fi
fi fi
@ -649,7 +670,7 @@ function build_update_apps() {
# possible de détecter le type quand on a le projet # possible de détecter le type quand on a le projet
# en cas de maj ici, mettre à jour aussi le code ci-dessus # en cas de maj ici, mettre à jour aussi le code ci-dessus
if [ -f "$DEST/composer.json" ]; then TYPE=composer if [ -f "$DEST/composer.json" ]; then TYPE=composer
else TYPE=inconnu else TYPE=none
fi fi
fi fi
fi fi
@ -669,9 +690,6 @@ function build_update_apps() {
[ -n "$composer_action" ] || { composer_action="${var}_COMPOSER_ACTION"; composer_action="${!composer_action}"; } [ -n "$composer_action" ] || { composer_action="${var}_COMPOSER_ACTION"; composer_action="${!composer_action}"; }
[ -n "$composer_action" ] || composer_action="$DEFAULT_COMPOSER_ACTION" [ -n "$composer_action" ] || composer_action="$DEFAULT_COMPOSER_ACTION"
composer=/usr/bin/composer
[ -x "$DEST/composer.phar" ] && composer="$DEST/composer.phar"
if [ -z "$BUILD_UPDATE_DEVEL" ]; then if [ -z "$BUILD_UPDATE_DEVEL" ]; then
case "${composer_action:-install}" in case "${composer_action:-install}" in
i|install) composer_action=install;; i|install) composer_action=install;;
@ -680,8 +698,11 @@ function build_update_apps() {
*) ewarn "$composer_action: action invalide"; composer_action=;; *) ewarn "$composer_action: action invalide"; composer_action=;;
esac esac
if [ -n "$composer_action" ]; then if [ -n "$composer_action" ]; then
setx cwd=pwd
cd "$DEST"
estep "Installation des dépendances composer" estep "Installation des dépendances composer"
"$composer" -d"$DEST" "$composer_action" ${PRODUCTION:+--no-dev -o} || { eend; return 1; } auto_composer "$composer_action" ${PRODUCTION:+--no-dev -o} || { eend; return 1; }
cd "$cwd"
fi fi
fi fi
fi fi
@ -1208,26 +1229,58 @@ EOF
} }
function auto_composer() { function auto_composer() {
local -a replace_env_args env_args local COMPOSER_IMAGE="$DEFAULT_COMPOSER_IMAGE"
if [ -f docker-compose.yml ]; then compose_set_env_args local COMPOSER_CMD=
else docker_set_env_args local COMPOSER_SETUP=
[ -f .composer.conf ] && source ./.composer.conf
# les premiers arguments peuvent service à redéfinir les variables
while [ $# -gt 0 ]; do
case "$1" in
COMPOSER_IMAGE=*) setv "$1"; shift;;
COMPOSER_CMD=*) setv "$1"; shift;;
COMPOSER_SETUP=*) setv "$1"; shift;;
*) break;;
esac
done
if [ "$COMPOSER_IMAGE" == none ]; then
# lancement direct
case "$1" in
rootshell|shell|rootbash|bash)
# ewarn parce qu'on est pas root dans ce shell contrairement à ce qui est demandé
ewarn "Lancement d'un shell utilisateur"
bash "$@"
;;
usershell|ushell|userbash|ubash)
estep "Lancement d'un shell utilisateur"
bash "$@"
;;
*)
if [ -n "$COMPOSER_CMD" ]; then :
elif [ -x composer.phar ]; then COMPOSER_CMD=./composer.phar
elif [ -x /usr/bin/composer ]; then COMPOSER_CMD=/usr/bin/composer
else
eerror "Impossible de trouver composer"
return 1
fi
"$COMPOSER_CMD" "$@"
;;
esac
return $?
fi fi
local user group projdir local user group projdir actualcmd args
local actualcmd args
setx user=id -un; setx user=getent passwd "$user" setx user=id -un; setx user=getent passwd "$user"
setx group=id -gn; setx group=getent group "$group" setx group=id -gn; setx group=getent group "$group"
setx projdir=pwd setx projdir=pwd
case "$1" in case "$1" in
rootshell|shell|rootbash|bash) rootshell|shell|rootbash|bash)
shift
actualcmd='eval "bash $args"' actualcmd='eval "bash $args"'
shift
;; ;;
usershell|ushell|userbash|ubash) usershell|ushell|userbash|ubash)
shift
actualcmd='eval "su-exec \"$user\" bash $args"' actualcmd='eval "su-exec \"$user\" bash $args"'
shift
;; ;;
*) *)
actualcmd='eval "su-exec \"$user\" \"$composer\" $args"' actualcmd='eval "su-exec \"$user\" \"$composer\" $args"'
@ -1235,13 +1288,13 @@ function auto_composer() {
esac esac
setx args=qvals "$@" setx args=qvals "$@"
local -a cmd local -a basecmd cmd setupscript runscript
cmd=( basecmd=(
docker run -it --rm
-e user="$user" -e user="$user"
-e group="$group" -e group="$group"
-e home="$HOME"
-e projdir="$projdir" -e projdir="$projdir"
-e setup="$COMPOSER_SETUP"
-e composer="$COMPOSER_CMD"
-e args="$args" -e args="$args"
-v "$HOME:$HOME" -v "$HOME:$HOME"
) )
@ -1249,20 +1302,59 @@ function auto_composer() {
# si le répertoire de projet ne se trouve pas dans $HOME, le monter aussi # si le répertoire de projet ne se trouve pas dans $HOME, le monter aussi
cmd+=(-v "$projdir:$projdir") cmd+=(-v "$projdir:$projdir")
fi fi
cmd+=( setupscript='eval "$setup"'
"${COMPOSER_IMAGE:-$DEFAULT_COMPOSER_IMAGE}" runscript='
bash -c '
echo "$user" >>/etc/passwd; user="${user%%:*}" echo "$user" >>/etc/passwd; user="${user%%:*}"
echo "$group" >>/etc/group; group="${group%%:*}" echo "$group" >>/etc/group; group="${group%%:*}"
cd "$projdir" cd "$projdir"
if [ -x composer.phar ]; then composer=./composer.phar if [ -n "$composer" ]; then :
elif [ -x composer.phar ]; then composer=./composer.phar
elif [ -x /usr/bin/composer ]; then composer=/usr/bin/composer elif [ -x /usr/bin/composer ]; then composer=/usr/bin/composer
else else
echo "ERROR: unable to find composer" echo "ERROR: Impossible de trouver composer"
exit 1 exit 1
fi fi
'"$actualcmd" '"$actualcmd"
if [ -n "$COMPOSER_SETUP" ]; then
# lancement dans un container docker à préparer
local NAME project_name container_name dkid
if [ -f docker-compose.yml ]; then
compose_set_project_name set_container_name
else
NAME="$(basename -- "$(pwd)")"
docker_check_name set_container_name
fi
container_name="dk_composer_${container_name}"
# vérifier l'existence de l'image
setx dkid=docker image ls --format '{{.ID}}' "${container_name}_image"
# créer le container le cas échéant
if [ -z "$dkid" ]; then
estep "Création du container $container_name avec l'image $COMPOSER_IMAGE"
cmd=(
docker create -it --name "${container_name}_ct"
"${basecmd[@]}"
"$COMPOSER_IMAGE"
bash -c "$setupscript"
)
setx dkid="${cmd[@]}" || return 1
docker container start -ai "$dkid" || return 1
docker container commit "$dkid" "${container_name}_image" || return 1
docker container rm "$dkid" || return 1
fi
# prendre comme image le container créé
COMPOSER_IMAGE="${container_name}_image"
fi
cmd=(
docker run -it --rm
"${basecmd[@]}"
"$COMPOSER_IMAGE"
bash -c "$runscript"
) )
"${cmd[@]}" "${cmd[@]}"
} }