#!/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 function display_help() { uecho "$scriptname: outil pour faciliter l'utilisation de docker USAGE $scriptname CMDs... COMMANDES build Construire les images push Pousser les images vers le serveur start, run [SERVICE] Démarrer le(s) service(s) stop [SERVICE] Arrêter le(s) service(s) up Créer l'environnement, démarrer les services et suivre les logs de façon interactive. logs [SERVICE] Afficher les logs down Arrêter les services et supprimer l'environnement brd 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) bs Construire les images (comme avec build) puis démarrer les services (comme avec start) ip [SERVICE] Afficher l'adresse IP interne du service exec SERVICE COMMAND Lancer la commande dans le container spécifié systemd-unit 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 Afficher les containers en cours d'exécution ls Lister les images actuellement présentes rm Supprimer une image prune Supprimer les containers et les images inutilisées OPTIONS générales (ces options sont communes à toutes les commandes) -d, --chdir PROJDIR -p, --profile PROFILE -P, --prod -T, --test -n, --fake -j, --no-cache -h, --host HOST OPTIONS build (ces options ne sont valides que pour les commandes build, brd, bs) -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_BRANCH= APPS=() # liste d'applications à mettre à jour app_URL= # url du dépôt app_DEST= # répertoire dans lequel faire le checkout app_PROFILE_ORIGIN= # origine spécifique à un profil app_PROFILE_BRANCH= # branche spécifique à un profil app_ORIGIN= # ou... origine par défaut de la branche app_BRANCH= # ou... branche par défaut app_TYPE= # type de projet (composer par défaut) app_AFTER_UPDATE=() # liste de commandes à lancer après le checkout -u, --uu, --update-apps-only Ne faire que la mise à jour depuis les dépôts dépendants. --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 VARIABLES de update-apps.conf 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 'inconnu' 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_ FONCTIONS de update-apps.conf sqlmig [DESTDIR [SRCDIR]] Copier les définitions des bases de données au format sqlmig de SRCDIR/config/sqlmig vers DESTDIR/config/mariadb/sqlmig" } 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/([^=]+)=(.*)/replace_build_args+=(--build-arg \1="\2"); \1="\2"/' } 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)" [ -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 [ -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" 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 } function compose_set_env_args() { replace_env_args+=(-f docker-compose.yml) if [ -f docker-compose.override.yml ]; then replace_env_args+=(-f docker-compose.override.yml) fi local PROJECT_NAME=--none-- [ -f .compose.env ] && source ./.compose.env if [ -n "$PROFILE" ]; then if [ -f "docker-compose.$PROFILE.yml" ]; then replace_env_args+=(-f "docker-compose.$PROFILE.yml") fi if [ "$PROJECT_NAME" != --none-- ]; then if [ -z "$COMPOSE_PROJECT_NAME" ]; then [ -n "$PROJECT_NAME" ] || PROJECT_NAME="$(basename -- "$(pwd)")" COMPOSE_PROJECT_NAME="${PROJECT_NAME}_${PROFILE}" fi export COMPOSE_PROJECT_NAME fi fi if [ "$1" == set_container_name ]; then if [ "$PROJECT_NAME" == --none-- ]; then project_name="$(basename -- "$(pwd)")" else project_name="$PROJECT_NAME" fi container_name="${project_name//[^a-zA-Z0-9_-]/}" [ -n "$PROFILE" ] && container_name="${container_name}_$PROFILE" fi } function host_run() { # lancer le script $2..@ sur l'hôte $1 # 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 # 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 if [ -n "$host" -a "$host" != localhost ]; then if check_hostname "$host"; then estep "Lancement de $script localement" runscript_as_root "$script" "$@" elif progexists docker-machine; then local dm; setx dm=docker-machine active 2>/dev/null if [ "${host%%.*}" == "$dm" ]; then 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 ($dm) n'est pas la destination ($host)" 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" "$@" } BUILD_UPDATE_APPS= BUILD_BUILD= UPDATE_APPS_ORIGIN= UPDATE_APPS_BRANCH= function build_set_options() { case "$1" in u) BUILD_UPDATE_APPS=1; BUILD_BUILD=;; b) BUILD_UPDATE_APPS=; BUILD_BUILD=1;; *) BUILD_UPDATE_APPS=1; BUILD_BUILD=1;; esac UPDATE_APPS_ORIGIN="$2" UPDATE_APPS_BRANCH="$3" } function update_apps_func_sqlmig() { local destdir="$1" srcdir="$2" [ -n "$destdir" ] || destdir=db [ "${destdir%/config/mariadb/sqlmig}" != "$destdir" ] || destdir="$destdir/config/mariadb/sqlmig" [ -n "$srcdir" ] || srcdir="$dest" [ "${srcdir%/config/sqlmig}" != "$srcdir" ] || srcdir="$srcdir/config/sqlmig" [ -d "$srcdir" ] || return 0 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 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 APPS=() [ -f update-apps.conf ] && source ./update-apps.conf [ ${#APPS[*]} -gt 0 ] || return 0 local PRODUCTION DEVELOPMENT case "$PROFILE" in prod) PRODUCTION=1; DEVELOPMENT=;; test) PRODUCTION=1; DEVELOPMENT=1;; devel) PRODUCTION=; DEVELOPMENT=;; esac etitle "Mise à jour des dépendances" local app type url dest branch after_update after_updates for app in "${APPS[@]}"; do etitle "$app" url="${app}_URL"; url="${!url}" [ -n "$url" ] || { ewarn "$app: vous devez définir l'url" eend; return 1 } dest="${app}_DEST"; dest="${!dest}" [ -n "$dest" ] || dest="$app/b" mkdir -p "$dest" || { eend; return 1; } origin="${app}_${PROFILE}_ORIGIN"; origin="${!origin}" [ -n "$origin" ] || { origin="${app}_ORIGIN"; origin="${!origin}"; } [ -n "$origin" ] || origin="$DEFAULT_ORIGIN" branch="${app}_${PROFILE}_BRANCH"; branch="${!branch}" [ -n "$branch" ] || { branch="${app}_BRANCH"; branch="${!branch}"; } [ -n "$branch" ] || branch="$DEFAULT_BRANCH" type="${app}_TYPE"; type="${!type}" if [ -z "$type" ]; then if [ -f "$dest/composer.json" ]; then type=composer else type=inconnu fi fi after_updates="${app}_AFTER_UPDATE" if is_defined "$after_updates"; then after_updates="$after_updates[@]"; after_updates="${!after_updates}" elif [ "$type" == composer ]; then after_updates=(sqlmig) else after_updates=() fi dest="$dest/$app" if [ ! -d "$dest" ]; then # clonage initial estep "Clonage $url:$branch --> $dest" git clone -o "$origin" -b "$branch" "$url" "$dest" || { eend; return 1; } else # mise à jour estep "Maj dépôt $url:$branch --> $dest" setx cwd=pwd cd "$dest" git fetch --all -p -f || { eend; return 1; } git reset --hard "$origin/$branch" || { eend; return 1; } cd "$cwd" fi estep "Type de dépôt: $type" if [ "$type" == composer ]; then composer=/usr/bin/composer [ -x "$dest/composer.phar" ] && composer="$dest/composer.phar" estep "Installation des dépendances composer" "$composer" -d"$dest" install ${PRODUCTION:+--no-dev -o} || { eend; return 1; } fi for after_update in "${after_updates[@]}"; do if [ "${after_update#/}" != "$after_update" ]; then # commande absolue, la lancer telle quelle estep "$after_update" eval "$after_update" || { eend; return 1; } elif [ "${after_update#./}" != "$after_update" ]; then # commande relative, la lancer telle quelle estep "$after_update" eval "$after_update" || { eend; return 1; } else # c'est une fonction update_apps_func_* estep "$after_update" eval "update_apps_func_$after_update" || { eend; return 1; } fi done eend done eend } function initialize_build_env() { CTXDIR=. NAME= TAGS=(latest) VERSION= } function default_update_build_env() { [ -n "$VERSION" ] || docker_add_build_arg VERSION "$(get_version)" [ -n "$VERSION" ] && TAGS+=("$VERSION") } 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 ${FAKE:+qvals} docker build \ ${NO_CACHE:+--no-cache} \ "${replace_env_args[@]}" "${env_args[@]}" \ "${replace_build_args[@]}" "${build_args[@]}" \ "$@" "$CTXDIR" } 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 build_update_apps || return 1 compose_build else docker_parse_env_args docker_check_name docker_add_build_arg build_date "$(date +%y%m%d)" update_build_env build_update_apps || return 1 docker_build fi } function auto_push() { local -a replace_env_args env_args local -a replace_build_args build_args local tag initialize_build_env if [ -f docker-compose.yml ]; then compose_set_env_args update_build_env else docker_parse_env_args docker_check_name update_build_env fi for tag in "${TAGS[@]}"; do ${FAKE:+qvals} docker push "$NAME:$tag" done } 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() { ${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 local project_name container_name if [ -f docker-compose.yml ]; then compose_set_env_args replace_run_args=(-d) compose_up "$@" else docker_set_env_args docker_check_name set_container_name replace_run_args=(-d --name "$container_name") docker_up "$@" fi } function default_compose_stop() { ${FAKE:+qvals} docker-compose \ "${replace_env_args[@]}" "${env_args[@]}" \ stop "${replace_stop_args[@]}" "${stop_args[@]}" \ "$@" } function default_docker_stop() { ${FAKE:+qvals} docker container stop \ "${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 "$@" else docker_set_env_args docker_check_name set_container_name docker_stop "$@" fi } function default_compose_logs() { ${FAKE:+qvals} docker-compose \ "${replace_env_args[@]}" "${env_args[@]}" \ logs "${replace_logs_args[@]}" "${logs_args[@]}" \ "$@" } function default_docker_logs() { ${FAKE:+qvals} docker logs \ "${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 "$@" else docker_set_env_args docker_check_name set_container_name replace_logs_args=(-f) docker_logs "$@" 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" ${FAKE:+qvals} docker container stop \ "${replace_down_args[@]}" "${down_args[@]}" \ "$container_name" "$@" estep "rm" ${FAKE:+qvals} docker container rm \ "${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 "$@" else docker_set_env_args docker_check_name set_container_name docker_down "$@" fi } 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 docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$cid" done fi } function default_docker_show_ip() { ${FAKE:+qvals} docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \ "${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 } function default_compose_exec() { ${FAKE:+qvals} docker-compose \ "${replace_env_args[@]}" "${env_args[@]}" \ exec "${replace_exec_args[@]}" "${exec_args[@]}" \ "$@" } function default_docker_exec() { ${FAKE:+qvals} docker container exec \ "${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 "$@" else docker_set_env_args docker_check_name set_container_name docker_exec "$@" fi } function default_compose_systemd_unit() { 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 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 } function default_docker_systemd_unit() { local docker="$(which docker 2>/dev/null)" 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 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" } function compose_systemd_unit() { default_compose_systemd_unit "$@"; } function docker_systemd_unit() { default_docker_systemd_unit "$@"; } function auto_systemd_unit() { 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 estep "Génération de l'unité systemd" export COMPOSE_PROJECT_NAME= if [ -f docker-compose.yml ]; then compose_set_env_args set_container_name replace_run_args=(-d --no-color) compose_systemd_unit "$@" 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") docker_systemd_unit "$@" fi [ -n "$COMPOSE_PROJECT_NAME" ] || COMPOSE_PROJECT_NAME="$project_name" chmod 755 "$tmpscript" cat >"$tmpscript" </etc/systemd/system/$container_name.service </dev/null for dm_profile in "${DM_PROFILES[@]}"; do splitpair "$dm_profile" dm profile if [ "$dm" == "$active_dm" ]; then DEFAULT_PROFILE="$profile" break fi done fi chdir= FAKE= NO_CACHE= HOST= update_apps_mode=ub update_apps_origin= update_apps_branch= args=( --help '$exit_with display_help' -d:,--chdir: chdir= -p:,--profile: PROFILE= -P,--prod PROFILE=prod -T,--test PROFILE=test -n,--fake FAKE=1 -j,--no-cache NO_CACHE=1 -h:,--host: HOST= -g,--ug,--no-update-apps update_apps_mode=b -u,--uu,--update-apps-only update_apps_mode=u --uo:,--update-apps-origin: update_apps_origin= --ub:,--update-apps-branch: update_apps_branch= ) parse_args "$@"; set -- "${args[@]}" # construire par défaut [ $# -eq 0 ] && set -- build [ -n "$PROFILE" ] || PROFILE="$DEFAULT_PROFILE" [ -n "$chdir" ] && { cd "$chdir" || die; } while [ $# -gt 0 ]; do [ "$1" == -- ] && { shift; continue; } cmd="$1"; shift case "$cmd" in b|build) 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 enote "Profil $PROFILE" auto_build "${args[@]}" || die ;; 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 enote "Profil $PROFILE" auto_push "${args[@]}" || die ;; s|run|start) args=() while [ $# -gt 0 -a "$1" != -- ]; do args+=("$1"); shift done enote "Profil $PROFILE" auto_up "${args[@]}" || die ;; k|stop) args=() while [ $# -gt 0 -a "$1" != -- ]; do args+=("$1"); shift done enote "Profil $PROFILE" auto_stop "${args[@]}" || die ;; 1|up) args=() while [ $# -gt 0 -a "$1" != -- ]; do args+=("$1"); shift done 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 ;; d|brd) do_auto_down=1 function auto_down_trap() { [ -n "$do_auto_down" ] && auto_down } trap auto_down_trap 1 3 15 EXIT 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 enote "Profil $PROFILE" if auto_build; then auto_up "${args[@]}" && auto_logs || die else do_auto_down= fi ;; bs) 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 enote "Profil $PROFILE" auto_build && auto_up "${args[@]}" ;; ip|show-ip) args=() while [ $# -gt 0 -a "$1" != -- ]; do args+=("$1"); shift done enote "Profil $PROFILE" auto_show_ip "${args[@]}" || die ;; x|exec) args=() while [ $# -gt 0 -a "$1" != -- ]; do args+=("$1"); shift done enote "Profil $PROFILE" auto_exec "${args[@]}" || die ;; systemd-unit|systemd) args=() while [ $# -gt 0 -a "$1" != -- ]; do args+=("$1"); shift done enote "Profil $PROFILE" auto_systemd_unit "${args[@]}" || die ;; ps) docker container ps -a || die;; ls) docker image ls || die;; rm) args=() while [ $# -gt 0 -a "$1" != -- ]; do args+=("$1"); shift done docker image rm "${args[@]}" || die ;; X|prune) docker container prune -f || die docker image prune -f || die ;; *) die "$cmd: commande inconnue";; esac done