nutools/toinst

556 lines
18 KiB
Plaintext
Raw Normal View History

2017-04-18 11:35:54 +04:00
#!/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 xmlsupport
function display_help() {
uecho "$scriptname: Déployer une ou plusieurs webapps vers Tomcat
USAGE
$scriptname [options] <archive|dir>...
OPTIONS
-c, --config CONFIG
Spécifier un fichier de configuration qui contient les informations
spécifiées par les options ci-dessous: TOMCAT_PROFILE, CATALINA_BASE,
TOMCAT_USER, TOMCAT_GROUP, TOMCAT_VERSION, MANAGER_URL, MANAGER_USER,
MANAGER_PASSWORD, WAMAP, BACKUP, RESTART
-C, --config-profile TOMCAT_PROFILE
Spécifier le profil de configuration à utiliser. Cette valeur détermine
la façon dont sont calculés CATALINA_BASE, TOMCAT_USER, TOMCAT_GROUP et
TOMCAT_VERSION. Les valeurs valides sont:
* debian:tomcatV
Tomcat installé par 'apt-get install tomcatV'. L'alias 'd:V' est
aussi supporté, e.g 'debian:tomcat7' ou 'd:8'
* runs:NAME
Tomcat installé par 'runs tomcat/V name=NAME'. Le suffixe NAME est
le nom de base des fichiers de tomcat. Pour spécifier le cas échéant
la version de Tomcat, il faut utiliser l'option -V ci-dessous.
L'alias NAME sans le préfixe runs: est supporté aussi.
Le profil par défaut est calculé comme suit:
* Si un répertoire de la forme /var/lib/tomcatV existe alors il s'agit
de debian:tomcatV.
* Si le lien /opt/tomcat --> /opt/apache-tomcat-V existe, vérifier
l'existence du script /etc/init.d/tomcatV. Si le script existe, alors
utiliser runs:tomcatV comme profil. Sinon, utiliser runs:tomcat.
* Sinon, aucun profil n'est sélectionné, et il faut spécifier
manuellement les options -d, -U, -G, -V
-d, --catalina-base CATALINA_BASE
Spécifier le répertoire de base des configurations de Tomcat. La valeur
par défaut est celle de CATALINA_HOME. Cette option n'a normalement pas
besoin d'être spécifiée.
-U, --tomcat-user TOMCAT_USER
-G, --tomcat-group TOMCAT_GROUP
Spécifier l'utilisateur et le groupe propriétaires des fichiers de
Tomcat. Ces options n'ont normalement pas besoin d'être spécifiées.
-V, --tomcat-version TOMCAT_VERSION
Spécifier la version de tomcat installée, e.g 8.0.37 pour une version
complète ou simplement 8 si on ne donne que la version majeure.
Cette option peut s'avérer nécessaire avec le profil runs:tomcat bien
que les meilleurs efforts soient faits pour détecter la valeur
effective.
-g, --manager-url MANAGER_URL
Spécifier l'url du manager, e.g http://localhost:8080/manager/text
Par défaut, le fichier server.xml est consulté pour connaitre sur quel
port écoute le serveur.
-u, --user MANAGER_USER
-p, --password MANAGER_PASSWORD
Spécifier le compte et le mot de passe à utiliser pour piloter le
manager Tomcat, notamment pour redémarrer l'application venant d'être
déployée. Ce compte doit avoir le rôle manager-script à partir de Tomcat
6.0.30, et le rôle manager-gui dans les version antérieurs. Par défaut,
le fichier tomcat-users.xml est consulté pour avoir cette information.
-m, --wamap WAMAPS
Ajouter un ou plusieurs mappings de la forme src:dest. Avec ce mapping,
la webapp src est déployée avec le nom dest. Plusieurs mappings peuvent
être spécifiés en les séparant par des virgules. Si src est mentionné
plusieurs fois, e.g src:dest1,src:dest2 alors la webapp src est déployée
plusieurs fois avec des noms distincts.
2017-04-19 08:12:32 +04:00
--protect PROTECTS
2017-04-18 11:35:54 +04:00
--exclude EXCLUDES
--replace-excludes EXCLUDES
--rsync-option RSYNC_OPTIONS
--replace-rsync-options RSYNC_OPTIONS
XXX Options non documentées à implémenter
-b, --backup
--no-backup
Avant le déploiement du service numérique, faire (resp. ne pas faire)
une sauvegarde des fichiers actuellement déployés.
-B, --backup-only
Ne pas faire le déploiement. Faire uniquement la sauvegarde.
-n, --no-restart
Après le déploiement de la webapp, ne pas redémarrer l'application.
-r, --restart-only
Ne pas faire le déploiement. Redémarrer uniquement l'application.
--fake
2017-04-19 08:12:32 +04:00
Afficher simplement ce qui serait fait. Ne pas le faire réellement.
--config-template
Créer un modèle de configuration dans le répertoire des webapp
spécifiées. Si aucune webapp n'est spécifiée, créer le fichier dans le
répertoire courant."
2017-04-18 11:35:54 +04:00
}
VARS=(
TOMCAT_PROFILE
CATALINA_BASE TOMCAT_USER TOMCAT_GROUP TOMCAT_VERSION
MANAGER_URL MANAGER_USER MANAGER_PASSWORD
BACKUP RESTART
)
ARRAYS=(
2017-04-19 08:12:32 +04:00
WAMAPS PROTECTS EXCLUDES RSYNC_OPTIONS REPLACE_RSYNC_OPTIONS
2017-04-18 11:35:54 +04:00
)
function __reset_vars() {
local var
for var in "${VARS[@]}"; do
eval "$var="
done
for var in "${ARRAYS[@]}"; do
eval "$var=()"
done
}
function __dump_vars() {
local var
for var in "${VARS[@]}"; do
echo_setv2 "$var"
done
for var in "${ARRAYS[@]}"; do
echo_seta2 "$var"
done
}
function use_manager_script() {
local v="$TOMCAT_VERSION"
if [ -z "$v" ]; then
return 0
elif [[ "$v" == 6.0.* ]]; then
if [ "${v#6.0.}" -ge 30 ]; then
return 0
else
return 1
fi
elif [ "${v%%.*}" -gt 6 ]; then
return 0
else
return 1
fi
}
function parse_server() {
local -a lines
local serverxml port
serverxml="$CATALINA_BASE/conf/server.xml"
array_from_lines lines "$(xpathtool -g "/Server/Service[@name='Catalina']/Connector/@port" "$serverxml")"
port="${lines[0]}"
if [ -n "$port" ]; then
if use_manager_script; then
MANAGER_URL="http://localhost:$port/manager/text"
else
MANAGER_URL="http://localhost:$port/manager/html"
fi
fi
}
function parse_tomcat_users() {
local -a lines
local usersxml role
usersxml="$CATALINA_BASE/conf/tomcat-users.xml"
if use_manager_script; then
role=manager-script
else
role=manager-gui
fi
array_from_lines lines "$(xpathtool -g "/tomcat-users/user[contains(@roles,'$role')]/@username" "$usersxml")"
MANAGER_USER="${lines[0]}"
if [ -n "$MANAGER_USER" ]; then
array_from_lines lines "$(xpathtool -g "/tomcat-users/user[@username='$MANAGER_USER']/@password" "$usersxml")"
MANAGER_PASSWORD="${lines[0]}"
fi
}
action=deploy
parse_tomcat_users=
parse_server=
istmpdir=
tmpdir=
2017-04-18 11:35:54 +04:00
config=
tomcat_profile=
catalina_base=
tomcat_user=
tomcat_group=
tomcat_version=
manager_url=
manager_user=
manager_password=
wamaps=()
2017-04-19 08:12:32 +04:00
protects=()
2017-04-18 11:35:54 +04:00
excludes=()
rsync_options=(-rptL --delete --exclude /.git/)
replace_rsync_options=()
backup=
restart=
fake=
args=(
--help '$exit_with display_help'
--private-parse-server '$action=parse; parse_server=1'
--private-parse-tomcat-users '$action=parse; parse_tomcat_users=1'
--is-tmpdir '$istmpdir=1; tmpdir=.'
2017-04-18 11:35:54 +04:00
-c:,--config: config=
-C:,--config-profile: tomcat_profile=
-d:,--catalina-base:,--catalina-home: catalina_base=
-U:,--tomcat-user: tomcat_user=
-G:,--tomcat-group: tomcat_group=
-V:,--tomcat-version: tomcat_version=
-g:,--manager-url: manager_url=
-u:,--user: manager_user=
-p:,--password: manager_password=
-m:,--wamap: wamaps
-b,--backup backup=1
--no-backup backup=0
-B,--backup-only action=backup
--restart restart=1
-n,--no-restart restart=0
-r,--restart-only action=restart
--fake fake=1
2017-04-19 08:12:32 +04:00
--config-template action=config-template
2017-04-18 11:35:54 +04:00
)
parse_args "$@"; set -- "${args[@]}"
if [ "$action" == parse ]; then
CATALINA_BASE="$1"
TOMCAT_VERSION="$2"
if [ -n "$parse_server" ]; then
parse_server
echo_setv2 MANAGER_URL
fi
if [ -n "$parse_tomcat_users" ]; then
parse_tomcat_users
echo_setv2 MANAGER_USER
echo_setv2 MANAGER_PASSWORD
fi
exit 0
fi
# Charger la configuration
__reset_vars
if [ -n "$config" ]; then
eval "$(
__reset_vars
CATALINA_HOME=
source "$config" 2>/dev/null || exit 1
[ -n "$CATALINA_BASE" ] || CATALINA_BASE="$CATALINA_HOME"
__dump_vars
)"
fi
# Traiter la ligne de commande
for var in "${VARS[@]}"; do
lvar="${var,,}"
if [ -n "${!lvar}" ]; then
setv "$var" "${!lvar}"
fi
done
[ -n "$RESTART" ] || RESTART=1 # valeur par défaut
normyesvals BACKUP RESTART
for var in "${ARRAYS[@]}"; do
lvar="${var,,}"
if ! array_isempty "$lvar"; then
array_copy "$var" "$lvar"
fi
done
array_fix_paths WAMAPS ,
# Calculer le profil de connexion
if [ -z "$TOMCAT_PROFILE" ]; then
for v in 8 7; do
if [ -d /var/lib/tomcat$v ]; then
TOMCAT_PROFILE=debian:tomcat$v
break
fi
done
fi
if [ -z "$TOMCAT_PROFILE" ]; then
v=
if [ -L /opt/tomcat ]; then
setx v=readlink /opt/tomcat
setx v=basename -- "$v"
else
array_lsdirs ts /opt "apache-tomcat-*"
if [ ${#ts[*]} -gt 0 ]; then
[ -n "$CATALINA_BASE" ] || CATALINA_BASE="${ts[0]}"
v="$CATALINA_BASE"
[ -L "$v" ] && setx v=readlink "$v"
setx v=basename -- "$v"
fi
fi
if [ -n "$v" ] && [[ "$v" == apache-tomcat-* ]]; then
v=${v#apache-tomcat-}
mv=${v%%.*}
if [ -f /etc/init.d/tomcat$mv ]; then
TOMCAT_PROFILE=runs:tomcat$mv
else
TOMCAT_PROFILE=runs:tomcat
fi
[ -z "$TOMCAT_VERSION" ] && TOMCAT_VERSION="$v"
fi
fi
if [ -n "$TOMCAT_PROFILE" ]; then
case "$TOMCAT_PROFILE" in
debian:*|runs:*) ;;
d:*) TOMCAT_PROFILE="debian:tomcat${TOMCAT_PROFILE#d:}";;
*) TOMCAT_PROFILE="runs:$TOMCAT_PROFILE";;
esac
fi
# Calculer les valeurs dérivées du profil de connexion
case "$TOMCAT_PROFILE" in
debian:*)
t="${TOMCAT_PROFILE#debian:}"
v="${t#tomcat}"
[ -z "$CATALINA_BASE" ] && CATALINA_BASE="/var/lib/$t"
eval "$(
setv "${t^^}_USER"
setv "${t^^}_GROUP"
source "/etc/default/$t" 2>/dev/null
eval "echo tomcat_user=\"\$${t^^}_USER\""
eval "echo tomcat_group=\"\$${t^^}_GROUP\""
)"
[ -z "$TOMCAT_USER" ] && TOMCAT_USER="$tomcat_user"
[ -z "$TOMCAT_GROUP" ] && TOMCAT_GROUP="$tomcat_group"
[ -z "$TOMCAT_VERSION" ] && TOMCAT_VERSION="$v"
;;
runs:*)
v="${TOMCAT_PROFILE#runs:tomcat}"
if [ -z "$CATALINA_BASE" -a "$v" != "$TOMCAT_PROFILE" ]; then
array_lsdirs ts /opt "apache-tomcat-$v*"
CATALINA_BASE="${ts[0]}"
fi
if [ -z "$CATALINA_BASE" ]; then
if [ -L /opt/tomcat ]; then
setx CATALINA_BASE=readlink /opt/tomcat
else
array_lsdirs ts /opt "apache-tomcat-*"
CATALINA_BASE="${ts[0]}"
fi
fi
name="${TOMCAT_PROFILE#runs:}"
eval "$(
TOMCAT_USER=
source "/etc/default/$name" 2>/dev/null
echo tomcat_user="$TOMCAT_USER"
)"
[ -z "$TOMCAT_USER" ] && TOMCAT_USER="$tomcat_user"
if [ -z "$TOMCAT_VERSION" ]; then
v="$CATALINA_BASE"
[ -L "$v" ] && setx v=readlink "$v"
setx v=basename -- "$v"
if [[ "$v" == apache-tomcat-* ]]; then
TOMCAT_VERSION="${v#apache-tomcat-}"
fi
fi
;;
esac
# Calculer les valeurs dérivées des fichiers de $CATALINA_BASE
if [ -n "$CATALINA_BASE" -a -n "$TOMCAT_VERSION" ]; then
if [ -z "$MANAGER_URL" -o -z "$MANAGER_USER" ]; then
# lire les fichiers de configuratione et déterminer MANAGER_URL,
# MANAGER_USER et MANAGER_PASSWORD
if is_root; then
[ -z "$MANAGER_URL" ] && parse_server
[ -z "$MANAGER_USER" ] && parse_tomcat_users
else
args=()
[ -z "$MANAGER_URL" ] && array_add args --private-parse-server
[ -z "$MANAGER_USER" ] && array_add args --private-parse-tomcat-users
array_add args "$CATALINA_BASE" "$TOMCAT_VERSION"
eval "$(run_as root --noexec "${args[@]}")"
fi
fi
fi
# A partir de la liste des webapps et de WAMAPS, construire une liste de couples
# waname:src pour la sauvegarde et/ou le déploiement
2017-04-19 08:12:32 +04:00
[ -n "$fake" -o "$action" == config-template ] && require_webapps= || require_webapps=1
if [ $# -eq 0 -a -n "$require_webapps" ]; then
2017-04-18 11:35:54 +04:00
[ -d WEB-INF ] && src=. || src=
read_value "Veuillez entrer la webapp à déployer" src "$src" O
set -- "$src"
fi
srcs=()
[ -n "$istmpdir" ] || ac_set_tmpdir tmpdir
2017-04-18 11:35:54 +04:00
for src in "$@"; do
if [ -f "$src" ] && is_archive "$src"; then
2017-04-18 11:35:54 +04:00
setx waname=get_archive_appname "$src"
wadir="$tmpdir/$waname"
mkdir "$wadir"
if extract_archive "$src" "$wadir"; then
array_add srcs "$wadir"
2017-04-18 11:35:54 +04:00
else
eerror "$src: erreur lors de l'extraction de l'archive"
fi
elif [ -d "$src" ]; then
array_add srcs "$(abspath "$src")"
elif [ -e "$src" ]; then
eerror "$src: fichier invalide"
2017-04-18 11:35:54 +04:00
else
eerror "$src: fichier ou répertoire introuvable"
2017-04-18 11:35:54 +04:00
fi
done
2017-04-19 08:12:32 +04:00
[ ${#srcs[*]} -gt 0 -o -z "$require_webapps" ] || die
2017-04-18 11:35:54 +04:00
deploymaps=()
for src in "${srcs[@]}"; do
setx waname=basename -- "$src"
found=
for wamap in "${WAMAPS[@]}"; do
splitpair "$wamap" from to
if [ "$waname" == "$from" ]; then
found=1
array_add deploymaps "$to:$src"
fi
done
if [ -z "$found" ]; then
array_add deploymaps "$waname:$src"
fi
done
################################################################################
# Maintenant, nous pouvons faire les actions
2017-04-19 08:12:32 +04:00
if [ "$action" == config-template ]; then
if [ ${#deploymaps[*]} -gt 0 ]; then
toinstconfname=.toinst.conf
else
toinstconfname=toinst.conf
deploymaps=(:.)
fi
for deploymap in "${deploymaps[@]}"; do
splitpair "$deploymap" waname src
toinstconf="$src/$toinstconfname"
if [ -f "$toinstconf" ]; then
estepi "$(ppath "$toinstconf"): configuration déjà existante"
else
estep "$(ppath "$toinstconf")"
echo >"$toinstconf" "# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
# Fichiers à exclure de la source lors du déploiement
#$(echo_seta2 EXCLUDES)
# Fichiers à protéger dans la destination lors du déploiement
#$(echo_seta2 PROTECTS)"
fi
done
exit 0
fi
2017-04-18 11:35:54 +04:00
## Sauvegarde
if [ -n "$BACKUP" -o "$action" == backup ]; then
if [ -n "$fake" ]; then
:
else
:
fi
fi
## Déploiement
if [ "$action" == deploy ]; then
[ -n "$CATALINA_BASE" -o -n "$fake" ] || die "Vous devez spécifier l'option --catalina-base"
if [ -n "$fake" ]; then
# Afficher ce qu'il faut faire
etitle "Variables définies" __dump_vars
etitle "Déploiements des webapps"
for deploymap in "${deploymaps[@]}"; do
splitpair "$deploymap" waname src
setx srcname=basename -- "$src"
dest="${CATALINA_BASE:-CATALINA_BASE}/webapps/$waname"
etitle "$waname"
evalx qvals rsync "${RSYNC_OPTIONS[@]}" "$src/" "$dest" // eecho
evalx qvals chmod -R u=rwX,g=rX,o=rX "$dest" // eecho
if [ -n "$TOMCAT_USER" ]; then
evalx qvals chown -R "$TOMCAT_USER:$TOMCAT_GROUP" "$dest" // eecho
fi
eend
done
eend
elif ! is_root; then
# le déploiement doit être fait en root
args=(
-C "$TOMCAT_PROFILE"
-d "$CATALINA_BASE"
-U "$TOMCAT_USER"
-G "$TOMCAT_GROUP"
-V "$TOMCAT_VERSION"
-g "$MANAGER_URL"
-u "$MANAGER_USER"
-p "$MANAGER_PASSWORD"
-m "$(array_join WAMAPS ,)"
--no-backup
--no-restart
)
run_as root --noexec "${args[@]}" "${srcs[@]}" || die
else
# faire le déploiement
etitle "Déploiements des webapps"
for deploymap in "${deploymaps[@]}"; do
splitpair "$deploymap" waname src
setx srcname=basename -- "$src"
dest="$CATALINA_BASE/webapps/$waname"
etitle "$srcname"
estepi "Déploiement vers $dest"
estep "Copie des fichiers"
if ! rsync "${RSYNC_OPTIONS[@]}" "$src/" "$dest"; then
eerror "Une erreur s'est produite pendant la copie des fichiers"
else
error=
estep "Correction des permissions et du propriétaire"
chmod -R u=rwX,g=rX,o=rX "$dest" || error=1
if [ -n "$TOMCAT_USER" ]; then
chown -R "$TOMCAT_USER:$TOMCAT_GROUP" "$dest" || error=1
fi
if [ -n "$error" ]; then
eeror "Une erreur s'est produite pendant la mise à jour"
fi
fi
eend
done
eend
fi
fi
## Redémarrage
if [ -n "$RESTART" -o "$action" == restart ]; then
etitle "Redémarrage des webapps"
if [ -z "$MANAGER_URL" -o -z "$MANAGER_USER" ]; then
ewarn "Impossible de recharger la webapp parce que l'url du manager et/ou le compte admin n'ont pas pu être déterminés."
[ -z "$fake" ] && enote "\
Par défaut, les webapps ne sont rechargées automatiquement que si le fichier web.xml est modifié.
Utilisez les options -g, -u, -p pour spécifier les informations manquantes nécessaires au pilotage du manager."
elif [ -n "$fake" ]; then
estepi "Utilisation du manager à l'adresse $MANAGER_URL"
for deploymap in "${deploymaps[@]}"; do
splitpair "$deploymap" waname src
etitle "$waname"
evalx qvals curl -fsS -u "$MANAGER_USER:$MANAGER_PASSWORD" "$MANAGER_URL/reload?path=/$waname" // eecho
eend
done
else
estepi "Utilisation du manager à l'adresse $MANAGER_URL"
for deploymap in "${deploymaps[@]}"; do
splitpair "$deploymap" waname src
ebegin "$waname"
curl -fsS -u "$MANAGER_USER:$MANAGER_PASSWORD" "$MANAGER_URL/reload?path=/$waname" >/dev/null
eend $?
done
fi
eend
fi