nutools/dk

2118 lines
75 KiB
Plaintext
Raw Normal View History

#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source "$(dirname "$0")/lib/ulib/auto" || exit 1
2020-03-26 16:40:37 +04:00
urequire pff json
function display_help() {
uecho "$scriptname: outil pour faciliter l'utilisation de docker
USAGE
$scriptname CMDs...
2020-03-20 22:51:05 +04:00
Si une commande commence ou se termine par un underscore, e.g '_ls', elle est
passée telle quelle à docker (en enlevant l'underscore d'abord, bien sûr). Si
une commande ne figure pas dans la liste ci-dessous, elle est passée telle
quelle à docker.
Certaines commandes ci-dessous ont le même nom que des commandes docker, et
nécessitent un projet docker ou docker-compose. Si ces commandes sont lancées
alors qu'on n'est pas dans un projet docker, alors elles sont passées telle
quelles à docker. ATTENTION: comme la commande est exécutée par docker, cela
veut dire qu'elle n'aura pas la même sématique.
COMMANDES
2019-11-21 08:55:09 +04:00
get-profile
Afficher le profil courant
2019-06-01 14:34:20 +04:00
b|build [SERVICE]
2019-03-28 10:53:50 +04:00
Construire les images
2019-06-01 14:34:20 +04:00
p|push
p|push [SERVICES...]
La première syntaxe est utilisable avec un projet docker. Elle permet de
pousser l'image qui a été construite avec build vers le serveur
La deuxième syntaxe est utilisée avec un projet docker-compose. Elle
permet de pousser les images correspondant aux services qui ont été
construit vers le serveur.
2019-06-24 23:57:02 +04:00
s|start [SERVICE]
2019-03-28 10:53:50 +04:00
Démarrer le(s) service(s)
2019-06-01 14:34:20 +04:00
k|stop [SERVICE]
2019-03-28 10:53:50 +04:00
Arrêter le(s) service(s)
2019-06-01 14:34:20 +04:00
1|up
2019-03-28 10:53:50 +04:00
Créer l'environnement, démarrer les services et suivre les logs de façon
interactive.
2019-06-01 14:34:20 +04:00
Vaguement équivalent à -- start -- logs
l|logs [SERVICE]
2019-03-28 10:53:50 +04:00
Afficher les logs
2019-06-01 14:34:20 +04:00
0|down
2019-03-28 10:53:50 +04:00
Arrêter les services et supprimer l'environnement
2019-06-24 23:57:02 +04:00
r|run SERVICE [COMMAND]
Démarrer le service en mode interactif avec la commande spécifiée
Les options suivantes sont supportées, mais il faut les spécifier avant
SERVICE:
* pour docker et docker-compose: --volume
* uniquement pour docker-compose: --detach, -e, --label, --no-deps,
--service-ports, --use-aliases
Par défaut, --rm est activé; utiliser --no-rm pour ne pas supprimer le
container après utilisation.
2019-06-24 23:57:02 +04:00
x|exec SERVICE COMMAND
Lancer une commande dans le container correspondant au service spécifié,
qui doit être en fonctionnement
2019-06-01 14:34:20 +04:00
d|brd
2019-03-28 10:53:50 +04:00
Construire les images (comme avec build), démarrer les services et
suivre les logs de façon interactive (comme avec up). Dès que l'on
arrête l'affichage des logs avec Ctrl+C, arrêter les services et
supprimer l'environnement (comme avec down)
2019-06-01 14:34:20 +04:00
Vaguement équivalent à -- build -- start [args] -- logs
suivi de -- down
2018-12-09 22:33:07 +04:00
bs
2019-03-28 10:53:50 +04:00
Construire les images (comme avec build) puis démarrer les services
(comme avec start)
2019-06-01 14:34:20 +04:00
Equivalent à -- build -- start [args]
2019-06-24 23:57:02 +04:00
br SERVICE [COMMAND]
Construire les images (comme avec build) puis démarrer le service avec
la commande spécifiée (comme avec run)
Equivalent à -- build -- run [args]
2019-06-05 10:13:20 +04:00
y|deploy [args...]
(Re)déployer un stack. Cette commande ne fonctionne qu'en mode swarm.
Implique --stack
by|bd [args...]
Equivalent à --stack -- build -- deploy args...
2019-06-01 14:34:20 +04:00
Utilisable notamment en développement
2019-06-05 10:13:20 +04:00
bp [args...]
Equivalent à --stack -- build -- push args...
bpy|bpd [args...]
Equivalent à --stack -- build -- push -- deploy args...
2020-03-20 22:51:05 +04:00
ser|service COMMAND SERVICE [args...]
2019-06-05 10:13:20 +04:00
Frontend pour 'docker service COMMAND args... SERVICE'
Cette commande ne fonctionne qu'en mode swarm. Il n'est pas nécessaire
de préfixer le nom du service avec le nom du stack, pour être cohérent
avec les autres commandes
IMPORTANT: notez que les arguments sont placés avant le nom du service.
Celà signifie qu'on ne peut spécifier que des options à la commande.
Penser aussi à protéger ces options de l'analyse eg.
$scriptname -- service logs web -f
Pour des cas d'utilisation plus complexe, il faut lancer directement
docker service
sta|status [SERVICE] [num]
2020-03-26 16:40:37 +04:00
Afficher le status du service spécifié: pour chaque occurence, sur quel
noeud il tourne (ou tournait), quel est le statut actuel ainsi que le
message associé. Si le service n'est pas spécifié, prendre la liste des
services affichée par docker service ls
2020-03-26 16:40:37 +04:00
'num' est le numéro de l'instance de service. Si ce numéro est précisé,
afficher les informations uniquement pour cette instance là, ainsi que
les logs
Il est possible de spécifier un filtre docker name=value avant 'num'. Ce
filtre est utilisé pour sélectionner certaines instances du service.
- id=<ID> a task's ID ou prefix
- name=<string> a task's name or prefix
- node=<string> a node's name or ID
- desired-state=(running|shutdown|accepted)
2019-06-05 10:13:20 +04:00
u|update SERVICE [args...]
Mettre à jour un service, équivalent à 'service update SERVICE'
scale SERVICE=REPLICAS [args...]
Mettre à jour le nom de réplicas d'un service, équivalent à la commande
'service scale SERVICE=REPLICAS'
2019-06-01 14:34:20 +04:00
ip|show-ip [SERVICE]
2019-04-17 02:31:09 +04:00
Afficher l'adresse IP interne du service
2019-06-01 14:34:20 +04:00
systemd|systemd-unit
2019-04-10 07:25:20 +04:00
Générer une unité systemd qui démarre les services. A priori, ce n'est
nécessaire que si aucune politique de redémarrage n'a été définie.
ps [filter|name=value]
2019-03-28 10:53:50 +04:00
Afficher les containers en cours d'exécution
Le filtre est une expression régulière de type awk qui est mise en
2020-03-26 16:40:37 +04:00
correspondance avec les noms de l'image et de la tâche.
Il est aussi possible d'utiliser un filtre docker de la forme name=value
- ancestor=(<image-name>[:tag]|<image-id>| <image@digest>)
containers created from an image or a descendant.
- before=(<container-name>|<container-id>)
- expose=(<port>[/<proto>]|<startport-endport>/[<proto>])
- exited=<int> an exit code of <int>
- health=(starting|healthy|unhealthy|none)
- id=<ID> a container's ID
- is-task=(true|false)
- label=<key> or label=<key>=<value>
- name=<string> a container's name
- network=(<network-id>|<network-name>)
- publish=(<port>[/<proto>]|<startport-endport>/[<proto>])
- since=(<container-name>|<container-id>)
- status=(created|restarting|removing|running|paused|exited)
- volume=(<volume name>|<mount point destination>)
ls [filter|name=value]
2019-03-28 10:53:50 +04:00
Lister les images actuellement présentes
Le filtre est une expression régulière de type awk qui est mise en
correspondance avec le nom de l'image. Un suffixe :tag permet de ne
sélectionner que les images correspondant au filtre qui ont le tag
spécifié.
Il est aussi possible d'utiliser un filtre docker de la forme name=value
- dangling=(true|false) - find unused images
- label=<key> or label=<key>=<value>
- before=(<image-name>[:tag]|<image-id>| <image@digest>)
- since=(<image-name>[:tag]|<image-id>| <image@digest>)
- reference=(pattern of an image reference)
pull filter
Mettre à jour une ou plusieurs images
Le filtre est une expression régulière de type awk qui est mise en
correspondance avec le nom de l'image. Un suffixe :tag permet de ne
sélectionner que les images correspondant au filtre qui ont le tag
spécifié.
rm filter
Supprimer une ou plusieurs images
Le filtre est une expression régulière de type awk qui est mise en
correspondance avec le nom de l'image. Un suffixe :tag permet de ne
sélectionner que les images correspondant au filtre qui ont le tag
spécifié.
2019-06-01 14:34:20 +04:00
X|prune
2019-03-28 10:53:50 +04:00
Supprimer les containers et les images inutilisées
2020-01-22 10:47:14 +04:00
composer|ci|cu|cr|cs [args...]
2019-10-02 22:16:40 +04:00
Frontend pour lancer composer à l'intérieur d'un container. Les
2020-01-22 10:47:14 +04:00
commandes 'ci', 'cu', 'cr', 'cs' sont des alias pour 'composer install',
'composer update', 'composer rshell' et 'composer shell' respectivement
S'il existe un fichier .composer.conf dans le répertoire du projet, il
est sourcé. Ce fichier définit des variables qui indiquent comment la
commande composer est lancée. Les variables suivantes peuvent être
définies:
2020-01-22 10:47:14 +04:00
* COMPOSER_PHP -- Version de PHP en dessous de laquelle COMPOSER_IMAGE
2020-01-22 13:56:34 +04:00
est utilisé. En d'autres termes, c'est la version minimum de PHP
nécessaire pour faire tourner composer. L'idée est que si la version
de PHP installée est suffisante, il n'est pas nécessaire de passer par
une image docker.
2020-01-22 10:47:14 +04:00
Cette valeur doit être spécifiée avec le format de PHP_VERSION_ID i.e
70300 pour PHP 7.3
Spécifier 'any' ou 'force' pour forcer l'utilisation de l'image docker
2020-01-30 14:32:44 +04:00
* COMPOSER_PHP_MAX -- Version de PHP à partir de laquelle COMPOSER_IMAGE
est utilisée. En d'autres termes, c'est la version maximum de PHP, à
partir de laquelle il faut passer par une image docker. L'idée est que
si la version de PHP installée est trop récente, ça peut poser
problème avec le calcul des dépendances.
Cette valeur doit être spécifiée avec le format de PHP_VERSION_ID i.e
70300 pour PHP 7.3
Si la valeur n'est pas spécifiée ou vaut 'none', elle est ignorée.
* COMPOSER_IMAGE -- Image utilisée pour lancer composer. La valeur par
défaut est:
$DEFAULT_COMPOSER_IMAGE
Spécifier 'none' pour lancer directement composer sans passer par une
image docker.
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.
* COMPOSER_MACHINE -- Nom de la docker machine sur laquelle se connecter
pour lancer l'image docker. La valeur par défaut est -u, ce qui force
l'utilisation de l'instance docker locale.
* 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.
2020-01-22 10:47:14 +04:00
La commande 'rshell' est une extension qui lance un shell bash au lieu
de 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 l'utilisateur root. La commande alternative 'shell' 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
2019-10-02 22:04:10 +04:00
2019-04-02 15:59:47 +04:00
OPTIONS générales
(ces options sont communes à toutes les commandes)
-d, --chdir PROJDIR
Spécifier le répertoire du projet
2019-06-11 08:18:43 +04:00
-c, --config CONFIG[.yml]
Spécifier le fichier de configuration à utiliser. le fichier de profil
2019-06-11 08:18:43 +04:00
CONFIG.PROFILE.yml est chargé aussi s'il existe.
NB: il n'est pas nécessaire d'ajouter l'extension .yml au nom, cela
permet de faciliter l'utilisation avec l'auto-complétion quand il existe
des fichiers de profil
Si cette option n'est pas spécifiée, docker-compose.yml est utilisé par
défaut (ou avec l'option --stack docker-stack.yml s'il existe)
-p, --profile PROFILE
-P, --prod
-T, --test
Spécifier le profil
-m, --set-machine MACHINE
Choisir l'environnement docker-machine spécifié avant de lancer les
2019-10-02 22:04:10 +04:00
commandes. Utiliser -u pour desélectionner la machine en cours, e.g -m-u
2018-11-22 15:34:07 +04:00
-n, --fake
Ne pas lancer les commandes, simplement les afficher
2020-02-14 11:18:32 +04:00
-e, --build-arg, --env VAR=VALUE
(Re)définir un argument pour le build ou une variable d'environnement
-f, --force
Forcer l'opération (là où cela a du sens)
2019-04-02 15:59:47 +04:00
-h, --host HOST
Spécifier l'hôte pour la commande systemd-unit
2019-04-02 15:59:47 +04:00
OPTIONS build
2019-06-01 14:34:20 +04:00
(ces options ne sont valides que pour les commandes build, brd, bs, bd, bpd)
--stack
Indiquer que le build est fait pour un déploiement avec deploy.
2019-06-05 10:13:20 +04:00
S'il existe un fichier docker-stack.yml, il est utilisé de préférence à
la place de docker-compose.yml. De même, les fichiers de profil de la
forme docker-stack.PROFILE.yml sont utilisés de préférence aux fichiers
docker-compose.PROFILE.yml
Cette option n'est nécessaire qu'avec build puisque les commandes
deploy, bd, bpd et update impliquent --stack
-j, --no-cache
Ne pas utiliser le cache lors du build
2019-04-02 15:59:47 +04:00
-g, --ug, --no-update-apps
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:
DEFAULT_DEVEL_SRCDIR=
DEFAULT_ORIGIN=
2019-04-02 15:59:47 +04:00
DEFAULT_BRANCH=
DEFAULT_COMPOSER_ACTION=
PROFILE_CLEAN= # fonction de nettoyage spécifique au profil
CLEAN= # ou... fonction de nettoyage par défaut
APPS=() # applications à mettre à jour par défaut
PROFILE_APPS=() # ou... spécifique au profil 'PROFILE'
app_URL= # url du dépôt
app_DEVEL_SRCDIR= # répertoire source en mode devel
app_DEST= # répertoire dans lequel faire le checkout
app_PROFILE_ORIGIN= # origine spécifique au profil 'PROFILE'
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_TYPE= # type de projet (composer|none)
app_AFTER_UPDATE=() # liste de commandes à lancer après le checkout
app_COMPOSER_ACTION= # action projet composer (install|update|none)
2019-04-02 15:59:47 +04:00
-u, --uu, --update-apps-only
Ne faire que la mise à jour depuis les dépôts dépendants.
-w, --ww, --update-apps-devel
Faire la mise à jour en mode devel: le projet ainsi que ses fichiers des
répertoires vendor/lib et vendor/ur sont synchronisés via rsync depuis
\$DEFAULT_DEVEL_SRCDIR qui vaut par défaut \$HOME/wop/php
2019-04-02 15:59:47 +04:00
--uo, --update-apps-origin ORIGIN
Spécifier l'origine par défaut pour update-apps
--ub, --update-apps-branch BRANCH
Spécifier la branche par défaut pour update-apps
2019-06-01 14:34:20 +04:00
OPTIONS deploy
-l, --without-registry-auth
Ne pas transporter les informations d'autorisation aux agents swarm
(c'est à dire ne pas utiliser l'option --with-registry-auth)
VARIABLES de update-apps.conf
DEVEL_SRCDIR
répertoire source pour le mode devel. attention, il s'agit du répertoire
du projet, alors que DEFAULT_DEVEL_SRCDIR est le répertoire de base par
défaut des projets
ORIGIN
vaut 'origin' par défaut
BRANCH
vaut 'develop' par défaut
TYPE
vaut 'composer' par défaut si le fichier composer.json existe à la
racine du projet. sinon vaut 'none' par défaut
AFTER_UPDATE
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
- s'il n'y a pas de chemin, alors ce doit être le nom d'une fonction
existante auquel on enlève le préfixe update_apps_func_
2019-09-18 10:57:12 +04:00
Au moment où la commande est lancée, le répertoire courant est celui du
projet. Les variables suivantes sont disponibles:
URL= # url du dépôt
DEVEL_SRCDIR= # répertoire source en mode devel
DEST= # répertoire dans lequel faire le checkout
ORIGIN= # origine de la branche
BRANCH= # branche sélectionnée dans le dépôt
TYPE= # type de projet (composer|none)
COMPOSER_ACTION
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
2019-12-03 06:39:00 +04:00
directives supportées sont 'install', 'update' et 'none'
FONCTIONS de update-apps.conf
sqlmig [DESTDIR [SRCDIR [NOFIX]]]
Copier les définitions des bases de données au format sqlmig de
SRCDIR/config/sqlmig vers DESTDIR/config/mariadb/sqlmig
Si SRCDIR ne se termine pas par '/config/sqlmig' ou si DESTDIR ne se
termine pas par '/config/mariadb/sqlmig', rajouter ces suffixes
2019-09-18 10:57:12 +04:00
automatiquement, sauf si une valeur NOFIX est spécifiée.
pff [MAPS [PFFDIR]]
Si PFFDIR est un projet pff, mettre à jour le profil pff en fonction du
profil de déploiement.
MAPS détermine le mapping entre profil de déploiement (prod, test,
devel) et le profil pff. Il s'agit d'une liste de valeurs séparées par
des virgules de la forme DEST[:SRC]
- Une valeur de la forme 'DEST:SRC' fait correspondre le profil de
déploiement SRC au profil pff 'DEST'
- Une valeur de la forme 'DEST' force le choix du profil pff DEST quel
que soit le profil de déploiement
- Pour simplifier l'écriture des mappings, les aliases suivants sont
reconnus:"'
PTD est remplacé par prod:prod,test:test,devel:devel
PT " " " prod:prod,test:test
'"Si aucun profil de déploiement ne correspond, le comportement par défaut
est de forcer le premier profil défini dans le projet pff"
}
function echo_lines() { local IFS=$'\n'; echo "$*"; }
function get_version() {
local GIT_DIR; unset GIT_DIR
if git rev-parse --git-dir >/dev/null 2>&1; then
local head commit tag
commit="$(git rev-list --tags --max-count=1 2>/dev/null)"
if [ -n "$commit" ]; then
tag="$(git describe --tags "$commit" 2>/dev/null)"
if [ -n "$tag" ]; then
head="$(git rev-parse HEAD)"
if [ "$commit" != "$head" ]; then
echo "$tag-develop"
else
echo "$tag"
fi
return
fi
fi
elif [ -f VERSION.txt ]; then
cat VERSION.txt
fi
echo develop
}
function docker_add_build_arg() {
eval "replace_build_args+=(--build-arg $1=\"$2\"); $1=\"$2\""
}
function docker_parse_build_args() {
cat "$1" |
grep -v '^#' |
grep -v '^$' |
sed -r 's/([^=]+)=(.*)/\1=\2; replace_build_args+=(--build-arg \1="$\1")/'
}
function docker_parse_env_args() {
[ -f .build.env ] && eval "$(docker_parse_build_args .build.env)"
[ -f build.env ] && eval "$(docker_parse_build_args build.env)"
2018-11-16 14:16:16 +04:00
[ -n "$PROFILE" -a -f ".build.$PROFILE.env" ] && eval "$(docker_parse_build_args ".build.$PROFILE.env")"
2020-02-14 11:18:32 +04:00
[ -n "$PROFILE" -a -f "build.$PROFILE.env" ] && eval "$(docker_parse_build_args "build.$PROFILE.env")"
}
function docker_set_env_args() {
[ -f .build.env ] && source ./.build.env
[ -f build.env ] && source ./build.env
2018-11-16 14:16:16 +04:00
[ -n "$PROFILE" -a -f ".build.$PROFILE.env" ] && source "./.build.$PROFILE.env"
2020-02-14 11:18:32 +04:00
[ -n "$PROFILE" -a -f "build.$PROFILE.env" ] && source "./build.$PROFILE.env"
}
function docker_set_run_args() {
replace_run_args+=(--env-file "$1")
source "$1"
}
function docker_check_name() {
[ -n "$NAME" ] || die "Vous devez définir NAME dans .build.env"
2018-11-22 15:34:07 +04:00
if [ "$1" == set_container_name ]; then
project_name="$NAME"
container_name="${project_name//[^a-zA-Z0-9_-]/}"
[ -n "$PROFILE" ] && container_name="${container_name}_$PROFILE"
fi
}
2019-06-01 14:34:20 +04:00
function compose_set_project_name() {
local PROJECT_NAME= PROJECT_NAME_REMOVE_SUFFIX=.service PROJECT_NAME_ADD_PROFILE=
[ -f .compose.env ] && source ./.compose.env
[ -n "$PROJECT_NAME" ] || PROJECT_NAME="$(basename -- "$(pwd)")"
PROJECT_NAME="${PROJECT_NAME%$PROJECT_NAME_REMOVE_SUFFIX}"
2018-11-16 14:16:16 +04:00
if [ -n "$PROFILE" ]; then
[ -n "$COMPOSE_PROJECT_NAME" ] || COMPOSE_PROJECT_NAME="$PROJECT_NAME${PROJECT_NAME_ADD_PROFILE:+_${PROFILE}}"
else
[ -n "$COMPOSE_PROJECT_NAME" ] || COMPOSE_PROJECT_NAME="$PROJECT_NAME"
fi
export COMPOSE_PROJECT_NAME
2018-11-22 15:34:07 +04:00
if [ "$1" == set_container_name ]; then
project_name="$PROJECT_NAME"
2018-11-22 15:34:07 +04:00
container_name="${project_name//[^a-zA-Z0-9_-]/}"
[ -n "$PROFILE" -a -n "$PROJECT_NAME_ADD_PROFILE" ] && container_name="${container_name}_$PROFILE"
2018-11-22 15:34:07 +04:00
fi
}
2019-06-01 14:34:20 +04:00
function compose_set_env_args() {
if [ -n "$CONFIG" ]; then
2019-06-11 08:18:43 +04:00
# autocomplétion friendly
[ ! -f "$CONFIG" -a -f "${CONFIG}yml" ] && CONFIG="${CONFIG}yml"
[ ! -f "$CONFIG" -a -f "$CONFIG.yml" ] && CONFIG="$CONFIG.yml"
##
replace_env_args+=(-f "$CONFIG")
if [ -n "$PROFILE" -a -f "${CONFIG%.yml}.$PROFILE.yml" ]; then
replace_env_args+=(-f "${CONFIG%.yml}.$PROFILE.yml")
fi
2019-06-01 14:34:20 +04:00
else
if [ -n "$USE_STACK" -a -f docker-stack.yml ]; then
replace_env_args+=(-f docker-stack.yml)
else
replace_env_args+=(-f docker-compose.yml)
fi
if [ -n "$USE_STACK" -a -f docker-stack.override.yml ]; then
replace_env_args+=(-f docker-stack.override.yml)
elif [ -f docker-compose.override.yml ]; then
replace_env_args+=(-f docker-compose.override.yml)
fi
if [ -n "$PROFILE" ]; then
if [ -n "$USE_STACK" -a -f "docker-stack.$PROFILE.yml" ]; then
replace_env_args+=(-f "docker-stack.$PROFILE.yml")
elif [ -f "docker-compose.$PROFILE.yml" ]; then
replace_env_args+=(-f "docker-compose.$PROFILE.yml")
fi
fi
fi
2019-06-01 14:34:20 +04:00
compose_set_project_name "$@"
}
2019-06-05 10:13:20 +04:00
function docker_set_deploy_args() {
if [ -n "$CONFIG" ]; then
2019-06-11 08:18:43 +04:00
# autocomplétion friendly
[ ! -f "$CONFIG" -a -f "${CONFIG}yml" ] && CONFIG="${CONFIG}yml"
[ ! -f "$CONFIG" -a -f "$CONFIG.yml" ] && CONFIG="$CONFIG.yml"
##
replace_deploy_args+=(-c "$CONFIG")
if [ -n "$PROFILE" -a -f "${CONFIG%.yml}.$PROFILE.yml" ]; then
replace_deploy_args+=(-c "${CONFIG%.yml}.$PROFILE.yml")
fi
2019-06-01 14:34:20 +04:00
else
if [ -n "$USE_STACK" -a -f docker-stack.yml ]; then
replace_deploy_args+=(-c docker-stack.yml)
else
replace_deploy_args+=(-c docker-compose.yml)
fi
if [ -n "$USE_STACK" -a -f docker-stack.override.yml ]; then
replace_deploy_args+=(-c docker-stack.override.yml)
elif [ -f docker-compose.override.yml ]; then
replace_deploy_args+=(-c docker-compose.override.yml)
fi
if [ -n "$PROFILE" ]; then
if [ -n "$USE_STACK" -a -f "docker-stack.$PROFILE.yml" ]; then
replace_deploy_args+=(-c "docker-stack.$PROFILE.yml")
elif [ -f "docker-compose.$PROFILE.yml" ]; then
replace_deploy_args+=(-c "docker-compose.$PROFILE.yml")
fi
fi
2019-06-01 14:34:20 +04:00
fi
compose_set_project_name "$@"
}
2018-11-22 15:34:07 +04:00
function host_run() {
# lancer le script $2..@ sur l'hôte $1
2019-04-10 07:25:20 +04:00
# si $1 n'est pas défini ou est le nom de l'hôte local ou vaut 'localhost',
# lancer le script en local avec les droits root
2018-11-22 15:34:07 +04:00
# sinon, si docker-machine existe, l'hôte doit correspondre à la machine active
# sinon, lancer inconditionnellement le script sur l'hôte distant
local host="$1" script="$2"; shift; shift
2019-04-10 07:25:20 +04:00
if [ -n "$host" -a "$host" != localhost ]; then
2018-11-22 15:34:07 +04:00
if check_hostname "$host"; then
estep "Lancement de $script localement"
runscript_as_root "$script" "$@"
elif progexists docker-machine; then
if [ "${host%%.*}" == "$DOCKER_MACHINE_NAME" ]; then
2018-11-22 15:34:07 +04:00
estep "Copie du script vers root@$host"
scp "$script" "root@$host:/tmp/tmp-dk-service-script" || die
estep "Lancement du script à distance"
local -a args; args=(/tmp/tmp-dk-service-script "$@")
ssh -qt "root@$host" "$(qvals "${args[@]}"); rm -f /tmp/tmp-dk-service-script"
else
ewarn "La machine active ($DOCKER_MACHINE_NAME) n'est pas la destination ($host)"
2018-11-22 15:34:07 +04:00
fi
else
estep "Copie du script vers root@$host"
scp "$script" "root@$host:/tmp/tmp-dk-service-script" || die
estep "Lancement du script à distance"
local -a args; args=(/tmp/tmp-dk-service-script "$@")
ssh -qt "root@$host" "$(qvals "${args[@]}"); rm -f /tmp/tmp-dk-service-script"
fi
else
estep "Lancement de $script localement"
runscript_as_root "$script" "$@"
fi
}
function local_run() {
# lancer le script $2..@ sur l'hôte $1 uniquement si c'est l'hôte courant
local host="$1" script="$2"; shift; shift
if [ -n "$host" ]; then
if ! check_hostname "$host"; then
eerror "Cette commande doit obligatoirement être lancée depuis l'hôte $host"
return 1
fi
fi
estep "Lancement de $script localement"
runscript_as_root "$script" "$@"
}
2019-04-02 15:59:47 +04:00
BUILD_UPDATE_APPS=
BUILD_BUILD=
UPDATE_APPS_ORIGIN=
UPDATE_APPS_BRANCH=
function build_set_options() {
BUILD_BUILD=
BUILD_UPDATE_APPS=
BUILD_UPDATE_DEVEL=
[[ "$1" == *b* ]] && BUILD_BUILD=1
[[ "$1" == *u* ]] && BUILD_UPDATE_APPS=1
[[ "$1" == *w* ]] && BUILD_UPDATE_DEVEL=1
2019-04-02 15:59:47 +04:00
UPDATE_APPS_ORIGIN="$2"
UPDATE_APPS_BRANCH="$3"
}
function update_apps_func_sqlmig() {
local destdir="$1" srcdir="$2" nofix="$3"
2019-04-02 15:59:47 +04:00
[ -n "$destdir" ] || destdir=db
2019-09-18 10:57:12 +04:00
[ -n "$srcdir" ] || srcdir="$DEST"
if [ -z "$nofix" ]; then
[ "${destdir%/config/mariadb/sqlmig}" != "$destdir" ] || destdir="$destdir/config/mariadb/sqlmig"
[ "${srcdir%/config/sqlmig}" != "$srcdir" ] || srcdir="$srcdir/config/sqlmig"
fi
2019-04-02 15:59:47 +04:00
2019-05-30 22:43:23 +04:00
if [ ! -d "$srcdir" ]; then
eerror "$srcdir: répertoire introuvable"
return 1
fi
2019-04-02 15:59:47 +04:00
local -a sqlmigs; local sqlmig name
array_lsall sqlmigs "$srcdir"
mkdir -p "$destdir" || return 1
for sqlmig in "${sqlmigs[@]}"; do
if [ -d "$sqlmig" ]; then
setx name=basename -- "$sqlmig"
rsync -av --delete-after "$sqlmig/" "$destdir/$name"
else
rsync -av "$sqlmig" "$destdir"
fi
done
return 0
}
function __maps_replace() {
if [ "${maps#$1,}" != "$maps" ]; then
maps="$2,${maps#$1,}"
elif [ "${maps%,$1}" != "$maps" ]; then
maps="${maps%,$1},$2"
elif [ "${maps/,$1,/}" != "$maps" ]; then
maps="${maps/,$1,/,$2,}"
elif [ "$maps" == "$1" ]; then
maps="$2"
fi
}
2019-09-18 10:57:12 +04:00
function update_apps_func_pff() {
local maps="$1" pffdir="${2:-$DEST}"
[ -f "$pffdir/$PFF_CONF" ] || return 0
# aliases
__maps_replace PTD prod:prod,test:test,devel:devel
__maps_replace PT prod:prod,test:test
2019-09-18 10:57:12 +04:00
source "$pffdir/$PFF_CONF"
pff_autofix "$pffdir"
local map src dest
array_split maps "$maps" ,
for map in "${maps[@]}"; do
if [ -z "$map" ]; then
continue
elif [[ "$map" == *:* ]]; then
# mapping de profil
splitpair "$map" dest src
if [ "$src" == "$PROFILE" ]; then
if array_contains PROFILES "$dest"; then
estep "Sélection du profil pff $dest"
pff_select_profile "$dest" "$pffdir"
return 0
fi
eerror "$dest: profil invalide, il a été ignoré"
fi
else
# forcer le profil
dest="$map"
if array_contains PROFILES "$dest"; then
estep "Sélection du profil pff $dest"
pff_select_profile "$dest" "$pffdir"
return 0
fi
eerror "$dest: profil invalide, il a été ignoré"
fi
done
# sélectionner le premier profil
setx dest=pff_get_first_profile "$pffdir"
if [ -n "$dest" ]; then
estep "Sélection du profil pff $dest"
pff_select_profile "$dest" "$pffdir"
fi
}
2019-04-02 15:59:47 +04:00
function build_update_apps() {
[ -n "$BUILD_UPDATE_APPS" ] || return 0
[ -f update-apps.conf ] || return 0
# charger le fichier de configuration
local DEFAULT_ORIGIN DEFAULT_BRANCH APPS
DEFAULT_ORIGIN="$UPDATE_APPS_ORIGIN"
[ -z "$DEFAULT_ORIGIN" ] && DEFAULT_ORIGIN=origin
DEFAULT_BRANCH="$UPDATE_APPS_BRANCH"
#XXX à terme, on déploiera la branche master en prod
[ -z "$DEFAULT_BRANCH" -a "$PROFILE" == prod ] && DEFAULT_BRANCH=develop #master
[ -z "$DEFAULT_BRANCH" ] && DEFAULT_BRANCH=develop
DEFAULT_DEVEL_SRCDIR="$HOME/wop/php"
DEFAULT_COMPOSER_ACTION=install
2019-04-02 15:59:47 +04:00
APPS=()
CLEAN=
2019-04-02 15:59:47 +04:00
[ -f update-apps.conf ] && source ./update-apps.conf
local apps # liste des applications spécifique au profil
apps="${PROFILE}_APPS[@]"; apps=("${!apps}")
[ ${#apps[*]} -gt 0 ] && APPS=("${apps[@]}")
2019-04-02 15:59:47 +04:00
[ ${#APPS[*]} -gt 0 ] || return 0
local PRODUCTION DEVELOPMENT
case "$PROFILE" in
prod) PRODUCTION=1; DEVELOPMENT=;;
test) PRODUCTION=1; DEVELOPMENT=1;;
devel) PRODUCTION=; DEVELOPMENT=;;
esac
local clean
clean="${PROFILE}_CLEAN"; clean="${!clean}"
[ -n "$clean" ] && CLEAN="$clean"
if [ -n "$CLEAN" ]; then
etitle "Nettoyage"
"$CLEAN"
eend
fi
2019-04-02 15:59:47 +04:00
etitle "Mise à jour des dépendances"
2019-09-18 10:57:12 +04:00
local app var URL DEVEL_SRCDIR DEST ORIGIN BRANCH TYPE after_update after_updates composer_action
2019-04-02 15:59:47 +04:00
for app in "${APPS[@]}"; do
etitle "$app"
2019-05-30 22:43:23 +04:00
var="${app//-/_}"
2019-09-18 10:57:12 +04:00
URL="${var}_URL"; URL="${!URL}"
[ -n "$URL" ] || {
ewarn "$app: vous devez définir l'url"
eend; return 1
}
2019-09-18 10:57:12 +04:00
DEVEL_SRCDIR="${var}_DEVEL_SRCDIR"; DEVEL_SRCDIR="${!DEVEL_SRCDIR}"
[ -n "$DEVEL_SRCDIR" ] || DEVEL_SRCDIR="$DEFAULT_DEVEL_SRCDIR/${URL##*/}"
2019-09-18 10:57:12 +04:00
DEST="${var}_DEST"; DEST="${!DEST}"
[ -n "$DEST" ] || DEST="$app/b"
mkdir -p "$DEST" || { eend; return 1; }
2019-09-18 10:57:12 +04:00
ORIGIN="${var}_${PROFILE}_ORIGIN"; ORIGIN="${!ORIGIN}"
[ -n "$ORIGIN" ] || { ORIGIN="${var}_ORIGIN"; ORIGIN="${!ORIGIN}"; }
[ -n "$ORIGIN" ] || ORIGIN="$DEFAULT_ORIGIN"
2019-09-18 10:57:12 +04:00
BRANCH="${var}_${PROFILE}_BRANCH"; BRANCH="${!BRANCH}"
[ -n "$BRANCH" ] || { BRANCH="${var}_BRANCH"; BRANCH="${!BRANCH}"; }
[ -n "$BRANCH" ] || BRANCH="$DEFAULT_BRANCH"
# calculer le type maintenant, on en a besoin pour le mode devel
2019-09-18 10:57:12 +04:00
TYPE="${var}_TYPE"; TYPE="${!TYPE}"
2019-09-18 10:57:12 +04:00
DEST="$DEST/$app"
if [ -n "$BUILD_UPDATE_DEVEL" ]; then
# synchronisation en mode devel
local -a rsync_opts; rsync_opts=(-a --delete --exclude .git/ --delete-excluded)
2019-09-18 10:57:12 +04:00
estep "Synchro $DEVEL_SRCDIR --> $DEST"
rsync "${rsync_opts[@]}" "$DEVEL_SRCDIR/" "$DEST" || { eend; return 1; }
2019-09-18 10:57:12 +04:00
if [ -z "$TYPE" ]; then
# possible de détecter le type quand on a le projet
# en cas de maj ici, mettre à jour aussi le code ci-dessous
2019-09-18 10:57:12 +04:00
if [ -f "$DEST/composer.json" ]; then TYPE=composer
else TYPE=none
fi
fi
2019-09-18 10:57:12 +04:00
if [ "$TYPE" == composer ]; then
# Synchronisation des dépendances
local -a depdirs; local depdir pname
2019-09-18 10:57:12 +04:00
setx -a depdirs=ls -d "$DEST/vendor/"{lib,ur}/* 2>/dev/null
for depdir in "${depdirs[@]}"; do
[ -L "$depdir" ] && rm "$depdir"
2019-09-18 10:57:12 +04:00
pname="${depdir#$DEST/vendor/}"; pname="${pname/\//-}"
estep "Synchro $DEFAULT_DEVEL_SRCDIR/$pname --> $depdir"
rsync "${rsync_opts[@]}" --exclude /vendor/ "$DEFAULT_DEVEL_SRCDIR/$pname/" "$depdir"
done
fi
else
2019-09-18 10:57:12 +04:00
if [ -d "$DEST" -a -d "$DEST/.git" ]; then
# mise à jour
2019-09-18 10:57:12 +04:00
estep "Maj dépôt $URL:$BRANCH --> $DEST"
setx cwd=pwd
2019-09-18 10:57:12 +04:00
cd "$DEST"
git fetch --all -p -f || { eend; return 1; }
2019-09-18 10:57:12 +04:00
git reset --hard "$ORIGIN/$BRANCH" || { eend; return 1; }
cd "$cwd"
else
# reliquat mode devel?
2019-09-18 10:57:12 +04:00
[ -d "$DEST" ] && rm -rf "$DEST"
# clonage initial
2019-09-18 10:57:12 +04:00
estep "Clonage $URL:$BRANCH --> $DEST"
git clone -o "$ORIGIN" -b "$BRANCH" "$URL" "$DEST" || { eend; return 1; }
fi
2019-09-18 10:57:12 +04:00
if [ -z "$TYPE" ]; then
# possible de détecter le type quand on a le projet
# en cas de maj ici, mettre à jour aussi le code ci-dessus
2019-09-18 10:57:12 +04:00
if [ -f "$DEST/composer.json" ]; then TYPE=composer
else TYPE=none
fi
fi
fi
2019-05-30 22:43:23 +04:00
after_updates="${var}_AFTER_UPDATE"
2019-04-02 15:59:47 +04:00
if is_defined "$after_updates"; then
2019-05-30 22:43:23 +04:00
after_updates="$after_updates[@]"; after_updates=("${!after_updates}")
2019-09-18 10:57:12 +04:00
elif [ "$TYPE" == composer ]; then
2019-04-02 15:59:47 +04:00
after_updates=(sqlmig)
else
after_updates=()
2019-04-02 15:59:47 +04:00
fi
2019-09-18 10:57:12 +04:00
estep "Type de dépôt: $TYPE"
if [ "$TYPE" == composer ]; then
composer_action="${var}_${PROFILE}_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"
if [ -z "$BUILD_UPDATE_DEVEL" ]; then
case "${composer_action:-install}" in
i|install) composer_action=install;;
u|update) composer_action=update;;
none|nop) composer_action=;;
*) ewarn "$composer_action: action invalide"; composer_action=;;
esac
if [ -n "$composer_action" ]; then
setx cwd=pwd
cd "$DEST"
estep "Installation des dépendances composer"
auto_composer "$composer_action" ${PRODUCTION:+--no-dev -o} || { eend; return 1; }
cd "$cwd"
fi
fi
2019-04-02 15:59:47 +04:00
fi
for after_update in "${after_updates[@]}"; do
if [ "${after_update#/}" != "$after_update" ]; then
# commande absolue, la lancer telle quelle
2019-09-18 10:57:12 +04:00
etitle "$after_update"
eval "$after_update" || { eend; eend; return 1; }
eend
2019-04-02 15:59:47 +04:00
elif [ "${after_update#./}" != "$after_update" ]; then
# commande relative, la lancer telle quelle
2019-09-18 10:57:12 +04:00
etitle "$after_update"
eval "$after_update" || { eend; eend; return 1; }
eend
2019-04-02 15:59:47 +04:00
else
# c'est une fonction update_apps_func_*
2019-09-18 10:57:12 +04:00
etitle "$after_update"
eval "update_apps_func_$after_update" || { eend; eend; return 1; }
eend
2019-04-02 15:59:47 +04:00
fi
done
eend
done
eend
}
function initialize_build_env() {
CTXDIR=.
NAME=
TAGS=(latest)
VERSION=
DIST=
}
2018-10-09 10:02:57 +04:00
function default_update_build_env() {
2020-02-14 11:18:32 +04:00
local var
if [ -n "$DIST" ]; then
[ -n "$VERSION" ] && VERSION="$VERSION-"
VERSION="$VERSION$DIST"
2019-07-18 22:51:43 +04:00
TAGS+=("$DIST")
fi
2018-10-09 10:02:57 +04:00
[ -n "$VERSION" ] || docker_add_build_arg VERSION "$(get_version)"
[ -n "$VERSION" ] && TAGS+=("$VERSION")
2020-02-14 11:18:32 +04:00
# Variables en ligne de commande
for var in "${VARS[@]}"; do
docker_add_build_arg "${var%%=*}" "${var#*=}"
done
2018-10-09 10:02:57 +04:00
}
function update_build_env() { default_update_build_env; }
function default_compose_build() {
${FAKE:+qvals} docker-compose \
"${replace_env_args[@]}" "${env_args[@]}" \
build \
${NO_CACHE:+--no-cache} \
"${replace_build_args[@]}" "${build_args[@]}" \
"$@"
}
function default_docker_build() {
local tag
for tag in "${TAGS[@]}"; do
replace_build_args+=(-t "$NAME:$tag")
done
2019-12-03 06:39:00 +04:00
${FAKE:+qvals} "$DOCKER" build \
${NO_CACHE:+--no-cache} \
"${replace_env_args[@]}" "${env_args[@]}" \
"${replace_build_args[@]}" "${build_args[@]}" \
"$@" "$CTXDIR"
}
2019-04-02 15:59:47 +04:00
function compose_build() {
[ -n "$BUILD_BUILD" ] || return 0
default_compose_build "$@"
}
function docker_build() {
[ -n "$BUILD_BUILD" ] || return 0
default_docker_build "$@"
}
function auto_build() {
local -a replace_env_args env_args
local -a replace_build_args build_args
initialize_build_env
if [ -f docker-compose.yml ]; then
compose_set_env_args
update_build_env
2019-04-02 15:59:47 +04:00
build_update_apps || return 1
compose_build "$@"
2020-03-20 22:51:05 +04:00
elif [ -f Dockerfile ]; then
docker_parse_env_args
docker_check_name
docker_add_build_arg build_date "$(date +%y%m%d)"
update_build_env
2019-04-02 15:59:47 +04:00
build_update_apps || return 1
docker_build "$@"
2020-03-20 22:51:05 +04:00
else
${FAKE:+qvals} "$DOCKER" build ${NO_CACHE:+--no-cache} "$@"
fi
}
function default_compose_push() {
${FAKE:+qvals} docker-compose \
"${replace_env_args[@]}" "${env_args[@]}" \
2019-06-01 14:34:20 +04:00
push \
"$@"
}
function default_docker_push() {
2019-12-03 06:39:00 +04:00
${FAKE:+qvals} "$DOCKER" push \
"${replace_env_args[@]}" "${env_args[@]}" \
"$@"
}
function compose_push() {
default_compose_push "$@"
}
function docker_push() {
local tag
for tag in "${TAGS[@]}"; do
default_docker_push "$NAME:$tag" "$@"
done
}
function auto_push() {
2018-10-09 10:02:57 +04:00
local -a replace_env_args env_args
local -a replace_build_args build_args
initialize_build_env
2018-10-09 10:02:57 +04:00
if [ -f docker-compose.yml ]; then
compose_set_env_args
update_build_env
compose_push "$@"
2020-03-20 22:51:05 +04:00
elif [ -f Dockerfile ]; then
2018-10-09 10:02:57 +04:00
docker_parse_env_args
docker_check_name
update_build_env
docker_push "$@"
2020-03-20 22:51:05 +04:00
else
${FAKE:+qvals} "$DOCKER" push "$@"
2018-10-09 10:02:57 +04:00
fi
}
function default_compose_up() {
${FAKE:+qvals} docker-compose \
"${replace_env_args[@]}" "${env_args[@]}" \
up "${replace_run_args[@]}" "${run_args[@]}" \
"${replace_user_args[@]}" "${user_args[@]}" "$@"
}
function default_docker_up() {
2019-12-03 06:39:00 +04:00
${FAKE:+qvals} "$DOCKER" run \
"${replace_env_args[@]}" "${env_args[@]}" \
"${replace_run_args[@]}" "${run_args[@]}" \
"$NAME" \
"${replace_user_args[@]}" "${user_args[@]}" "$@"
}
function compose_up() { default_compose_up "$@"; }
function docker_up() { default_docker_up "$@"; }
function auto_up() {
local -a replace_env_args env_args
local -a replace_run_args run_args
local -a replace_user_args user_args
2018-11-22 15:34:07 +04:00
local project_name container_name
if [ -f docker-compose.yml ]; then
compose_set_env_args
replace_run_args=(-d)
compose_up "$@"
2020-03-20 22:51:05 +04:00
elif [ -f Dockerfile ]; then
docker_set_env_args
2018-11-22 15:34:07 +04:00
docker_check_name set_container_name
replace_run_args=(-d --name "$container_name")
docker_up "$@"
2020-03-20 22:51:05 +04:00
else
${FAKE:+qvals} "$DOCKER" run "$@"
fi
}
2019-03-28 10:53:50 +04:00
function default_compose_stop() {
${FAKE:+qvals} docker-compose \
"${replace_env_args[@]}" "${env_args[@]}" \
stop "${replace_stop_args[@]}" "${stop_args[@]}" \
"$@"
}
function default_docker_stop() {
2019-12-03 06:39:00 +04:00
${FAKE:+qvals} "$DOCKER" container stop \
2019-03-28 10:53:50 +04:00
"${replace_stop_args[@]}" "${stop_args[@]}" \
"$container_name" "$@"
}
function compose_stop() { default_compose_stop "$@"; }
function docker_stop() { default_docker_stop "$@"; }
function auto_stop() {
local -a replace_env_args env_args
local -a replace_stop_args stop_args
local project_name container_name
if [ -f docker-compose.yml ]; then
compose_set_env_args
compose_stop "$@"
2020-03-20 22:51:05 +04:00
elif [ -f Dockerfile ]; then
2019-03-28 10:53:50 +04:00
docker_set_env_args
docker_check_name set_container_name
docker_stop "$@"
2020-03-20 22:51:05 +04:00
else
${FAKE:+qvals} "$DOCKER" stop "$@"
2019-03-28 10:53:50 +04:00
fi
}
function default_compose_logs() {
${FAKE:+qvals} docker-compose \
"${replace_env_args[@]}" "${env_args[@]}" \
logs "${replace_logs_args[@]}" "${logs_args[@]}" \
"$@"
}
function default_docker_logs() {
2019-12-03 06:39:00 +04:00
${FAKE:+qvals} "$DOCKER" logs \
2019-03-28 10:53:50 +04:00
"${replace_logs_args[@]}" "${logs_args[@]}" \
"$container_name" "$@"
}
function compose_logs() { default_compose_logs "$@"; }
function docker_logs() { default_docker_logs "$@"; }
function auto_logs() {
local -a replace_env_args env_args
local -a replace_logs_args logs_args
local project_name container_name
if [ -f docker-compose.yml ]; then
compose_set_env_args
replace_logs_args=(-f)
compose_logs "$@"
2020-03-20 22:51:05 +04:00
elif [ -f Dockerfile ]; then
2019-03-28 10:53:50 +04:00
docker_set_env_args
docker_check_name set_container_name
replace_logs_args=(-f)
docker_logs "$@"
2020-03-20 22:51:05 +04:00
else
${FAKE:+qvals} "$DOCKER" logs "$@"
2019-03-28 10:53:50 +04:00
fi
}
function default_compose_down() {
${FAKE:+qvals} docker-compose \
"${replace_env_args[@]}" "${env_args[@]}" \
down "${replace_down_args[@]}" "${down_args[@]}" \
"$@"
}
function default_docker_down() {
estep "stop"
2019-12-03 06:39:00 +04:00
${FAKE:+qvals} "$DOCKER" container stop \
2019-03-28 10:53:50 +04:00
"${replace_down_args[@]}" "${down_args[@]}" \
"$container_name" "$@"
estep "rm"
2019-12-03 06:39:00 +04:00
${FAKE:+qvals} "$DOCKER" container rm \
2019-03-28 10:53:50 +04:00
"${replace_rm_args[@]}" "${rm_args[@]}" \
"$container_name"
}
function compose_down() { default_compose_down "$@"; }
function docker_down() { default_docker_down "$@"; }
function auto_down() {
local -a replace_env_args env_args
local -a replace_down_args down_args
local -a replace_rm_args rm_args
local project_name container_name
if [ -f docker-compose.yml ]; then
compose_set_env_args
compose_down "$@"
2020-03-20 22:51:05 +04:00
elif [ -f Dockerfile ]; then
2019-03-28 10:53:50 +04:00
docker_set_env_args
docker_check_name set_container_name
docker_down "$@"
2020-03-20 22:51:05 +04:00
else
${FAKE:+qvals} "$DOCKER" stop "$@"
2019-03-28 10:53:50 +04:00
fi
}
2019-06-24 23:57:02 +04:00
function default_compose_run() {
${FAKE:+qvals} docker-compose \
"${replace_env_args[@]}" "${env_args[@]}" \
run "${replace_run_args[@]}" "${run_args[@]}" \
"${replace_user_args[@]}" "${user_args[@]}" "$@"
}
function default_docker_run() {
2019-12-03 06:39:00 +04:00
${FAKE:+qvals} "$DOCKER" run \
2019-06-24 23:57:02 +04:00
"${replace_env_args[@]}" "${env_args[@]}" \
"${replace_run_args[@]}" "${run_args[@]}" \
"$NAME" \
"${replace_user_args[@]}" "${user_args[@]}" "$@"
}
function compose_run() { default_compose_run "$@"; }
function docker_run() { default_docker_run "$@"; }
function auto_run() {
eval "$(utools_local parse_opts)"
local detach no_deps rm=1 service_ports use_aliases volume
local -a envs labels
2020-02-14 11:18:32 +04:00
local var
for var in "${VARS[@]}"; do
envs+=(-e "$var")
done
args=(
+
-d,--detach detach=1
-e: '$add@ envs -e; add@ envs'
-l:,--label: '$add@ labels -l; add@ labels'
--no-deps no_deps=1
--no-rm rm=
--rm rm=1
--service-ports service_ports=1
--use-aliases use_aliases=1
-v:,--volume: volume=
@ args -- "$@"
)
parse_opts "${args[@]}" && set -- "${args[@]}" || { eerror "$args"; return 1; }
2019-06-24 23:57:02 +04:00
local -a replace_env_args env_args
local -a replace_run_args run_args
local -a replace_user_args user_args
local project_name container_name
if [ -f docker-compose.yml ]; then
compose_set_env_args
replace_run_args=(
${detach:+-d}
"${envs[@]}" "${labels[@]}"
${no_deps:+--no-deps}
${rm:+--rm}
${service_ports:+--service-ports}
${use_aliases:+--use-aliases}
${volume:+-v "$volume"}
)
2019-06-24 23:57:02 +04:00
compose_run "$@"
2020-03-20 22:51:05 +04:00
elif [ -f Dockerfile ]; then
2019-06-24 23:57:02 +04:00
docker_set_env_args
docker_check_name set_container_name
replace_run_args=(
--name "$container_name"
${rm:+--rm}
${volume:+-v "$volume"}
)
2019-06-24 23:57:02 +04:00
docker_run "$@"
2020-03-20 22:51:05 +04:00
else
${FAKE:+qvals} "$DOCKER" run ${rm:+--rm} ${volume:+-v "$volume"} "$@"
2019-06-24 23:57:02 +04:00
fi
}
function default_compose_exec() {
${FAKE:+qvals} docker-compose \
"${replace_env_args[@]}" "${env_args[@]}" \
exec "${replace_exec_args[@]}" "${exec_args[@]}" \
"$@"
}
function default_docker_exec() {
2019-12-03 06:39:00 +04:00
${FAKE:+qvals} "$DOCKER" container exec \
2019-06-24 23:57:02 +04:00
"${replace_exec_args[@]}" "${exec_args[@]}" \
"$container_name" "$@"
}
function compose_exec() { default_compose_exec "$@"; }
function docker_exec() { default_docker_exec "$@"; }
function auto_exec() {
local -a replace_env_args env_args
local -a replace_exec_args exec_args
local project_name container_name
if [ -f docker-compose.yml ]; then
compose_set_env_args
compose_exec "$@"
2020-03-20 22:51:05 +04:00
elif [ -f Dockerfile ]; then
2019-06-24 23:57:02 +04:00
docker_set_env_args
docker_check_name set_container_name
docker_exec "$@"
2020-03-20 22:51:05 +04:00
else
${FAKE:+qvals} "$DOCKER" exec "$@"
2019-06-24 23:57:02 +04:00
fi
}
2019-06-05 10:13:20 +04:00
function default_docker_deploy() {
2019-12-03 06:39:00 +04:00
${FAKE:+qvals} "$DOCKER" \
2019-06-01 14:34:20 +04:00
stack deploy \
"${replace_deploy_args[@]}" "${deploy_args[@]}" \
"$container_name" "$@"
}
2019-06-05 10:13:20 +04:00
function docker_deploy() { default_docker_deploy "$@"; }
2019-06-01 14:34:20 +04:00
function auto_deploy() {
local -a replace_env_args env_args
local -a replace_deploy_args deploy_args
local project_name container_name
if [ -f docker-compose.yml -o -f docker-stack.yml ]; then
2019-06-05 10:13:20 +04:00
docker_set_deploy_args set_container_name
2019-06-01 14:34:20 +04:00
[ -n "$WITH_REGISTRY_AUTH" ] && replace_deploy_args+=(--with-registry-auth)
2019-06-05 10:13:20 +04:00
docker_deploy "$@"
else
die "Impossible de trouver ni docker-compose.yml ni docker-stack.yml"
fi
}
function default_docker_service() {
2019-12-03 06:39:00 +04:00
${FAKE:+qvals} "$DOCKER" service "$@"
2019-06-05 10:13:20 +04:00
}
function docker_service() { default_docker_service "$@"; }
function auto_service() {
if [ -f docker-compose.yml -o -f docker-stack.yml ]; then
local command="$1"; shift
[ -n "$command" ] || {
eerror "Vous devez spécifier la commande"
return 1
}
local -a command_args
[ "$command" == update -a -n "$WITH_REGISTRY_AUTH" ] && command_args+=(--with-registry-auth)
2019-06-05 10:13:20 +04:00
case "$command" in
ls) # ces commandes n'ont pas besoin du nom de service
docker_service "$command" "$@"
;;
*) # ces commandes ont besoin du nom du service
local service="$1"; shift
[ -n "$service" ] || {
eerror "Vous devez spécifier le nom du service"
return 1
}
local -a replace_env_args env_args
local -a replace_deploy_args deploy_args
local project_name container_name
2019-06-05 10:13:20 +04:00
docker_set_deploy_args set_container_name
service="${container_name}_${service#${container_name}_}"
docker_service "$command" "${command_args[@]}" "$@" "$service"
2019-06-05 10:13:20 +04:00
;;
esac
2019-06-01 14:34:20 +04:00
else
2020-03-20 22:51:05 +04:00
${FAKE:+qvals} "$DOCKER" service "$@"
2019-06-01 14:34:20 +04:00
fi
}
2020-03-26 16:40:37 +04:00
function __format() {
# formatter une liste de valeur. chaque argument est de la forme [SIZE:]VALUE
# il ne faudrait utiliser la forme VALUE que pour le dernier argument
local size value
for value in "$@"; do
if [[ "$value" == *:* ]]; then
size="${value%%:*}"
value="${value#*:}"
else
size=
fi
if [ -n "$size" ]; then
while [ "${#value}" -lt "$size" ]; do
value="$value "
done
if [ "${#value}" -gt "$size" ]; then
[ "$size" -gt 1 ] && value="${value:0:$(($size - 1))}"
value="$value"$'\xe2\x80\xa6'
fi
fi
echo -n "${value} "
done
echo
}
function __status_query_task() {
setx taskData="$DOCKER" inspect "$taskID"
setx taskSlot=json_get 0.Slot <<<"$taskData"
setx taskStatus=json_get 0.Status.Err <<<"$taskData"
setx serviceID=json_get 0.ServiceID <<<"$taskData"
}
function __status_query_service() {
[ "$serviceID" == "$pServiceID" ] && return
2020-03-26 16:40:37 +04:00
setx serviceData="$DOCKER" inspect "$serviceID"
setx serviceName=json_get 0.Spec.Name <<<"$serviceData"
setx serviceUpdateStatus=json_get 0.UpdateStatus.Message <<<"$serviceData"
pServiceID="$serviceID"
2020-03-26 16:40:37 +04:00
}
function __status_process_data() {
__status_query_task
__status_query_service
if [ -n "$serviceUpdateStatus" ]; then
echo "\
================
$serviceName: $serviceUpdateStatus
================"
serviceUpdateStatus=
fi
if [ "$num" -eq 0 ]; then
# afficher les en-têtes
__format 3:num 32:taskName 20:node 8:dState 20:cState :error
fi
if [ -z "$fnum" -o "$num" == "$fnum" ]; then
taskName="$serviceName.$taskSlot"
__format 3:"$num" 32:"$taskName.$taskID" 20:"$node" 8:"$desiredState" 20:"$currentState" :"$taskStatus"
fi
if [ "$num" == "$fnum" ]; then
"$DOCKER" service logs -f "$taskID"
fi
let num=num+1
}
function auto_status() {
local -a services
local service
if [[ "$1" == *=* ]]; then
: # le premier argument est un filtre
elif [ -n "$1" -a -z "${1//[0-9]/}" ]; then
: # le premier argument est un numéro d'instance
else
# le premier argument est un nom de service
service="$1"; shift
fi
if [ -n "$service" ]; then
if [ -f docker-compose.yml -o -f docker-stack.yml ]; then
# si on est dans répertoire de projet, il est possible de spécifier
# le service sans préfixe
local -a replace_env_args env_args
local -a replace_deploy_args deploy_args
local project_name container_name
docker_set_deploy_args set_container_name
service="${container_name}_${service#${container_name}_}"
fi
services=("$service")
else
# lister les services qui tournent actuellement
setx -a services=docker service ls --format "{{.Name}}"
2020-03-26 16:40:37 +04:00
fi
local -a psargs
2020-03-26 16:40:37 +04:00
local fnum
psargs=(
2020-03-26 16:40:37 +04:00
--format "taskID={{.ID}};node={{.Node}};desiredState='{{.DesiredState}}';currentState='{{.CurrentState}}';__status_process_data"
)
while [[ "$1" == *=* ]]; do
psargs+=(--filter "$1")
2020-03-26 16:40:37 +04:00
shift
done
fnum="$1"; shift
local num=0 taskData taskStatus taskSlot pServiceID serviceID serviceData serviceName serviceUpdateStatus
for service in "${services[@]}"; do
eval "$("$DOCKER" service ps "$service" "${psargs[@]}")"
done
2020-03-26 16:40:37 +04:00
}
2019-04-17 02:31:09 +04:00
function default_compose_show_ip() {
local -a cmd cids; local cid
cmd=(
docker-compose
"${replace_env_args[@]}" "${env_args[@]}"
ps -q "${replace_show_ip_args[@]}" "${show_ip_args[@]}"
"$@"
)
if [ -n "$FAKE" ]; then
echo "docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \"\$($(qvals "${cmd[@]}"))\""
else
setx -a cids="${cmd[@]}" 2>/dev/null
for cid in "${cids[@]}"; do
2019-12-03 06:39:00 +04:00
"$DOCKER" inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$cid"
2019-04-17 02:31:09 +04:00
done
fi
}
function default_docker_show_ip() {
2019-12-03 06:39:00 +04:00
${FAKE:+qvals} "$DOCKER" inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \
2019-04-17 02:31:09 +04:00
"${replace_show_ip_args[@]}" "${show_ip_args[@]}" \
"$container_name" "$@"
}
function compose_show_ip() { default_compose_show_ip "$@"; }
function docker_show_ip() { default_docker_show_ip "$@"; }
function auto_show_ip() {
local -a replace_env_args env_args
local -a replace_show_ip_args show_ip_args
local project_name container_name
if [ -f docker-compose.yml ]; then
compose_set_env_args
compose_show_ip "$@"
else
docker_set_env_args
docker_check_name set_container_name
docker_show_ip "$@"
fi
}
2019-04-10 07:25:20 +04:00
function default_compose_systemd_unit() {
2019-01-14 16:09:03 +04:00
local docker_compose="$(which docker-compose 2>/dev/null)"
if [ -z "$docker_compose" ]; then
if [ -x /usr/bin/docker-compose ]; then
docker_compose=/usr/bin/docker-compose
elif [ -x /usr/local/bin/docker-compose ]; then
docker_compose=/usr/local/bin/docker-compose
else
die "Impossible de trouver docker-compose"
fi
fi
2018-11-22 15:34:07 +04:00
setx startcmd=qvals "$docker_compose" \
"${replace_env_args[@]}" "${env_args[@]}" \
up "${replace_run_args[@]}" "${run_args[@]}" \
"${replace_user_args[@]}" "${user_args[@]}" "$@"
setx stopcmd=qvals "$docker_compose" down
}
2019-04-10 07:25:20 +04:00
function default_docker_systemd_unit() {
2019-12-03 06:39:00 +04:00
local docker="$(which "$DOCKER" 2>/dev/null)"
2019-01-14 16:09:03 +04:00
if [ -z "$docker" ]; then
if [ -x /usr/bin/docker ]; then
docker=/usr/bin/docker
elif [ -x /usr/local/bin/docker ]; then
docker=/usr/local/bin/docker
else
die "Impossible de trouver docker"
fi
fi
2018-11-22 15:34:07 +04:00
setx startcmd=qvals "$docker" run \
"${replace_env_args[@]}" "${env_args[@]}" \
"${replace_run_args[@]}" "${run_args[@]}" \
"$NAME" \
"${replace_user_args[@]}" "${user_args[@]}" "$@"
setx stopcmd=qvals "$docker" stop "$container_name"
}
2019-04-10 07:25:20 +04:00
function compose_systemd_unit() { default_compose_systemd_unit "$@"; }
function docker_systemd_unit() { default_docker_systemd_unit "$@"; }
function auto_systemd_unit() {
2018-11-22 15:34:07 +04:00
local -a replace_env_args env_args
local -a replace_run_args run_args
local -a replace_user_args user_args
local project_name container_name startcmd stopcmd
local tmpscript; ac_set_tmpfile tmpscript
2019-04-10 07:25:20 +04:00
estep "Génération de l'unité systemd"
2018-11-22 15:34:07 +04:00
export COMPOSE_PROJECT_NAME=
if [ -f docker-compose.yml ]; then
compose_set_env_args set_container_name
replace_run_args=(-d --no-color)
2019-04-10 07:25:20 +04:00
compose_systemd_unit "$@"
2018-11-22 15:34:07 +04:00
if [ -z "$HOST" -a -f .env ]; then
source ./.env
if [ -n "$PROFILE" ]; then
HOST="${PROFILE^^}_HOST"; HOST="${!HOST}"
fi
fi
else
docker_set_env_args
docker_check_name set_container_name
replace_run_args=(-d --name "$container_name")
2019-04-10 07:25:20 +04:00
docker_systemd_unit "$@"
2018-11-22 15:34:07 +04:00
fi
[ -n "$COMPOSE_PROJECT_NAME" ] || COMPOSE_PROJECT_NAME="$project_name"
chmod 755 "$tmpscript"
cat >"$tmpscript" <<EOF
#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
cat >/etc/systemd/system/$container_name.service <<EOD
[Unit]
Description=$project_name stack ($PROFILE)
2018-12-01 23:04:28 +04:00
Requires=docker.service
After=docker.service
2018-11-22 15:34:07 +04:00
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=$(pwd)
Environment=$(qval "COMPOSE_PROJECT_NAME=$COMPOSE_PROJECT_NAME")
ExecStart=$startcmd
ExecStop=$stopcmd
TimeoutStopSec=300
[Install]
WantedBy=multi-user.target
EOD
systemctl daemon-reload
systemctl enable $container_name.service
EOF
2019-04-10 07:25:20 +04:00
estep "Installation de l'unité systemd"
2018-11-22 15:34:07 +04:00
local_run "$HOST" "$tmpscript"
}
2019-10-03 19:20:32 +04:00
function default_local_composer() {
# lancement direct
case "$1" in
2020-01-22 10:47:14 +04:00
rootshell|rshell|rootbash|rbash)
2020-01-26 09:27:36 +04:00
shift
2019-10-03 19:20:32 +04:00
# ewarn parce qu'on est pas root dans ce shell contrairement à ce qui est demandé
2020-01-22 10:47:14 +04:00
ewarn "Lancement d'un shell utilisateur alors qu'un shell root est demandé"
2019-10-03 19:20:32 +04:00
bash "$@"
;;
2020-01-22 10:47:14 +04:00
usershell|shell|userbash|bash)
2020-01-26 09:27:36 +04:00
shift
2019-10-03 19:20:32 +04:00
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
2019-10-03 19:20:32 +04:00
"$COMPOSER_CMD" "$@"
;;
esac
}
function default_docker_composer() {
# lancement dans un container
local user group projdir actualcmd args
2019-10-02 22:04:10 +04:00
setx user=id -un; setx user=getent passwd "$user"
setx group=id -gn; setx group=getent group "$group"
setx projdir=pwd
2019-10-02 22:16:40 +04:00
case "$1" in
2020-01-22 10:47:14 +04:00
rootshell|rshell|rootbash|rbash)
shift
2020-01-26 09:27:36 +04:00
actualcmd='eval "bash $args"'
2019-10-02 22:20:48 +04:00
;;
2020-01-22 10:47:14 +04:00
usershell|shell|userbash|bash)
shift
2020-01-26 09:27:36 +04:00
actualcmd='eval "su-exec \"$user\" bash $args"'
2019-10-02 22:16:40 +04:00
;;
*)
actualcmd='eval "su-exec \"$user\" \"$composer\" $args"'
;;
esac
2019-10-02 22:04:10 +04:00
setx args=qvals "$@"
local -a basecmd cmd setupscript runscript
basecmd=(
2019-10-02 22:04:10 +04:00
-e user="$user"
-e group="$group"
-e projdir="$projdir"
-e setup="$COMPOSER_SETUP"
-e composer="$COMPOSER_CMD"
2019-10-02 22:04:10 +04:00
-e args="$args"
-v "$HOME:$HOME"
)
if [ "${projdir#$HOME/}" == "$projdir" ]; then
# si le répertoire de projet ne se trouve pas dans $HOME, le monter aussi
cmd+=(-v "$projdir:$projdir")
fi
setupscript='eval "$setup"'
runscript='
2019-10-02 22:04:10 +04:00
echo "$user" >>/etc/passwd; user="${user%%:*}"
echo "$group" >>/etc/group; group="${group%%:*}"
cd "$projdir"
if [ -n "$composer" ]; then :
elif [ -x composer.phar ]; then composer=./composer.phar
2019-10-02 22:04:10 +04:00
elif [ -x /usr/bin/composer ]; then composer=/usr/bin/composer
else
echo "ERROR: Impossible de trouver composer"
2019-10-02 22:04:10 +04:00
exit 1
fi
2019-10-02 22:16:40 +04:00
'"$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=(
2019-12-03 06:39:00 +04:00
"$DOCKER" create -it --name "${container_name}_ct"
"${basecmd[@]}"
"$COMPOSER_IMAGE"
bash -c "$setupscript"
)
setx dkid="${cmd[@]}" || return 1
2019-12-03 06:39:00 +04:00
"$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=(
2019-12-03 06:39:00 +04:00
"$DOCKER" run -it --rm
"${basecmd[@]}"
"$COMPOSER_IMAGE"
bash -c "$runscript"
2019-10-02 22:04:10 +04:00
)
"${cmd[@]}"
}
2019-10-03 19:20:32 +04:00
function local_composer() { default_local_composer "$@"; }
function docker_composer() { default_docker_composer "$@"; }
function auto_composer() {
2020-01-22 10:47:14 +04:00
local COMPOSER_PHP=
2020-01-30 14:32:44 +04:00
local COMPOSER_PHP_MAX=
2019-10-03 19:20:32 +04:00
local COMPOSER_IMAGE="$DEFAULT_COMPOSER_IMAGE"
local COMPOSER_MACHINE=-u
local COMPOSER_CMD=
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
2020-01-22 10:47:14 +04:00
COMPOSER_PHP=*) setv "$1"; shift;;
2020-01-30 14:32:44 +04:00
COMPOSER_PHP_MAX=*) setv "$1"; shift;;
2019-10-03 19:20:32 +04:00
COMPOSER_IMAGE=*) setv "$1"; shift;;
COMPOSER_MACHINE=*) setv "$1"; shift;;
COMPOSER_CMD=*) setv "$1"; shift;;
COMPOSER_SETUP=*) setv "$1"; shift;;
*) break;;
esac
done
2020-01-22 10:47:14 +04:00
local use_image
2020-01-30 14:32:44 +04:00
if [ -n "$COMPOSER_PHP_MAX" -a "$COMPOSER_PHP_MAX" != none ]; then
# Vérifier la version de PHP
php -r '
$version = $argv[1];
if (strpos($version, ".") !== false) {
$version = explode(".", $version);
$version = $version[0] * 10000 + $version[1] * 100 + (isset($version[2])? $version[2]: 0);
}
exit((PHP_VERSION_ID > $version)? 0: 1);
' -- "$COMPOSER_PHP_MAX" && use_image=1
fi
if [ -n "$use_image" ]; then
: # ok, on a déjà décidé qu'il faut utiliser une image
elif [ -z "$COMPOSER_PHP" ]; then
2020-01-22 10:47:14 +04:00
# pas de version minimum, tester simplement la valeur de COMPOSER_IMAGE
[ "$COMPOSER_IMAGE" != none ] && use_image=1
elif [ "$COMPOSER_PHP" == force -o "$COMPOSER_PHP" == any ]; then
use_image=1
2019-10-03 19:20:32 +04:00
else
2020-01-22 10:47:14 +04:00
# Vérifier la version de PHP
php -r '
$version = $argv[1];
if (strpos($version, ".") !== false) {
$version = explode(".", $version);
$version = $version[0] * 10000 + $version[1] * 100 + (isset($version[2])? $version[2]: 0);
}
exit((PHP_VERSION_ID < $version)? 0: 1);
' -- "$COMPOSER_PHP" && use_image=1
fi
if [ -n "$use_image" ]; then
[ "$COMPOSER_IMAGE" != none ] || die "Vous devez spécifier l'image à utiliser pour composer"
2019-10-03 19:20:32 +04:00
local PREVIOUS_DOCKER_MACHINE_NAME="$DOCKER_MACHINE_NAME"
if [ -n "$COMPOSER_MACHINE" -a "$DOCKER_MACHINE_NAME" != "$COMPOSER_MACHINE" ]; then
local -x DOCKER_TLS_VERIFY= DOCKER_HOST= DOCKER_CERT_PATH= DOCKER_MACHINE_NAME=
if [ "$COMPOSER_MACHINE" != -u ]; then
local env
setx env=docker-machine env "$COMPOSER_MACHINE" 2>/dev/null || {
eerror "$COMPOSER_MACHINE: une erreur s'est produite lors de la sélection du noeud avec docker-machine"
return 1
}
eval "$env"
fi
fi
docker_composer "$@"
2020-01-22 10:47:14 +04:00
else
local_composer "$@"
2019-10-03 19:20:32 +04:00
fi
}
2019-10-02 22:04:10 +04:00
################################################################################
2019-12-03 06:39:00 +04:00
# support limité docker / podman
if progexists docker; then DOCKER=docker
elif progexists podman; then DOCKER=podman
else DOCKER=docker
fi
2018-10-01 09:28:20 +04:00
DEFAULT_PROFILE=devel
# pour le moment ne pas lancer composer dans un container par défaut
2020-01-21 22:15:09 +04:00
DEFAULT_COMPOSER_IMAGE=none #docker.univ-reunion.fr/image/apache-php-myiccas-utils:d9
2018-10-01 20:49:00 +04:00
PROFILE=
2018-11-16 16:25:33 +04:00
DM_PROFILES=()
2018-10-01 09:28:20 +04:00
set_defaults dk
2018-11-16 14:16:16 +04:00
export PROFILE
2018-10-01 09:28:20 +04:00
chdir=
CONFIG=
DM_SET_MACHINE=
2019-06-01 14:34:20 +04:00
USE_STACK=
FAKE=
2020-02-14 11:18:32 +04:00
VARS=()
FORCE=
2018-11-22 15:34:07 +04:00
NO_CACHE=
HOST=
2019-06-01 14:34:20 +04:00
WITH_REGISTRY_AUTH=1
2019-04-02 15:59:47 +04:00
update_apps_mode=ub
update_apps_devel=
2019-04-02 15:59:47 +04:00
update_apps_origin=
update_apps_branch=
args=(
--help '$exit_with display_help'
-d:,--chdir: chdir=
-c:,--config: CONFIG=
2018-11-16 14:16:16 +04:00
-p:,--profile: PROFILE=
-P,--prod PROFILE=prod
-T,--test PROFILE=test
-m:,--set-machine: DM_SET_MACHINE=
2019-06-01 14:34:20 +04:00
--stack USE_STACK=1
-n,--fake FAKE=1
2020-02-14 11:18:32 +04:00
-e:,--build-arg:,--env: VARS
-f,--force FORCE=1
2018-11-22 15:34:07 +04:00
-j,--no-cache NO_CACHE=1
-h:,--host: HOST=
2019-04-02 15:59:47 +04:00
-g,--ug,--no-update-apps update_apps_mode=b
-u,--uu,--update-apps-only update_apps_mode=u
-w,--uw,--update-apps-devel update_apps_devel=1
2019-04-02 15:59:47 +04:00
--uo:,--update-apps-origin: update_apps_origin=
--ub:,--update-apps-branch: update_apps_branch=
2019-06-01 14:34:20 +04:00
-l,--without-registry-auth WITH_REGISTRY_AUTH=
)
parse_args "$@"; set -- "${args[@]}"
progexists docker-machine && DM_AVAILABLE=1 || DM_AVAILABLE=
if [ -n "$DM_SET_MACHINE" ]; then
[ -n "$DM_AVAILABLE" ] || die "docker-machine n'est pas disponible"
2019-10-02 22:04:10 +04:00
[ "$DM_SET_MACHINE" == - ] && DM_SET_MACHINE=-u
setx dm_env=docker-machine env "$DM_SET_MACHINE" || die
eval "$dm_env"
fi
if [ -n "$DM_AVAILABLE" ]; then
for dm_profile in "${DM_PROFILES[@]}"; do
splitpair "$dm_profile" dm profile
if [ "$dm" == "$DOCKER_MACHINE_NAME" ]; then
DEFAULT_PROFILE="$profile"
break
fi
done
fi
2018-09-27 21:51:33 +04:00
# construire par défaut
[ $# -eq 0 ] && set -- build
2018-11-16 14:16:16 +04:00
[ -n "$PROFILE" ] || PROFILE="$DEFAULT_PROFILE"
2018-10-01 09:28:20 +04:00
[ -n "$chdir" ] && { cd "$chdir" || die; }
update_apps_mode="${update_apps_mode}${update_apps_devel:+w}"
2018-09-27 21:51:33 +04:00
2019-08-14 17:29:30 +04:00
[ -f .dk.scripts.sh ] && source ./.dk.scripts.sh
[ -f dk.scripts.sh ] && source ./dk.scripts.sh
while [ $# -gt 0 ]; do
[ "$1" == -- ] && { shift; continue; }
cmd="$1"; shift
case "$cmd" in
2019-11-21 08:55:09 +04:00
get-profile|get_profile|profile)
echo "$PROFILE"
exit 0
;;
2018-09-27 21:46:24 +04:00
b|build)
2019-10-02 22:04:10 +04:00
build_set_options "$update_apps_mode" "$update_apps_origin" "$update_apps_branch"
[ -f .build.scripts.sh ] && source ./.build.scripts.sh
[ -f build.scripts.sh ] && source ./build.scripts.sh
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
2018-11-16 14:16:16 +04:00
enote "Profil $PROFILE"
auto_build "${args[@]}" || die
;;
p|push)
[ -f .build.scripts.sh ] && source ./.build.scripts.sh
[ -f build.scripts.sh ] && source ./build.scripts.sh
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
2018-11-16 14:16:16 +04:00
enote "Profil $PROFILE"
auto_push "${args[@]}" || die
;;
2019-06-24 23:57:02 +04:00
s|start)
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
2018-11-16 14:16:16 +04:00
enote "Profil $PROFILE"
auto_up "${args[@]}" || die
;;
2018-09-27 21:46:24 +04:00
k|stop)
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
2018-11-16 14:16:16 +04:00
enote "Profil $PROFILE"
auto_stop "${args[@]}" || die
;;
2018-09-27 21:46:24 +04:00
1|up)
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
2018-11-16 14:16:16 +04:00
enote "Profil $PROFILE"
auto_up "${args[@]}" && auto_logs || die
;;
l|logs)
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_logs "${args[@]}" || die
;;
0|down)
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_down "${args[@]}" || die
;;
2019-06-24 23:57:02 +04:00
r|run)
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_run "${args[@]}" || die
;;
x|exec)
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_exec "${args[@]}" || die
;;
2018-09-27 21:46:24 +04:00
d|brd)
do_auto_down=1
function auto_down_trap() {
[ -n "$do_auto_down" ] && auto_down
}
trap auto_down_trap 1 3 15 EXIT
2019-10-02 22:04:10 +04:00
build_set_options "$update_apps_mode" "$update_apps_origin" "$update_apps_branch"
2018-11-14 14:28:24 +04:00
[ -f .build.scripts.sh ] && source ./.build.scripts.sh
[ -f build.scripts.sh ] && source ./build.scripts.sh
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
2018-11-16 14:16:16 +04:00
enote "Profil $PROFILE"
if auto_build; then
auto_up "${args[@]}" && auto_logs || die
else
do_auto_down=
fi
;;
2018-12-09 22:33:07 +04:00
bs)
2019-10-02 22:04:10 +04:00
build_set_options "$update_apps_mode" "$update_apps_origin" "$update_apps_branch"
2018-12-09 22:33:07 +04:00
[ -f .build.scripts.sh ] && source ./.build.scripts.sh
[ -f build.scripts.sh ] && source ./build.scripts.sh
2019-06-01 14:34:20 +04:00
USE_STACK=1
2018-12-09 22:33:07 +04:00
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_build && auto_up "${args[@]}"
;;
2019-06-24 23:57:02 +04:00
br)
2019-10-02 22:04:10 +04:00
build_set_options "$update_apps_mode" "$update_apps_origin" "$update_apps_branch"
2019-06-24 23:57:02 +04:00
[ -f .build.scripts.sh ] && source ./.build.scripts.sh
[ -f build.scripts.sh ] && source ./build.scripts.sh
USE_STACK=1
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_build && auto_run "${args[@]}"
;;
2019-06-01 14:34:20 +04:00
y|deploy)
USE_STACK=1
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_deploy "${args[@]}" || die
;;
by|bd)
2019-10-02 22:04:10 +04:00
build_set_options "$update_apps_mode" "$update_apps_origin" "$update_apps_branch"
2019-06-01 14:34:20 +04:00
[ -f .build.scripts.sh ] && source ./.build.scripts.sh
[ -f build.scripts.sh ] && source ./build.scripts.sh
USE_STACK=1
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_build && auto_deploy "${args[@]}"
;;
2019-06-05 10:13:20 +04:00
bp)
2019-10-02 22:04:10 +04:00
build_set_options "$update_apps_mode" "$update_apps_origin" "$update_apps_branch"
2019-06-05 10:13:20 +04:00
[ -f .build.scripts.sh ] && source ./.build.scripts.sh
[ -f build.scripts.sh ] && source ./build.scripts.sh
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_build && auto_push "${args[@]}"
;;
2019-06-01 14:34:20 +04:00
bpy|bpd)
2019-10-02 22:04:10 +04:00
build_set_options "$update_apps_mode" "$update_apps_origin" "$update_apps_branch"
2019-06-01 14:34:20 +04:00
[ -f .build.scripts.sh ] && source ./.build.scripts.sh
[ -f build.scripts.sh ] && source ./build.scripts.sh
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_build && auto_push && auto_deploy "${args[@]}"
;;
2020-03-20 22:51:05 +04:00
ser|service)
2019-06-05 10:13:20 +04:00
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_service "${args[@]}" || die
;;
2020-03-26 16:40:37 +04:00
sta|status)
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_status "${args[@]}" || die
;;
2019-06-05 10:13:20 +04:00
u|update)
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_service update "${args[@]}" || die
;;
scale)
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_service scale "${args[@]}" || die
;;
2019-04-17 02:31:09 +04:00
ip|show-ip)
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_show_ip "${args[@]}" || die
;;
2019-04-10 07:25:20 +04:00
systemd-unit|systemd)
2019-03-28 10:53:50 +04:00
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
2019-04-10 07:25:20 +04:00
auto_systemd_unit "${args[@]}" || die
2019-03-28 10:53:50 +04:00
;;
ps)
pscmd=(
2019-12-03 06:39:00 +04:00
"$DOCKER" container ps -a
2019-09-18 00:35:10 +04:00
--format "table {{.ID}}\t{{.Image}}\t{{.Names}}\t{{.Status}}\t{{.RunningFor}}\t{{.Ports}}"
)
filtercmd=(cat)
awkscript='
NR == 1 { print; next }
($2 ~ filter || $3 ~ filter) { print }
'
if [ $# -eq 0 ]; then
# pas de filtre
:
elif [ "$1" == -- ]; then
# fin de la commande
shift
elif [[ "$1" == *=* ]]; then
# filtre docker
pscmd+=(--filter "$1")
shift
else
# expression régulière
filtercmd=(awk -v filter="$1" "$awkscript")
shift
fi
set -o pipefail
"${pscmd[@]}" | "${filtercmd[@]}" || die
;;
ls)
lscmd=(docker image ls)
filtercmd=(cat)
awkscript='
BEGIN {
if (split(filter, parts, /:/) > 1) {
filter = parts[1]
tag = parts[2]
} else {
tag = ""
}
}
NR == 1 { print; next }
(filter == "" || $1 ~ filter) && (tag == "" || $2 ~ tag) { print }
'
if [ $# -eq 0 ]; then
# pas de filtre
:
elif [ "$1" == -- ]; then
# fin de la commande
shift
elif [[ "$1" == *=* ]]; then
# filtre docker
lscmd+=(--filter "$1")
shift
else
# expression régulière
filtercmd=(awk -v filter="$1" "$awkscript")
shift
fi
set -o pipefail
"${lscmd[@]}" | "${filtercmd[@]}" || die
;;
pull)
lscmd=(docker image ls)
filtercmd=(awk 'NR == 1 { print; next } $2 !~ /</ { print }')
awkscript='
BEGIN {
if (split(filter, parts, /:/) > 1) {
filter = parts[1]
tag = parts[2]
} else {
tag = ""
}
}
NR == 1 { print; next }
(filter == "" || $1 ~ filter) && (tag == "" || $2 ~ tag) && $2 !~ /</ { print }
'
if [ $# -eq 0 -o "$1" == -- ]; then
# pas de filtre
ewarn "pull: Vous devez spécifier l'image à mettre à jour"
continue
elif [[ "$1" == *=* ]]; then
# filtre docker
lscmd+=(--filter "$1")
shift
else
# expression régulière
filtercmd=(awk -v filter="$1" "$awkscript")
shift
fi
all="$("${lscmd[@]}" | "${filtercmd[@]}")"
setx -a images awk 'NR == 1 { next } { print $1 ":" $2 }' <<<"$all"
if [ ${#images[*]} -gt 0 ]; then
echo "$all"
ask_yesno "Etes-vous sûr de vouloir mettre à jour ces images?" O || die
for image in "${images[@]}"; do
2019-12-03 06:39:00 +04:00
"$DOCKER" pull "$image" || die
done
fi
;;
rm)
lscmd=(docker image ls)
filtercmd=(cat)
awkscript='
BEGIN {
if (split(filter, parts, /:/) > 1) {
filter = parts[1]
tag = parts[2]
} else {
tag = ""
}
}
NR == 1 { print; next }
(filter == "" || $1 ~ filter) && (tag == "" || $2 ~ tag) { print }
'
if [ $# -eq 0 -o "$1" == -- ]; then
# pas de filtre
ewarn "rm: Vous devez spécifier l'image à supprimer"
continue
elif [[ "$1" == *=* ]]; then
# filtre docker
lscmd+=(--filter "$1")
shift
else
# expression régulière
filtercmd=(awk -v filter="$1" "$awkscript")
shift
fi
all="$("${lscmd[@]}" | "${filtercmd[@]}")"
setx -a images awk 'NR == 1 { next } { if ($1 == "<none>" || $2 == "<none>") { print $3 } else { print $1 ":" $2 } }' <<<"$all"
if [ ${#images[*]} -gt 0 ]; then
echo "$all"
ask_yesno "Etes-vous sûr de vouloir supprimer ces images?" || die
2019-12-03 06:39:00 +04:00
"$DOCKER" image rm ${FORCE:+--force} "${images[@]}" || die
fi
;;
2018-09-27 21:46:24 +04:00
X|prune)
2019-12-03 06:39:00 +04:00
"$DOCKER" container prune -f || die
"$DOCKER" image prune -f || die
;;
2020-01-22 10:47:14 +04:00
composer|c|ci|cu|cr|cs)
2019-10-02 22:04:10 +04:00
build_set_options "$update_apps_mode" "$update_apps_origin" "$update_apps_branch"
[ -f .build.scripts.sh ] && source ./.build.scripts.sh
[ -f build.scripts.sh ] && source ./build.scripts.sh
args=()
if [ "$cmd" == ci ]; then args+=(install)
elif [ "$cmd" == cu ]; then args+=(update)
2020-01-22 10:47:14 +04:00
elif [ "$cmd" == cr ]; then args+=(rshell)
2019-10-02 22:16:40 +04:00
elif [ "$cmd" == cs ]; then args+=(shell)
2019-10-02 22:04:10 +04:00
fi
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
auto_composer "${args[@]}"
;;
2020-03-20 22:51:05 +04:00
_*|*_)
# transmettre directement à docker
cmd="${cmd#_}"
cmd="${cmd%_}"
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
"$DOCKER" "$cmd" "${args[@]}"
;;
*)
2020-03-20 22:51:05 +04:00
# transmettre directement à docker
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
"$DOCKER" "$cmd" "${args[@]}"
esac
done