Compare commits

...

30 Commits

Author SHA1 Message Date
Jephté Clain eb3979de4d Intégration de la branche release-9.4.0 2019-06-05 10:15:32 +04:00
Jephté Clain 991f94b48c Init changelog & version 9.4.0 2019-06-05 10:15:32 +04:00
Jephté Clain fb96852bf6 Intégration de la branche dk-deploy 2019-06-05 10:14:23 +04:00
Jephté Clain 386fc0d070 implémenter service, update, scale 2019-06-05 10:14:08 +04:00
Jephté Clain c2f43e6b6d optimiser l'utilisation de docker-machine 2019-06-05 10:14:08 +04:00
Jephté Clain 8cb3b2fc57 ajouter la commande deploy 2019-06-05 10:14:07 +04:00
Jephté Clain 5967541159 cx-updatedev: ajouter l'option -j 2019-06-03 09:41:29 +04:00
Jephté Clain d79e218dfc dk: support de push pour docker-compose 2019-05-31 17:14:59 +04:00
Jephté Clain ccbfff4366 dk: simplifier la gestion du nommage des services 2019-05-31 15:42:11 +04:00
Jephté Clain 50dee34e6f dk: support de build d'un service en particulier 2019-05-30 23:25:34 +04:00
Jephté Clain 99d5069b55 bug 2019-05-30 22:43:23 +04:00
Jephté Clain a825f3b931 bug 2019-05-27 10:07:18 +04:00
Jephté Clain 8c143e16c3 foreach: ajout de --cc 2019-05-27 10:00:33 +04:00
Jephté Clain 7e26ae1e0c foreach: ajout des raccourcis -G et -C 2019-05-26 23:05:59 +04:00
Jephté Clain cbb34ecd3f cx-conndev: afficher les erreurs 2019-05-24 11:49:11 +04:00
Jephté Clain 7524a2869a cosmetic 2019-05-22 23:07:41 +04:00
Jephté Clain 9b03dcd69f cx-updatedev: ajout de -i et -u 2019-05-22 23:04:52 +04:00
Jephté Clain c7eca6ae7d cx-updatedev: ajout des options -l et -c 2019-05-21 10:54:54 +04:00
Jephté Clain 8b4067ab49 bug 2019-05-21 09:50:42 +04:00
Jephté Clain 3971dca710 scripts pour gérer projets composer 2019-05-21 09:40:15 +04:00
Jephté Clain c66eee117e scripts pour gérer projets composer 2019-05-21 09:31:23 +04:00
Jephté Clain 7c135faa60 fconv, fnconv: support de sed 2019-05-18 07:44:46 +04:00
Jephté Clain 72c3512072 dk: bug dans la détection du type de projet 2019-05-10 16:29:30 +04:00
Jephté Clain 0891e89278 sqlmig: corriger la lecture des paramètres 2019-05-09 12:48:17 +04:00
Jephté Clain d197fc0420 sqlmig: support de l'importation directe des fichiers csv 2019-05-09 12:21:07 +04:00
Jephté Clain d028c47842 dk: maj doc et support d'origine de profil 2019-05-02 13:46:08 +04:00
Jephté Clain b068a12c02 dk: maj doc et support de branche de profil 2019-05-02 13:39:24 +04:00
Jephté Clain d7c981d257 dk: afficher l'adresse ip 2019-04-17 02:31:09 +04:00
Jephté Clain 7ec538187b dk: renommer service en systemd-unit 2019-04-10 07:25:20 +04:00
Jephté Clain 43c5445603 Intégration de la branche release-9.3.0 2019-04-02 16:03:38 +04:00
11 changed files with 1064 additions and 183 deletions

View File

@ -1,3 +1,33 @@
## Version 9.4.0 du 05/06/2019-10:15
* `fb96852` Intégration de la branche dk-deploy
* `386fc0d` implémenter service, update, scale
* `c2f43e6` optimiser l'utilisation de docker-machine
* `8cb3b2f` ajouter la commande deploy
* `5967541` cx-updatedev: ajouter l'option -j
* `d79e218` dk: support de push pour docker-compose
* `ccbfff4` dk: simplifier la gestion du nommage des services
* `50dee34` dk: support de build d'un service en particulier
* `99d5069` bug
* `a825f3b` bug
* `8c143e1` foreach: ajout de --cc
* `7e26ae1` foreach: ajout des raccourcis -G et -C
* `cbb34ec` cx-conndev: afficher les erreurs
* `7524a28` cosmetic
* `9b03dcd` cx-updatedev: ajout de -i et -u
* `c7eca6a` cx-updatedev: ajout des options -l et -c
* `8b4067a` bug
* `3971dca` scripts pour gérer projets composer
* `c66eee1` scripts pour gérer projets composer
* `7c135fa` fconv, fnconv: support de sed
* `72c3512` dk: bug dans la détection du type de projet
* `0891e89` sqlmig: corriger la lecture des paramètres
* `d197fc0` sqlmig: support de l'importation directe des fichiers csv
* `d028c47` dk: maj doc et support d'origine de profil
* `b068a12` dk: maj doc et support de branche de profil
* `d7c981d` dk: afficher l'adresse ip
* `7ec5381` dk: renommer service en systemd-unit
## Version 9.3.0 du 02/04/2019-16:03 ## Version 9.3.0 du 02/04/2019-16:03
* `6a03853` ajout de update-apps en natif * `6a03853` ajout de update-apps en natif

14
TODO.md
View File

@ -1,3 +1,17 @@
# TODO # TODO
## dk
Ajouter le support du déploiement de services dans un swarm
Les nouvelles actions suivantes sont disponibles:
* deploy -- déployer un service
* bpd -- équivalent à build, push, deploy
* update -- mettre à jour un service déployé
* bpu -- équivalent à build, push, update
* rollback -- annuler la mise à jour d'un service
Pour toutes ces actions, utiliser par défaut docker-stack.yml s'il existe,
sinon utiliser docker-compose.yml (en tenant compte des paramètres des profils)
-*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary -*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary

View File

@ -1 +1 @@
9.3.0 9.4.0

60
cx-conndev Executable file
View File

@ -0,0 +1,60 @@
#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
urequire DEFAULTS
function display_help() {
uecho "$scriptname: se connecter à la base MySQL
USAGE
$scriptname [DATABASE]
OPTIONS
-h, -s, --service SERVICE
Spécifier le nom du service. La valeur par défaut est db"
}
service=db
args=(
--help '$exit_with display_help'
-h:,-s:,--service: service=
)
parse_args "$@"; set -- "${args[@]}"
[ -n "$service" ] || die "Vous devez spécifier le nom du service"
found=
first=1
while true; do
if [ -f composer.json ]; then
found=1
break
fi
first=
cd ..
if [ "$(pwd)" == "$HOME" ]; then
die "Cette commande ne peut être lancée que depuis un projet Composer"
fi
done
if [ -z "$first" ]; then
enote "Le répertoire du projet est $(ppath . ~)"
fi
[ -f bin/conndev.php ] || die "Impossible de trouver le script compagnon conndev.php"
###
function die_not_found() { die "$service: service introuvable"; }
setx cid=docker-compose ps -q "$service" 2>/dev/null || die_not_found
[ -n "$cid" ] || die_not_found
edebug "$service id: $cid"
function die_not_found() { die "$service: $cid: ip introuvable"; }
setx ip=docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$cid" || die_not_found
[ -n "$ip" ] || die_not_found
edebug "$service ip: $ip"
mysqlcmd="$(php bin/conndev.php "$ip" "$@")"
edebug "mysqlcmd: $mysqlcmd"
eval "$mysqlcmd"

56
cx-shelldev Executable file
View File

@ -0,0 +1,56 @@
#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
urequire DEFAULTS
function display_help() {
uecho "$scriptname: ouvrir un shell dans le container
USAGE
$scriptname [SHELL]
OPTIONS
-h, -s, --service SERVICE
Spécifier le nom du service sur lequel ouvrir le shell
-d
équivalent à -s db
-w
équivalent à -s web (c'est la valeur par défaut)"
}
service=web
args=(
--help '$exit_with display_help'
-h:,-s:,--service: service=
-d service=db
-w service=web
)
parse_args "$@"; set -- "${args[@]}"
[ -n "$service" ] || die "Vous devez spécifier le nom du service"
found=
first=1
while true; do
if [ -f composer.json ]; then
found=1
break
fi
first=
cd ..
if [ "$(pwd)" == "$HOME" ]; then
die "Cette commande ne peut être lancée que depuis un projet Composer"
fi
done
if [ -z "$first" ]; then
enote "Le répertoire du projet est $(ppath . ~)"
fi
###
setx cid=docker-compose ps -q "$service" 2>/dev/null || die "$service: service introuvable"
cmd=("$@")
[ ${#cmd[*]} -gt 0 ] || cmd=(bash)
docker-compose exec "$service" "${cmd[@]}"

190
cx-updatedev Executable file
View File

@ -0,0 +1,190 @@
#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
urequire DEFAULTS
function display_help() {
uecho "$scriptname: mettre à jour un module ur/* ou lib/* sans utiliser composer
ça permet de faire du développement plus rapidement sans utiliser les dépôts de
type path
USAGE
$scriptname modules...
OPTIONS
-n, --fake
Afficher simplement ce qui serait fait
-q, --quiet
Ne pas lancer rsync en mode verbose
-l, --link
Transformer les clones de dépôts en liens directs vers les projets
-k, --copy
Transformer les liens directs vers les projets en copies des projets
-i, --install
Supprimer les répertoires et les faire recréer par composer i
-j, --reinstall-link
Supprimer les répertoires et les faire recréer par composer i,
uniquement s'il s'agit de liens
-u, --update
Supprimer les répertoires et les faire recréer par composer u"
}
fake=
verbose=1
action=
args=(
--help '$exit_with display_help'
-n,--fake fake=1
-q,--quiet verbose=
-l,--link action=link
-k,--copy action=copy
-i,--install action=install
-j,--reinstall-link action=reinstall-link
-u,--update action=update
)
parse_args "$@"; set -- "${args[@]}"
found=
first=1
while true; do
if [ -f composer.json ]; then
found=1
break
fi
first=
cd ..
if [ "$(pwd)" == "$HOME" ]; then
die "Cette commande ne peut être lancée que depuis un projet Composer"
fi
done
if [ -z "$first" ]; then
enote "Le répertoire du projet est $(ppath . ~)"
fi
case "$action" in
install|update)
[ -x ./composer.phar ] || die "Impossible de trouver composer.phar"
;;
esac
###
if [ $# -eq 0 ]; then
setx -a ms=list_dirs vendor "ur/*" "lib/*"
set -- "${ms[@]}"
fi
function check_module() {
[ -d "../$m" ] || die "$m: module introuvable"
}
function update_with_rsync() {
local -a rsync_args
rsync_args=(
-a ${fake:+-n} ${verbose:+-v}
--delete
-f "- /.git/"
-f "- /vendor/"
"../$m/" "vendor/$p"
)
rsync "${rsync_args[@]}"
}
deps=()
for m in "$@"; do
m="${m#vendor/}" # pour permettre de spécifier le chemin directement
m="${m//\//-}"
case "$m" in
ur-*|lib-*) ;;
*) m="ur-$m";;
esac
p="${m//-/\/}"
check_module
case "$action" in
link)
# Ignorer les liens et transformer les copies en liens
if [ ! -L "vendor/$p" ]; then
link="$m"
path="/project/vendor/$p"
path="${path%/*}"
while [ -n "$path" ]; do
link="../$link"
path="${path%/*}"
done
etitle "$m"
estep "suppr. vendor/$p"
rm -rf "vendor/$p"
mkdirof "vendor/$p"
estep "vendor/$p --> $link"
ln -s "$link" "vendor/$p"
eend
fi
;;
copy)
# Transformer les liens en copie et les synchroniser
etitle "$m"
if [ -L "vendor/$p" ]; then
estep "suppr. vendor/$p"
rm -f "vendor/$p"
fi
update_with_rsync
eend
;;
install)
# Supprimer les liens et répertoires...
etitle "$m"
if [ -e "vendor/$p" ]; then
estep "suppr. vendor/$p"
rm -rf "vendor/$p"
fi
array_add deps "$p"
eend
;;
reinstall-link)
# Supprimer les liens uniquement...
etitle "$m"
if [ -L "vendor/$p" ]; then
estep "suppr. vendor/$p"
rm -f "vendor/$p"
fi
array_add deps "$p"
eend
;;
update)
# Supprimer les liens et répertoires...
etitle "$m"
if [ -e "vendor/$p" ]; then
estep "suppr. vendor/$p"
rm -rf "vendor/$p"
fi
array_add deps "$p"
eend
;;
*)
# Action par défaut: ignorer les liens et synchroniser les copies
if [ ! -L "vendor/$p" ]; then
etitle "$m"
update_with_rsync
eend
fi
;;
esac
done
case "$action" in
install|reinstall-link)
# ... puis installer les dépendances
etitle "Installation des dépendances"
./composer.phar i
eend
;;
update)
# ... puis mettre à jour les dépendances
etitle "Mise à jour des dépendances"
./composer.phar u "${deps[@]}"
eend
;;
esac

513
dk
View File

@ -9,72 +9,150 @@ USAGE
$scriptname CMDs... $scriptname CMDs...
COMMANDES COMMANDES
build b|build [SERVICE]
Construire les images Construire les images
push p|push
Pousser les images vers le serveur p|push [SERVICES...]
start, run [SERVICE] 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.
s|start|run [SERVICE]
Démarrer le(s) service(s) Démarrer le(s) service(s)
stop [SERVICE] k|stop [SERVICE]
Arrêter le(s) service(s) Arrêter le(s) service(s)
up 1|up
Créer l'environnement, démarrer les services et suivre les logs de façon Créer l'environnement, démarrer les services et suivre les logs de façon
interactive. interactive.
logs [SERVICE] Vaguement équivalent à -- start -- logs
l|logs [SERVICE]
Afficher les logs Afficher les logs
down 0|down
Arrêter les services et supprimer l'environnement Arrêter les services et supprimer l'environnement
brd d|brd
Construire les images (comme avec build), démarrer les services et 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 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 arrête l'affichage des logs avec Ctrl+C, arrêter les services et
supprimer l'environnement (comme avec down) supprimer l'environnement (comme avec down)
Vaguement équivalent à -- build -- start [args] -- logs
suivi de -- down
bs bs
Construire les images (comme avec build) puis démarrer les services Construire les images (comme avec build) puis démarrer les services
(comme avec start) (comme avec start)
exec SERVICE COMMAND Equivalent à -- build -- start [args]
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...
Utilisable notamment en développement
bp [args...]
Equivalent à --stack -- build -- push args...
bpy|bpd [args...]
Equivalent à --stack -- build -- push -- deploy args...
service COMMAND SERVICE [args...]
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
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'
ip|show-ip [SERVICE]
Afficher l'adresse IP interne du service
x|exec SERVICE COMMAND
Lancer la commande dans le container spécifié Lancer la commande dans le container spécifié
service systemd|systemd-unit
Générer une unité systemd qui démarre les services 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 ps
Afficher les containers en cours d'exécution Afficher les containers en cours d'exécution
ls ls
Lister les images actuellement présentes Lister les images actuellement présentes
rm rm
Supprimer une image Supprimer une image
prune X|prune
Supprimer les containers et les images inutilisées Supprimer les containers et les images inutilisées
OPTIONS générales OPTIONS générales
(ces options sont communes à toutes les commandes) (ces options sont communes à toutes les commandes)
-d, --chdir PROJDIR -d, --chdir PROJDIR
Spécifier le répertoire du projet
-p, --profile PROFILE -p, --profile PROFILE
-P, --prod -P, --prod
-T, --test -T, --test
Spécifier le profil
-m, --set-machine MACHINE
Choisir l'environnement docker-machine spécifié avant de lancer les
commandes
-n, --fake -n, --fake
-j, --no-cache Ne pas lancer les commandes, simplement les afficher
-h, --host HOST -h, --host HOST
Spécifier l'hôte pour la commande systemd-unit
OPTIONS build OPTIONS build
(ces options ne sont valides que pour les commandes build, brd, bs) (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.
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
-g, --ug, --no-update-apps -g, --ug, --no-update-apps
ne pas mettre à jour les dépôts dépendants. ces dépôts sont ne pas mettre à jour les dépôts dépendants. ces dépôts sont définis dans
définis dans le fichier update-apps.conf qui a le format le fichier update-apps.conf qui a le format suivant:
suivant:
DEFAULT_BRANCH= DEFAULT_BRANCH=
APPS=() APPS=() # liste d'applications à mettre à jour
app_URL= app_URL= # url du dépôt
app_DEST= app_DEST= # répertoire dans lequel faire le checkout
app_ORIGIN= app_PROFILE_ORIGIN= # origine spécifique à un profil
app_BRANCH= app_PROFILE_BRANCH= # branche spécifique à un profil
app_TYPE= app_ORIGIN= # ou... origine par défaut de la branche
app_AFTER_UPDATE=() 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 -u, --uu, --update-apps-only
Ne faire que la mise à jour depuis les dépôts dépendants. Ne faire que la mise à jour depuis les dépôts dépendants.
--uo, --update-apps-origin ORIGIN --uo, --update-apps-origin ORIGIN
Spécifier l'origine par défaut pour update-apps Spécifier l'origine par défaut pour update-apps
--ub, --update-apps-branch BRANCH --ub, --update-apps-branch BRANCH
Spécifier la branche par défaut pour update-apps" Spécifier la branche par défaut pour update-apps
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
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() { function get_version() {
@ -125,6 +203,7 @@ function docker_set_run_args() {
} }
function docker_check_name() { function docker_check_name() {
[ -n "$NAME" ] || die "Vous devez définir NAME dans .build.env" [ -n "$NAME" ] || die "Vous devez définir NAME dans .build.env"
if [ "$1" == set_container_name ]; then if [ "$1" == set_container_name ]; then
project_name="$NAME" project_name="$NAME"
container_name="${project_name//[^a-zA-Z0-9_-]/}" container_name="${project_name//[^a-zA-Z0-9_-]/}"
@ -132,57 +211,89 @@ function docker_check_name() {
fi fi
} }
function compose_set_project_name() {
local PROJECT_NAME= PROJECT_NAME_REMOVE_SUFFIX=.service PROJECT_NAME_ADD_PROFILE=1
[ -f .compose.env ] && source ./.compose.env
[ -n "$PROJECT_NAME" ] || PROJECT_NAME="$(basename -- "$(pwd)")"
PROJECT_NAME="${PROJECT_NAME%$PROJECT_NAME_REMOVE_SUFFIX}"
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
if [ "$1" == set_container_name ]; then
project_name="$PROJECT_NAME"
container_name="${project_name//[^a-zA-Z0-9_-]/}"
[ -n "$PROFILE" -a -n "$PROJECT_NAME_ADD_PROFILE" ] && container_name="${container_name}_$PROFILE"
fi
}
function compose_set_env_args() { function compose_set_env_args() {
replace_env_args+=(-f docker-compose.yml) if [ -n "$USE_STACK" -a -f docker-stack.yml ]; then
if [ -f docker-compose.override.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) replace_env_args+=(-f docker-compose.override.yml)
fi fi
local PROJECT_NAME=--none--
[ -f .compose.env ] && source ./.compose.env
if [ -n "$PROFILE" ]; then if [ -n "$PROFILE" ]; then
if [ -f "docker-compose.$PROFILE.yml" ]; 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") replace_env_args+=(-f "docker-compose.$PROFILE.yml")
fi fi
if [ "$PROJECT_NAME" != --none-- ]; then fi
if [ -z "$COMPOSE_PROJECT_NAME" ]; then
[ -n "$PROJECT_NAME" ] || PROJECT_NAME="$(basename -- "$(pwd)")" compose_set_project_name "$@"
COMPOSE_PROJECT_NAME="${PROJECT_NAME}_${PROFILE}" }
fi function docker_set_deploy_args() {
export COMPOSE_PROJECT_NAME 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_env_args+=(-c "docker-stack.$PROFILE.yml")
elif [ -f "docker-compose.$PROFILE.yml" ]; then
replace_env_args+=(-c "docker-compose.$PROFILE.yml")
fi fi
fi fi
if [ "$1" == set_container_name ]; then
if [ "$PROJECT_NAME" == --none-- ]; then compose_set_project_name "$@"
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() { function host_run() {
# lancer le script $2..@ sur l'hôte $1 # lancer le script $2..@ sur l'hôte $1
# si $1 n'est pas défini ou est le nom l'hôte local, lancer le script en # si $1 n'est pas défini ou est le nom de l'hôte local ou vaut 'localhost',
# local avec les droits root # lancer le script en local avec les droits root
# sinon, si docker-machine existe, l'hôte doit correspondre à la machine active # sinon, si docker-machine existe, l'hôte doit correspondre à la machine active
# sinon, lancer inconditionnellement le script sur l'hôte distant # sinon, lancer inconditionnellement le script sur l'hôte distant
local host="$1" script="$2"; shift; shift local host="$1" script="$2"; shift; shift
if [ -n "$host" ]; then if [ -n "$host" -a "$host" != localhost ]; then
if check_hostname "$host"; then if check_hostname "$host"; then
estep "Lancement de $script localement" estep "Lancement de $script localement"
runscript_as_root "$script" "$@" runscript_as_root "$script" "$@"
elif progexists docker-machine; then elif progexists docker-machine; then
local dm; setx dm=docker-machine active 2>/dev/null if [ "${host%%.*}" == "$DOCKER_MACHINE_NAME" ]; then
if [ "${host%%.*}" == "$dm" ]; then
estep "Copie du script vers root@$host" estep "Copie du script vers root@$host"
scp "$script" "root@$host:/tmp/tmp-dk-service-script" || die scp "$script" "root@$host:/tmp/tmp-dk-service-script" || die
estep "Lancement du script à distance" estep "Lancement du script à distance"
local -a args; args=(/tmp/tmp-dk-service-script "$@") local -a args; args=(/tmp/tmp-dk-service-script "$@")
ssh -qt "root@$host" "$(qvals "${args[@]}"); rm -f /tmp/tmp-dk-service-script" ssh -qt "root@$host" "$(qvals "${args[@]}"); rm -f /tmp/tmp-dk-service-script"
else else
ewarn "La machine active ($dm) n'est pas la destination ($host)" ewarn "La machine active ($DOCKER_MACHINE_NAME) n'est pas la destination ($host)"
fi fi
else else
estep "Copie du script vers root@$host" estep "Copie du script vers root@$host"
@ -231,7 +342,10 @@ function update_apps_func_sqlmig() {
[ -n "$srcdir" ] || srcdir="$dest" [ -n "$srcdir" ] || srcdir="$dest"
[ "${srcdir%/config/sqlmig}" != "$srcdir" ] || srcdir="$srcdir/config/sqlmig" [ "${srcdir%/config/sqlmig}" != "$srcdir" ] || srcdir="$srcdir/config/sqlmig"
[ -d "$srcdir" ] || return 0 if [ ! -d "$srcdir" ]; then
eerror "$srcdir: répertoire introuvable"
return 1
fi
local -a sqlmigs; local sqlmig name local -a sqlmigs; local sqlmig name
array_lsall sqlmigs "$srcdir" array_lsall sqlmigs "$srcdir"
@ -271,29 +385,28 @@ function build_update_apps() {
esac esac
etitle "Mise à jour des dépendances" etitle "Mise à jour des dépendances"
local app type url dest branch after_update after_updates local app var type url dest branch after_update after_updates
for app in "${APPS[@]}"; do for app in "${APPS[@]}"; do
etitle "$app" etitle "$app"
url="${app}_URL"; url="${!url}"
dest="${app}_DEST"; dest="${!dest}"
origin="${app}_ORIGIN"; origin="${!origin}"
branch="${app}_BRANCH"; branch="${!branch}"
type="${app}_TYPE"; type="${!type}"
after_updates="${app}_AFTER_UPDATE"
if is_defined "$after_updates"; then
after_updates="$after_updates[@]"; after_updates="${!after_updates}"
else
# script par défaut après update-apps
after_updates=(sqlmig)
fi
var="${app//-/_}"
url="${var}_URL"; url="${!url}"
[ -n "$url" ] || { [ -n "$url" ] || {
ewarn "$app: vous devez définir l'url" ewarn "$app: vous devez définir l'url"
eend; return 1 eend; return 1
} }
[ -n "$dest" ] || dest="$app"
dest="${var}_DEST"; dest="${!dest}"
[ -n "$dest" ] || dest="$app/b"
mkdir -p "$dest" || { eend; return 1; } mkdir -p "$dest" || { eend; return 1; }
origin="${var}_${PROFILE}_ORIGIN"; origin="${!origin}"
[ -n "$origin" ] || { origin="${var}_ORIGIN"; origin="${!origin}"; }
[ -n "$origin" ] || origin="$DEFAULT_ORIGIN" [ -n "$origin" ] || origin="$DEFAULT_ORIGIN"
branch="${var}_${PROFILE}_BRANCH"; branch="${!branch}"
[ -n "$branch" ] || { branch="${var}_BRANCH"; branch="${!branch}"; }
[ -n "$branch" ] || branch="$DEFAULT_BRANCH" [ -n "$branch" ] || branch="$DEFAULT_BRANCH"
dest="$dest/$app" dest="$dest/$app"
@ -311,6 +424,7 @@ function build_update_apps() {
cd "$cwd" cd "$cwd"
fi fi
type="${var}_TYPE"; type="${!type}"
if [ -z "$type" ]; then if [ -z "$type" ]; then
if [ -f "$dest/composer.json" ]; then if [ -f "$dest/composer.json" ]; then
type=composer type=composer
@ -318,6 +432,16 @@ function build_update_apps() {
type=inconnu type=inconnu
fi fi
fi fi
after_updates="${var}_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
estep "Type de dépôt: $type" estep "Type de dépôt: $type"
if [ "$type" == composer ]; then if [ "$type" == composer ]; then
composer=/usr/bin/composer composer=/usr/bin/composer
@ -395,33 +519,51 @@ function auto_build() {
compose_set_env_args compose_set_env_args
update_build_env update_build_env
build_update_apps || return 1 build_update_apps || return 1
compose_build compose_build "$@"
else else
docker_parse_env_args docker_parse_env_args
docker_check_name docker_check_name
docker_add_build_arg build_date "$(date +%y%m%d)" docker_add_build_arg build_date "$(date +%y%m%d)"
update_build_env update_build_env
build_update_apps || return 1 build_update_apps || return 1
docker_build docker_build "$@"
fi fi
} }
function default_compose_push() {
${FAKE:+qvals} docker-compose \
"${replace_env_args[@]}" "${env_args[@]}" \
push \
"$@"
}
function default_docker_push() {
${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() { function auto_push() {
local -a replace_env_args env_args local -a replace_env_args env_args
local -a replace_build_args build_args local -a replace_build_args build_args
local tag
initialize_build_env initialize_build_env
if [ -f docker-compose.yml ]; then if [ -f docker-compose.yml ]; then
compose_set_env_args compose_set_env_args
update_build_env update_build_env
compose_push "$@"
else else
docker_parse_env_args docker_parse_env_args
docker_check_name docker_check_name
update_build_env update_build_env
docker_push "$@"
fi fi
for tag in "${TAGS[@]}"; do
${FAKE:+qvals} docker push "$NAME:$tag"
done
} }
function default_compose_up() { function default_compose_up() {
@ -545,6 +687,98 @@ function auto_down() {
fi fi
} }
function default_docker_deploy() {
${FAKE:+qvals} docker \
stack deploy \
"${replace_deploy_args[@]}" "${deploy_args[@]}" \
"$container_name" "$@"
}
function docker_deploy() { default_docker_deploy "$@"; }
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
docker_set_deploy_args set_container_name
[ -n "$WITH_REGISTRY_AUTH" ] && replace_deploy_args+=(--with-registry-auth)
docker_deploy "$@"
else
die "Impossible de trouver ni docker-compose.yml ni docker-stack.yml"
fi
}
function default_docker_service() {
${FAKE:+qvals} docker service "$@"
}
function docker_service() { default_docker_service "$@"; }
function auto_service() {
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
local command="$1"; shift
[ -n "$command" ] || {
eerror "Vous devez spécifier la commande"
return 1
}
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
}
docker_set_deploy_args set_container_name
service="${container_name}_${service#${container_name}_}"
docker_service "$command" "$@" "$service"
;;
esac
else
die "Impossible de trouver ni docker-compose.yml ni docker-stack.yml"
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() { function default_compose_exec() {
${FAKE:+qvals} docker-compose \ ${FAKE:+qvals} docker-compose \
"${replace_env_args[@]}" "${env_args[@]}" \ "${replace_env_args[@]}" "${env_args[@]}" \
@ -572,7 +806,7 @@ function auto_exec() {
fi fi
} }
function default_compose_service() { function default_compose_systemd_unit() {
local docker_compose="$(which docker-compose 2>/dev/null)" local docker_compose="$(which docker-compose 2>/dev/null)"
if [ -z "$docker_compose" ]; then if [ -z "$docker_compose" ]; then
if [ -x /usr/bin/docker-compose ]; then if [ -x /usr/bin/docker-compose ]; then
@ -589,7 +823,7 @@ function default_compose_service() {
"${replace_user_args[@]}" "${user_args[@]}" "$@" "${replace_user_args[@]}" "${user_args[@]}" "$@"
setx stopcmd=qvals "$docker_compose" down setx stopcmd=qvals "$docker_compose" down
} }
function default_docker_service() { function default_docker_systemd_unit() {
local docker="$(which docker 2>/dev/null)" local docker="$(which docker 2>/dev/null)"
if [ -z "$docker" ]; then if [ -z "$docker" ]; then
if [ -x /usr/bin/docker ]; then if [ -x /usr/bin/docker ]; then
@ -607,21 +841,21 @@ function default_docker_service() {
"${replace_user_args[@]}" "${user_args[@]}" "$@" "${replace_user_args[@]}" "${user_args[@]}" "$@"
setx stopcmd=qvals "$docker" stop "$container_name" setx stopcmd=qvals "$docker" stop "$container_name"
} }
function compose_service() { default_compose_service "$@"; } function compose_systemd_unit() { default_compose_systemd_unit "$@"; }
function docker_service() { default_docker_service "$@"; } function docker_systemd_unit() { default_docker_systemd_unit "$@"; }
function auto_service() { function auto_systemd_unit() {
local -a replace_env_args env_args local -a replace_env_args env_args
local -a replace_run_args run_args local -a replace_run_args run_args
local -a replace_user_args user_args local -a replace_user_args user_args
local project_name container_name startcmd stopcmd local project_name container_name startcmd stopcmd
local tmpscript; ac_set_tmpfile tmpscript local tmpscript; ac_set_tmpfile tmpscript
estep "Génération du service" estep "Génération de l'unité systemd"
export COMPOSE_PROJECT_NAME= export COMPOSE_PROJECT_NAME=
if [ -f docker-compose.yml ]; then if [ -f docker-compose.yml ]; then
compose_set_env_args set_container_name compose_set_env_args set_container_name
replace_run_args=(-d --no-color) replace_run_args=(-d --no-color)
compose_service "$@" compose_systemd_unit "$@"
if [ -z "$HOST" -a -f .env ]; then if [ -z "$HOST" -a -f .env ]; then
source ./.env source ./.env
if [ -n "$PROFILE" ]; then if [ -n "$PROFILE" ]; then
@ -632,7 +866,7 @@ function auto_service() {
docker_set_env_args docker_set_env_args
docker_check_name set_container_name docker_check_name set_container_name
replace_run_args=(-d --name "$container_name") replace_run_args=(-d --name "$container_name")
docker_service "$@" docker_systemd_unit "$@"
fi fi
[ -n "$COMPOSE_PROJECT_NAME" ] || COMPOSE_PROJECT_NAME="$project_name" [ -n "$COMPOSE_PROJECT_NAME" ] || COMPOSE_PROJECT_NAME="$project_name"
chmod 755 "$tmpscript" chmod 755 "$tmpscript"
@ -661,7 +895,7 @@ systemctl daemon-reload
systemctl enable $container_name.service systemctl enable $container_name.service
EOF EOF
estep "Installation du service" estep "Installation de l'unité systemd"
local_run "$HOST" "$tmpscript" local_run "$HOST" "$tmpscript"
} }
@ -671,21 +905,13 @@ DM_PROFILES=()
set_defaults dk set_defaults dk
export PROFILE export PROFILE
if progexists docker-machine; then
setx active_dm=docker-machine active 2>/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= chdir=
DM_SET_MACHINE=
USE_STACK=
FAKE= FAKE=
NO_CACHE= NO_CACHE=
HOST= HOST=
WITH_REGISTRY_AUTH=1
update_apps_mode=ub update_apps_mode=ub
update_apps_origin= update_apps_origin=
update_apps_branch= update_apps_branch=
@ -695,6 +921,8 @@ args=(
-p:,--profile: PROFILE= -p:,--profile: PROFILE=
-P,--prod PROFILE=prod -P,--prod PROFILE=prod
-T,--test PROFILE=test -T,--test PROFILE=test
-m:,--set-machine: DM_SET_MACHINE=
--stack USE_STACK=1
-n,--fake FAKE=1 -n,--fake FAKE=1
-j,--no-cache NO_CACHE=1 -j,--no-cache NO_CACHE=1
-h:,--host: HOST= -h:,--host: HOST=
@ -702,9 +930,26 @@ args=(
-u,--uu,--update-apps-only update_apps_mode=u -u,--uu,--update-apps-only update_apps_mode=u
--uo:,--update-apps-origin: update_apps_origin= --uo:,--update-apps-origin: update_apps_origin=
--ub:,--update-apps-branch: update_apps_branch= --ub:,--update-apps-branch: update_apps_branch=
-l,--without-registry-auth WITH_REGISTRY_AUTH=
) )
parse_args "$@"; set -- "${args[@]}" 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"
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
# construire par défaut # construire par défaut
[ $# -eq 0 ] && set -- build [ $# -eq 0 ] && set -- build
[ -n "$PROFILE" ] || PROFILE="$DEFAULT_PROFILE" [ -n "$PROFILE" ] || PROFILE="$DEFAULT_PROFILE"
@ -726,7 +971,7 @@ while [ $# -gt 0 ]; do
enote "Profil $PROFILE" enote "Profil $PROFILE"
auto_build "${args[@]}" || die auto_build "${args[@]}" || die
;; ;;
push) p|push)
[ -f .build.scripts.sh ] && source ./.build.scripts.sh [ -f .build.scripts.sh ] && source ./.build.scripts.sh
[ -f build.scripts.sh ] && source ./build.scripts.sh [ -f build.scripts.sh ] && source ./build.scripts.sh
args=() args=()
@ -801,6 +1046,7 @@ while [ $# -gt 0 ]; do
build_set_options "$update_apps_mode" "$update_apps_origin" "$update_apps_branch" 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
[ -f build.scripts.sh ] && source ./build.scripts.sh [ -f build.scripts.sh ] && source ./build.scripts.sh
USE_STACK=1
args=() args=()
while [ $# -gt 0 -a "$1" != -- ]; do while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift args+=("$1"); shift
@ -808,6 +1054,81 @@ while [ $# -gt 0 ]; do
enote "Profil $PROFILE" enote "Profil $PROFILE"
auto_build && auto_up "${args[@]}" auto_build && auto_up "${args[@]}"
;; ;;
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)
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
USE_STACK=1
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_build && auto_deploy "${args[@]}"
;;
bp)
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_push "${args[@]}"
;;
bpy|bpd)
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_push && auto_deploy "${args[@]}"
;;
service)
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_service "${args[@]}" || die
;;
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
;;
ip|show-ip)
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_show_ip "${args[@]}" || die
;;
x|exec) x|exec)
args=() args=()
while [ $# -gt 0 -a "$1" != -- ]; do while [ $# -gt 0 -a "$1" != -- ]; do
@ -816,13 +1137,13 @@ while [ $# -gt 0 ]; do
enote "Profil $PROFILE" enote "Profil $PROFILE"
auto_exec "${args[@]}" || die auto_exec "${args[@]}" || die
;; ;;
service) systemd-unit|systemd)
args=() args=()
while [ $# -gt 0 -a "$1" != -- ]; do while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift args+=("$1"); shift
done done
enote "Profil $PROFILE" enote "Profil $PROFILE"
auto_service "${args[@]}" || die auto_systemd_unit "${args[@]}" || die
;; ;;
ps) docker container ps -a || die;; ps) docker container ps -a || die;;
ls) docker image ls || die;; ls) docker image ls || die;;

4
fconv
View File

@ -54,6 +54,8 @@ COMMANDES
Transformer certains caratères UTF-8 en équivalents qui existent en Latin1 Transformer certains caratères UTF-8 en équivalents qui existent en Latin1
na, noaccents na, noaccents
Transformer les caractères accentués en caractères non accentués Transformer les caractères accentués en caractères non accentués
[sed] s/from/to/opts
Filtrer avec l'expression régulière de sed 's/from/to/opts'
sort [-u] sort [-u]
Trier le fichier avec la commande sort. Attention! Il ne faut utiliser Trier le fichier avec la commande sort. Attention! Il ne faut utiliser
que les options de sort qui agissent sur un flux e.g. -u pour trier les que les options de sort qui agissent sur un flux e.g. -u pour trier les
@ -151,6 +153,8 @@ function parse_cmd() {
cr) echo _nl2cr;; cr) echo _nl2cr;;
latin1compat|lc) echo _latin1compat;; latin1compat|lc) echo _latin1compat;;
noaccents|na|fixchars|fc) echo _noaccents;; noaccents|na|fixchars|fc) echo _noaccents;;
s/*) qvals sed "$cmd" "$@";;
sed) qvals sed "$@";;
sort) qvals sort "$@";; sort) qvals sort "$@";;
*) *)
echo "$cmd: commande invalide" echo "$cmd: commande invalide"

6
fnconv
View File

@ -51,7 +51,9 @@ COMMANDES
u, uppercase u, uppercase
Transformer le nom en majuscule Transformer le nom en majuscule
f, fixcase f, fixcase
Transformer le nom en minuscule s'il est entièrement en majuscule" Transformer le nom en minuscule s'il est entièrement en majuscule
[sed] s/from/to/opts
Renommer le fichier avec l'expression régulière de sed 's/from/to/opts'"
} }
function _lowercase() { function _lowercase() {
@ -163,6 +165,8 @@ function parse_cmd() {
lowercase|lower|l) echo _lowercase;; lowercase|lower|l) echo _lowercase;;
uppercase|upper|u) echo _uppercase;; uppercase|upper|u) echo _uppercase;;
fixcase|fix|f) echo _fixcase;; fixcase|fix|f) echo _fixcase;;
s/*) qvals sed "$cmd" "$@";;
sed) qvals sed "$@";;
*) *)
echo "$cmd: commande invalide" echo "$cmd: commande invalide"
return 1 return 1

58
foreach
View File

@ -74,10 +74,20 @@ OPTIONS
Si l'expansion est désactivée, il faut protéger le caractère \$ pour Si l'expansion est désactivée, il faut protéger le caractère \$ pour
qu'il soit traité, e.g, avec les examples ci-dessus: qu'il soit traité, e.g, avec les examples ci-dessus:
$scriptname -n '*.c' 'cp \"\$item\" dest/dir' $scriptname -n '*.c' 'cp \"\$item\" dest/dir'
-t, --title --title
--no-title --pt, --parent-title
--nt, --no-title
Afficher (resp. ne pas afficher) chaque correspondance avant de lancer Afficher (resp. ne pas afficher) chaque correspondance avant de lancer
la commande. Par défaut, l'affichage est effectué." la commande. Par défaut, l'affichage est effectué.
Avec --parent-title, pour chaque correspondance afficher plutôt le
répertoire parent (valide uniquement avec l'option -p)
-G, --git-projects
Equivalent à '--ptitle -p */.git --' e.g '$scriptname -G git pull' pour
mettre à jour les dépôts situés dans un répertoire
-C, --composer-projects
Equivalent à '--ptitle -p */composer.json --'
--cc, --composer-cmd
Equivalent à '--ptitle -p */composer.phar -- ./composer.phar'"
} }
basedir= basedir=
@ -85,7 +95,8 @@ match=auto
changedir= changedir=
parentdir= parentdir=
expand=1 expand=1
title=1 title=auto
shortcut=
args=(+ args=(+
--help '$exit_with display_help' --help '$exit_with display_help'
-b:,--basedir: basedir= -b:,--basedir: basedir=
@ -97,18 +108,37 @@ args=(+
-s,--string match=string -s,--string match=string
-x,--expand expand=1 -x,--expand expand=1
-n,--no-expand expand= -n,--no-expand expand=
-t,--title title=1 --title title=1
--no-title title= --pt,--parent-title title=p
--nt,--no-title title=
-G,--git-projects shortcut=git
-C,--composer-projects shortcut=composer
--cc,--composer-cmd shortcut=composer-cmd
) )
parse_args "$@"; set -- "${args[@]}" parse_args "$@"; set -- "${args[@]}"
case "$shortcut" in
git)
set -- */.git -- "$@"
parentdir=1
[ "$title" == auto ] && title=p
;;
composer)
set -- */composer.json -- "$@"
parentdir=1
[ "$title" == auto ] && title=p
;;
composer-cmd)
set -- */composer.phar -- ./composer.phar "$@"
parentdir=1
[ "$title" == auto ] && title=p
;;
esac
if [ "$match" == auto ]; then if [ "$match" == auto ]; then
if [ -n "$changedir" ]; then [ -n "$changedir" ] && match=dir || match=all
match=dir
else
match=all
fi
fi fi
[ "$title" == auto ] && title=1
alt_syntax= alt_syntax=
for sep in "$@"; do for sep in "$@"; do
@ -175,7 +205,11 @@ fi
[ -n "$title" ] && einfo "${#items[@]} correspondance(s) trouvée(s)" [ -n "$title" ] && einfo "${#items[@]} correspondance(s) trouvée(s)"
let index=0 let index=0
for item in "${items[@]}"; do for item in "${items[@]}"; do
[ -n "$title" ] && etitle "$item" if [ -n "$parentdir" -a "$title" == p ]; then
etitle "$(dirname -- "$item")"
elif [ -n "$title" ]; then
etitle "$item"
fi
i="$item" i="$item"
setx file=abspath "$item" setx file=abspath "$item"
setx dir=dirname -- "$file" setx dir=dirname -- "$file"

314
sqlmig
View File

@ -80,13 +80,53 @@ OPTIONS
spécifié au nom de la base de données. Cette valeur peut être spécifiée spécifié au nom de la base de données. Cette valeur peut être spécifiée
dans la section [sqlmig] du fichier my.cnf ou avec la variable SUFFIX dans la section [sqlmig] du fichier my.cnf ou avec la variable SUFFIX
pour ora.conf pour ora.conf
--csv2sql
Convertir les fichiers CSV en SQL. C'est la valeur par défaut. Ce
paramètre peut être spécifié dans my.cnf sous la forme
[sqlmig]
csv2sql=1
ou dans ora.conf
CSV2SQL=1
Pour le moment, cette conversion n'est supportée que pour MySQL. Tous
les fichiers de la forme [NUM]TABLE[-data].csv sont transformés en une
suite d'insertion dans la table TABLE. Une variante insère les données
dans la table après l'avoir vidée avec 'truncate table'. Les fichiers
doivent être de la forme [NUM]TABLE-data_truncate.csv
--csv-null VALUE --csv-null VALUE
Lors de la conversion des fichiers .csv en .sql, considérer que VALUE Lors de la conversion des fichiers .csv en .sql, considérer que VALUE
représente la valeur NULL. Par défaut, utiliser la chaine vide représente la valeur NULL. Par défaut, utiliser la chaine vide
--csv-null-empty
--csv-null-mysql --csv-null-mysql
--csv-null-upper --csv-null-upper
Aliases pour --csv-null '\\N' et --csv-null NULL respectivement Aliases pour --csv-null '', --csv-null '\\N' et --csv-null NULL respectivement
--no-csv2sql
Ne pas convertir les fichiers CSV en SQL. Ce paramètre peut être
spécifié dans my.cnf sous la forme
[sqlmig]
csv2sql=0
ou dans ora.conf
CSV2SQL=0
--load-data DEFAULT|LOCAL|SERVER
Si l'option --no-csv2sql est activée, spécifier le type de chargement
effectué pour les fichiers CSV.
* Avec LOCAL (la valeur par défaut), la directive 'load data local' est
utilisée. Cependant les erreurs éventuelles sont ignorées parce que le
serveur n'a pas de moyen pour arrêter la transmission des informations
par le client.
* Avec SERVER, la directive 'load data' est utilisée. Les erreurs
éventuelles sont affichées et arrêtent l'importation des données. Par
contre, le fichier doit être accessible par le serveur MySQL puisque
les données sont chargées directement par le serveur.
NB: avec MariaDB sur systemd, l'accès à /home, /root et /run/user est
désactivé par défaut. Pour pouvoir utiliser ce mode avec des fichiers
de l'utilisateur, il faut lancer ces commandes:
[ \$(id -u) == 0 ] && sudo= || sudo=sudo
\$sudo mkdir -p /etc/systemd/system/mariadb.service.d
\$sudo tee /etc/systemd/system/mariadb.service.d/dontprotecthome.conf <<<\$'[Service]\nProtectHome=false'
\$sudo systemctl daemon-reload
* Avec DEFAULT, utiliser SERVER si on communique avec le serveur MySQL
local (c'est à dire si host n'est pas spécifié ou vaut 127.*, ::1 ou
localhost). Sinon, utiliser LOCAL
--profile PROFILE --profile PROFILE
-P, --prod -P, --prod
-T, --test -T, --test
@ -156,14 +196,9 @@ OPTIONS
--force, --continue-on-error --force, --continue-on-error
Ne pas s'arrêter en cas d'erreur de mise à jour Ne pas s'arrêter en cas d'erreur de mise à jour
--no-data-csv --no-data-csv
Ne pas convertir les fichiers *-data.csv en fichier .sql Ne pas procéder à la conversion des fichiers CSV en SQL
correspondant. Cette conversion n'est supportée que pour MySQL pour le
moment, et un fichier de la forme NUMTABLE-data.csv où NUM est une valeur
numérique est transformé en une suite d'insertions dans la table TABLE.
La variante NUMTABLE-data_truncate.csv ajoute les données dans la table
après l'avoir vidée avec truncate.
--force-data-csv --force-data-csv
Forcer la conversion des fichiers *-data.csv. Par défaut, la conversion Forcer la conversion des fichiers CSV en SQL. Par défaut, la conversion
n'est faite que si le fichier csv est plus récent que le fichier sql n'est faite que si le fichier csv est plus récent que le fichier sql
correspondant. correspondant.
--devel-mode --devel-mode
@ -326,12 +361,60 @@ function set_dbdirs() {
fi fi
} }
function fix_csv2sql() {
if [ -z "$csv2sql" ]; then
# valeur par défaut
csv2sql=1
elif is_yes "$csv2sql"; then
csv2sql=1
elif is_no "$csv2sql"; then
csv2sql=0
fi
}
function fix_csv_null() { function fix_csv_null() {
# si csv_null a une valeur vide, c'est déjà la valeur par défaut
case "$csv_null" in case "$csv_null" in
empty) csv_null=;;
mysql) csv_null='\N';; mysql) csv_null='\N';;
upper) csv_null=NULL;; upper) csv_null=NULL;;
esac esac
} }
function fix_load_data() {
if [ -z "$load_data" ]; then
# valeur par défaut
load_data=local
else
case "${load_data,,}" in
default|d*) load_data=default;;
local|l*) load_data=local;;
server|s*) load_data=server;;
esac
fi
if [ "$load_data" == default ]; then
case "$host" in
""|localhost|127.*|::1) load_data=server;;
*) load_data=local;;
esac
fi
}
function get_csvinfo() {
# afficher les informations sur un fichier csv: nom de la table, et s'il
# faut faire un truncate
local csvname="$(basename -- "$1")"
local script='{
truncate = ($0 ~ /-data_truncate(.devel)?.csv$/)? "1": ""
sub(/^.*\//, "")
sub(/^(([A-Z][-.A-Z0-9]*[0-9]-?)|([0-9][-.0-9]*-?))/, "")
sub(/\.csv$/, "")
sub(/\.devel$/, "")
sub(/-data(_[a-z]+*)?$/, "")
print "truncate=" truncate
gsub(/'\''/, "'\'\\\\\'\''")
print "table='\''" $0 "'\''"
}'
awk "$script" <<<"$csvname"
}
################################################################################ ################################################################################
# MySQL # MySQL
@ -476,6 +559,13 @@ function mysql__mconf_get() {
setx tmp=mconf_get "$defaults" sqlmig suffix setx tmp=mconf_get "$defaults" sqlmig suffix
[ -n "$tmp" ] && suffix="$tmp" [ -n "$tmp" ] && suffix="$tmp"
fi fi
if [ -n "$set_csv2sql" ]; then
setx tmp=mconf_get "$defaults" sqlmig csv2sql
[ -n "$tmp" ] && {
csv2sql="$tmp"
fix_csv2sql
}
fi
if [ -n "$set_csv_null" ]; then if [ -n "$set_csv_null" ]; then
setx tmp=mconf_get "$defaults" sqlmig csv_null setx tmp=mconf_get "$defaults" sqlmig csv_null
[ -n "$tmp" ] && { [ -n "$tmp" ] && {
@ -483,14 +573,27 @@ function mysql__mconf_get() {
fix_csv_null fix_csv_null
} }
fi fi
if [ -n "$set_load_data" ]; then
if [ -z "$host" ]; then
# load_data==default requière host
setx host=mconf_get "$defaults" client host
fi
setx tmp=mconf_get "$defaults" sqlmig load-data
[ -n "$tmp" ] && {
load_data="$tmp"
fix_load_data
}
fi
} }
function mysql_set_userargs() { function mysql_set_userargs() {
local dir="$1" dbname="$2" defaults local dir="$1" dbname="$2" defaults
local set_suffix set_csv_null local set_suffix set_csv2sql set_csv_null set_load_data
userargs=() userargs=()
setx defaults=mysql_get_defaults "$dir" setx defaults=mysql_get_defaults "$dir"
[ -z "$suffix" ] && set_suffix=1 [ -z "$suffix" ] && set_suffix=1
[ -z "$csv2sql" ] && set_csv2sql=1
[ -z "$csv_null" ] && set_csv_null=1 [ -z "$csv_null" ] && set_csv_null=1
[ -z "$load_data" ] && set_load_data=1
if [ -f "$defaults" ]; then if [ -f "$defaults" ]; then
array_add userargs --defaults-file="$defaults" array_add userargs --defaults-file="$defaults"
mysql__mconf_get "$defaults" mysql__mconf_get "$defaults"
@ -509,6 +612,10 @@ function mysql_set_userargs() {
mysql__mconf_get "$dir/my-${dbname}.cnf" mysql__mconf_get "$dir/my-${dbname}.cnf"
fi fi
[ ${#userargs[*]} -gt 0 ] || array_add userargs --default-character-set utf8 [ ${#userargs[*]} -gt 0 ] || array_add userargs --default-character-set utf8
# initialiser les valeurs par défaut
fix_csv2sql
fix_csv_null
fix_load_data
} }
function mysql_set_mysqlargs() { function mysql_set_mysqlargs() {
mysqlargs=() mysqlargs=()
@ -561,7 +668,26 @@ function mysql_user_update() {
if [ -z "$updateone" ]; then if [ -z "$updateone" ]; then
mysql_before_update "$dbname" || die mysql_before_update "$dbname" || die
fi fi
cat "$update" | mysql_user_ve || abort_on_error if [[ "$update" == *.sql ]]; then
# SQL
cat "$update" | mysql_user_ve || abort_on_error
else
# CSV
local truncate table local sql
eval "$(get_csvinfo "$update")"
[ -n "$truncate" ] && sql="truncate table $table;"
[ "$load_data" == local ] && local=1 || local=
sql="${sql}load data${local:+ local} infile '$update' into table \`$table\`
character set 'utf8'
fields terminated by ','
optionally enclosed by '\\\"'
escaped by '\\\\'
lines terminated by '\\n'
starting by ''
ignore 1 lines
($(<"$update" awk '{ print; exit }'));"
echo "$sql" | mysql_user_ve || abort_on_error
fi
if [ -z "$updateone" ]; then if [ -z "$updateone" ]; then
mysql_after_update "$dbname" || die mysql_after_update "$dbname" || die
fi fi
@ -827,7 +953,7 @@ function oracle_source_adminconf() {
} }
function oracle_source_userconf() { function oracle_source_userconf() {
local dir="$1" dbname="$2" local dir="$1" dbname="$2"
unset ORACLE_SID NLS_LANG ADMINCONNECT USERCONNECT SQLMIGLOG SUFFIX CSV_NULL unset ORACLE_SID NLS_LANG ADMINCONNECT USERCONNECT SQLMIGLOG SUFFIX CSV2SQL CSV_NULL
setx defaults=oracle_get_defaults "$dir" setx defaults=oracle_get_defaults "$dir"
[ -f "$defaults" ] && source "$defaults" [ -f "$defaults" ] && source "$defaults"
[ -f "$dir/ora-${dbname}.conf" ] && source "$dir/ora-${dbname}.conf" [ -f "$dir/ora-${dbname}.conf" ] && source "$dir/ora-${dbname}.conf"
@ -851,10 +977,10 @@ function oracle_source_userconf() {
fi fi
[ -n "$SQLMIGLOG" ] || SQLMIGLOG="/tmp/sqlmig-${ORACLE_SID}-${dbname}.log" [ -n "$SQLMIGLOG" ] || SQLMIGLOG="/tmp/sqlmig-${ORACLE_SID}-${dbname}.log"
[ -z "$suffix" ] && suffix="$SUFFIX" [ -z "$suffix" ] && suffix="$SUFFIX"
[ -z "$csv_null" ] && { [ -z "$csv2sql" ] && csv2sql="$CSV2SQL"
csv_null="$CSV_NULL" [ -z "$csv_null" ] && csv_null="$CSV_NULL"
fix_csv_null fix_csv2sql
} fix_csv_null
} }
ORACLE_ADMIN_CONF_DONE= ORACLE_ADMIN_CONF_DONE=
function oracle_admin_update() { function oracle_admin_update() {
@ -918,7 +1044,9 @@ charset=
oracle_sid= oracle_sid=
nls_lang= nls_lang=
suffix= suffix=
csv2sql=
csv_null= csv_null=
load_data=
profile= profile=
type=auto type=auto
action=update action=update
@ -946,9 +1074,13 @@ args=(
-s:,--oracle-sid: oracle_sid= -s:,--oracle-sid: oracle_sid=
--nls-lang: nls_lang= --nls-lang: nls_lang=
--suffix: suffix= --suffix: suffix=
--csv2sql csv2sql=1
--csv-null: csv_null= --csv-null: csv_null=
--csv-null-empty csv_null=empty
--csv-null-mysql csv_null='\N' --csv-null-mysql csv_null='\N'
--csv-null-upper csv_null=NULL --csv-null-upper csv_null=NULL
--no-csv2sql csv2sql=0
--load-data: load_data=
--profile: profile= --profile: profile=
-P,--prod profile=prod -P,--prod profile=prod
-T,--test profile=test -T,--test profile=test
@ -1059,8 +1191,7 @@ grant all privileges on $dbname.* to '$dbname';"
default-character-set=utf8 default-character-set=utf8
[sqlmig] [sqlmig]
#suffix= #suffix="
csv_null="
fi fi
if [ ! -f "$dbdir/my-${dbname}.cnf" ]; then if [ ! -f "$dbdir/my-${dbname}.cnf" ]; then
@ -1069,7 +1200,12 @@ csv_null="
# Paramètres de connexion pour $dbname # Paramètres de connexion pour $dbname
[client] [client]
#user= #user=
#password=" #password=
[sqlmig]
#csv2sql=0
csv_null=
#load-data=default"
fi fi
elif [ "$type" == oracle ]; then elif [ "$type" == oracle ]; then
@ -1110,7 +1246,8 @@ USERCONNECT=$dbname/password
SQLMIGLOG=\"/tmp/sqlmig-\${ORACLE_SID}-${dbname}.log\" SQLMIGLOG=\"/tmp/sqlmig-\${ORACLE_SID}-${dbname}.log\"
# divers # divers
#SUFFIX= #SUFFIX=
#CSV_NULL=" #CSV2SQL=0
CSV_NULL="
fi fi
else else
@ -1289,9 +1426,9 @@ function should_update() {
elif [ "${name#maint-}" != "$name" ]; then elif [ "${name#maint-}" != "$name" ]; then
# ignorer les opérations de maintenance par défaut # ignorer les opérations de maintenance par défaut
return 1 return 1
elif [ "$dbmode" != devel -a "${name%.devel.sql}" != "$name" ]; then elif [ "$dbmode" != devel -a "${name%.devel.*}" != "$name" ]; then
# si on est en mode autre que devel, le nom ne doit pas se terminer # si on est en mode autre que devel, le nom ne doit pas se terminer
# par .devel.sql # par .devel.*
return 1 return 1
fi fi
return 0 return 0
@ -1347,13 +1484,16 @@ for dbdir in "${dbdirs[@]}"; do
ensure_dbtype "$dbdir" "$type" ensure_dbtype "$dbdir" "$type"
ensure_dbmode "$dbtype" "$mode" ensure_dbmode "$dbtype" "$mode"
if [ -n "$data_csv" ]; then ############################################################################
# Conversion csv --> sql if [ "$dbtype" == mysql ]; then
array_lsfiles csvs "$dbdir" "*.csv" # construire les paramètres pour mysql
if [ "$dbtype" == mysql ]; then mysql_set_adminargs "$dbdir"
setx defaults=mysql_get_defaults "$dbdir" mysql_set_userargs "$dbdir" "$dbname"
set_csv_null=1 mysql_set_mysqlargs
mysql__mconf_get "$defaults"
if is_yes "$csv2sql" && [ -n "$data_csv" ]; then
# Conversion csv --> sql
array_lsfiles csvs "$dbdir" "*.csv"
etitled "Conversion" etitled "Conversion"
for csv in "${csvs[@]}"; do for csv in "${csvs[@]}"; do
@ -1364,50 +1504,47 @@ for dbdir in "${dbdirs[@]}"; do
fi fi
estep "$csvname --> ${csvname%.csv}.sql" estep "$csvname --> ${csvname%.csv}.sql"
script='{ eval "$(get_csvinfo "$csvname")"
truncate = ($0 ~ /-data_truncate(.devel)?.csv$/)? "1": "" mysqlloadcsv_args=(
sub(/^.*\//, "") ${truncate:+-T}
sub(/^[A-Z0-9.]*[0-9]-?/, "") -Z "$csv_null"
sub(/\.csv$/, "") --prefix "-- -*- coding: utf-8 mode: sql -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8"
sub(/\.devel$/, "") -nIf "$csv" "$table"
sub(/-data(_[a-z]+*)?$/, "") )
print "truncate=" truncate "$scriptdir/mysqlloadcsv" "${mysqlloadcsv_args[@]}" >"$sql"
gsub(/'\''/, "'\'\\\\\'\''")
print "table='\''" $0 "'\''"
}'
eval "$(awk "$script" <<<"$csvname")"
"$scriptdir/mysqlloadcsv" >"$sql" ${truncate:+-T} -Z "$csv_null" -nIf "$csv" "$table" --prefix "-- -*- coding: utf-8 mode: sql -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8"
done done
eend; eclearp eend; eclearp
fi fi
fi
# lister les mises à jour disponibles # lister les mises à jour disponibles
drops=() drops=()
creates=() creates=()
updates=() updates=()
array_lsfiles files "$dbdir" "*.sql" have_csv=
for file in "${files[@]}"; do array_lsfiles files "$dbdir" "*.sql" "*.csv"
if have_tag drop "$file"; then for file in "${files[@]}"; do
array_add drops "$file" if [[ "$file" == *.sql ]]; then
elif have_tag create "$file"; then if have_tag drop "$file"; then
array_add creates "$file" array_add drops "$file"
else elif have_tag create "$file"; then
array_add updates "$file" array_add creates "$file"
fi else
done array_add updates "$file"
fi
############################################################################ elif [ ! -f "${file%.csv}.sql" ]; then
if [ "$dbtype" == mysql ]; then # n'ajouter le CSV que si le fichier SQL correspondant n'existe pas
# construire les paramètres pour mysql array_add updates "$file"
mysql_set_adminargs "$dbdir" have_csv=1
mysql_set_userargs "$dbdir" "$dbname" fi
mysql_set_mysqlargs done
if [ -n "$suffix" ]; then if [ -n "$suffix" ]; then
estepi "Suffixe: $dbname --> $dbname$suffix" estepi "Suffixe: $dbname --> $dbname$suffix"
dbname="$dbname$suffix" dbname="$dbname$suffix"
fi fi
if is_no "$csv2sql" && [ -n "$have_csv" ]; then
estepi "Chargement des fichiers CSV avec la méthode $load_data"
fi
# Suppression # Suppression
if [ -n "$drop" ]; then if [ -n "$drop" ]; then
@ -1449,10 +1586,16 @@ for dbdir in "${dbdirs[@]}"; do
mysql_tbconf "$dbname" mysql_tbconf "$dbname"
for update in "${updates[@]}"; do for update in "${updates[@]}"; do
should_update "$update" || continue should_update "$update" || continue
if have_tag admin "$update"; then if [[ "$update" == *.sql ]]; then
[ -n "$updatedir" ] && name="${update#$updatedir/}" || name="${update#$dbdir/}" # fichier SQL
mysql_admin_update "$name" "$update" "$updateone" if have_tag admin "$update"; then
else [ -n "$updatedir" ] && name="${update#$updatedir/}" || name="${update#$dbdir/}"
mysql_admin_update "$name" "$update" "$updateone"
else
mysql_user_update "${update#$dbdir/}" "$update" "$dbname" "$updateone"
fi
elif is_no "$csv2sql"; then
# fichier CSV, ne les traiter que si on est en mode --no-csv2sql
mysql_user_update "${update#$dbdir/}" "$update" "$dbname" "$updateone" mysql_user_update "${update#$dbdir/}" "$update" "$dbname" "$updateone"
fi fi
done done
@ -1466,6 +1609,28 @@ for dbdir in "${dbdirs[@]}"; do
oracle_source_userconf "$dbdir" "$dbname" oracle_source_userconf "$dbdir" "$dbname"
oracle_ensure_opdir oracle_ensure_opdir
# lister les mises à jour disponibles
drops=()
creates=()
updates=()
have_csv=
array_lsfiles files "$dbdir" "*.sql" "*.csv"
for file in "${files[@]}"; do
if [[ "$file" == *.sql ]]; then
if have_tag drop "$file"; then
array_add drops "$file"
elif have_tag create "$file"; then
array_add creates "$file"
else
array_add updates "$file"
fi
elif [ ! -f "${file%.csv}.sql" ]; then
# n'ajouter le CSV que si le fichier SQL correspondant n'existe pas
array_add updates "$file"
have_csv=1
fi
done
if [ -n "$suffix" ]; then if [ -n "$suffix" ]; then
estepi "Suffixe: $dbname --> $dbname$suffix" estepi "Suffixe: $dbname --> $dbname$suffix"
dbname="$dbname$suffix" dbname="$dbname$suffix"
@ -1511,11 +1676,14 @@ for dbdir in "${dbdirs[@]}"; do
oracle_tbconf "$dbname" oracle_tbconf "$dbname"
for update in "${updates[@]}"; do for update in "${updates[@]}"; do
should_update "$update" || continue should_update "$update" || continue
if have_tag admin "$update"; then if [[ "$update" == *.sql ]]; then
[ -n "$updatedir" ] && name="${update#$updatedir/}" || name="${update#$dbdir/}" # fichier SQL
oracle_admin_update "$name" "$update" "$updateone" if have_tag admin "$update"; then
else [ -n "$updatedir" ] && name="${update#$updatedir/}" || name="${update#$dbdir/}"
oracle_user_update "${update#$dbdir/}" "$update" "$dbname" "$updateone" oracle_admin_update "$name" "$update" "$updateone"
else
oracle_user_update "${update#$dbdir/}" "$update" "$dbname" "$updateone"
fi
fi fi
done done
eend; eclearp eend; eclearp