nutools/lib/ulib/woinst

668 lines
23 KiB
Bash

##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
## Déploiement de bundle WebObjects
##@cooked nocomments
##@require ulib
##@require base
##@require prefixes
##@require apache
##@require webobjects
uprovide woinst
urequire ulib base prefixes apache webobjects
function date2version() {
local date="$1"
dd="$(expr "$date" : "\(..\)")"; [ -z "$dd" ] && dd="$(date +%d)"
mm="$(expr "$date" : "../\(..\)")"; [ -z "$mm" ] && mm="$(date +%m)"
yyyy="$(expr "$date" : "../../\(....\)")"; [ -z "$yyyy" ] && yyyy="$(date +%Y)"
yy="$(expr "$yyyy" : "..\(..\)")"
echo "$yyyy$mm$dd"
}
function woconf() {
function __woconf_display_help() {
uecho "woctl configure: configurer une application ou un framework
USAGE
configure <app.woa|fwk.framework> [cmds...]
cmds est soit un unique argument avec une commande par ligne, soit une suite de commandes séparées par //
COMMANDES
# comment
Les commentaires sont ignorés
v[erify]
Vérifier le corriger la consistance du bundle.
Cette action est effectuée automatiquement sauf si l'option --no-verify
est spécifiée.
set_config configfile
c>configfile
Changer le fichier de configuration par défaut
set_config configfile srcfile
c>configfile:srcfile
Créer le fichier configfile en le copiant depuis srcfile, et en faire le
nouveau fichier de configuration par défaut
set_property prop value [configfile]
c[configfile/]prop=value
Modifier une propriété dans le fichier de configuration spécifié.
Utiliser le fichier de configuration par défaut si configfile n'est pas
spécifié.
set_eomodel eomodel
e>eomodel
Changer l'eomodel par défaut
set_dbconfig dbConfig [eomodel]
e[eomodel/]dbConfig
Activer la configuration dbConfig dans l'eomodel spécifié. Utiliser
l'eomodel par défaut si eomodel n'est pas spécifié.
add Fwk.framework
aFwk.framework
Ajouter un framework au classpath de l'application
remove Fwk.framework
rFwk.framework
Enlever un framework du classpath de l'application
replace before after
sbefore:after
Faire un recherche/remplace dans les fichiers de classpath de
l'application.
f[ix_case]
Corriger la casse dans les fichiers de classpath de l'application, selon
les frameworks effectivement installés. En effet, un déploiement qui
peut fonctionner sur MacOSX, dont le système de fichier n'est pas
sensible à la casse, peut cesser de fonctionner sur Linux, parce que le
nom du jar ne correspond pas."
}
local noverify bundle cmds cmd
noverify=
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with __woconf_display_help' \
--noverify,--no-verify noverify=1 \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
bundle="$1"; shift
[ -n "$bundle" ] || {
eerror "Il faut spécifier le bundle à configurer"
return 1
}
if is_wobundle "$bundle" && is_woappdir "$bundle"; then
:
elif is_wobundle "$bundle" && is_wofwkdir "$bundle"; then
:
else
eerror "N'est pas un bundle valide: $bundle"
return 1
fi
bundle="$(abspath "$bundle")"
[ -w "$bundle" ] || die "Bundle non accessible en écriture"
if [ $# -le 1 ]; then
array_from_lines cmds "$(filter_comment <<<"$1")"
else
cmds=()
cmd=()
while [ -n "$1" ]; do
if [ "$1" == // ]; then
if [ -n "${cmd[*]}" ]; then
cmds=("${cmds[@]}" "$(qvals "${cmd[@]}")")
fi
cmd=()
else
cmd=("${cmd[@]}" "$1")
fi
shift
done
if [ -n "${cmd[*]}" ]; then
cmds=("${cmds[@]}" "$(qvals "${cmd[@]}")")
fi
fi
etitle "Configuration de $(ppath "$bundle")"
local verify_done first=1
[ -z "$noverify" ] && {
estep verify
verifix_bundle "$bundle"
verify_done=1
}
for cmd in "${cmds[@]}"; do
eval "set -- $cmd"
if [ $# -eq 1 ]; then
# commandes abrégées sur une lettre
case "$1" in
v|verify|verifix)
# si v est en premier, et que la vérification a déjà été faite,
# alors on peut l'ignorer
if [ -z "$first" -o -z "$verify_done" ]; then
estep "verify"
verifix_bundle "$bundle"
fi
;;
f|fix_case|fix-case)
estep "fix-case"
fix_jars_case "$bundle"
;;
c*)
eerror "set_config / set_property ne sont pas implémentés"
;;
e*)
eerror "set_eomodel / set_dbconfig ne sont pas implémentés"
;;
a*)
local framework="${1#a}"
estep "add $framework"
add_framework "$bundle" "$framework"
;;
r*)
local framework="${1#r}"
estep "remove $framework"
remove_framework "$bundle" "$framework"
;;
s*)
local search replace
replace="${1#s}"
search="${replace%%:*}"
replace="${replace#*:}"
if [ -n "$replace" ]; then
estep "Replace in classpath $search --> $replace"
else
estep "Delete in classpath $search"
fi
searchreplace_classpath "$bundle" "$search" "$replace"
;;
*) eerror "Commande invalide: $1";;
esac
else
# commandes "user-friendly"
case "$1" in
conf|config|set_conf|set_config)
eerror "set_config n'est pas implémenté"
;;
prop|property|set_prop|set_property)
eerror "set_property n'est pas implémenté"
;;
eomodel|set_eomodel)
eerror "set_eomodel n'est pas implémenté"
;;
dbconf|dbconfig|set_dbconf|set_dbconfig)
eerror "set_dbconfig n'est pas implémenté"
;;
add|add_fwk|add_framework)
estep "add $2"
add_framework "$bundle" "$2"
;;
remove|remove_fwk|remove_framework)
estep "remove $2"
remove_framework "$bundle" "$2"
;;
repl|replace)
if [ -n "$3" ]; then
estep "Replace in classpath $2 --> $3"
else
estep "Delete in classpath $2"
fi
searchreplace_classpath "$bundle" "$2" "$3"
;;
*) eerror "Commande invalide: $*";;
esac
fi
first=
done
eend
}
function wotag() {
function __wotag_display_help() {
uecho "woctl tag: attacher une information de version à un bundle
USAGE
tag [options] <bundle>
OPTIONS
-c Vérifier si des informations de versions existent dans le bundle
spécifié.
-s Afficher les informations de versions attachées
-v VERSION
Spécifier la version, ou '-' s'il n'y a pas de version
-d DATE
Spécifier la date de release
-m DESC
Spécifier une description du bundle
Si aucune des options -v, -d, -m n'est spécifiée, alors tenter de prendre les
informations de version et la date de release depuis le fichier VERSION.txt
situé dans le répertoire de resources.
Sinon, il faut saisir manuellement les informations."
}
local action newversion newdate newdesc
local version date desc release
local bundlename bundle found
action=tag
newversion=
newdate=
newdesc=
bundlename=
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with __wotag_display_help' \
-c action=check \
-s action=show \
-v:,--version: newversion= \
-d:,--date: newdate= \
-m:,--desc: newdesc= \
--message: bundlename= \
@ args -- "$@" &&
set -- "${args[@]}" || {
eerror "$args"
return 1
}
bundle="$1"
[ -n "$bundle" ] || {
eerror "Il faut spécifier le bundle à tagger"
return 1
}
if [ ! -d "$bundle" ]; then
if [ "$action" == "check" ]; then
return 1
elif [ "$action" == "show" ]; then
[ -z "$bundlename" ] && bundlename="$(basename "$bundle")"
eecho "$bundlename: not found"
return 0
else
eerror "Bundle non trouvé: $bundle"
return 1
fi
elif is_wobundle "$bundle" && is_woappdir "$bundle"; then
:
elif is_wobundle "$bundle" && is_wofwkdir "$bundle"; then
:
else
eerror "N'est pas un bundle valide: $bundle"
return 1
fi
bundle="$(abspath "$bundle")"
[ -z "$bundlename" ] && bundlename="$(basename "$bundle")"
local infofile="$(get_infofile "$bundle")"
local jawotoolsfile="$(get_jawotoolsfile "$bundle")"
local jawotoolsfile2="$bundle/jawotools.properties"
local versionfile="$(get_versionfile "$bundle")"
if [ "$action" == "check" ]; then
[ -f "$jawotoolsfile" ] || return 1
read_jawotoolsfile "$jawotoolsfile" version date
[ -n "$version" -o -n "$date" ] && return 0
return 1
elif [ "$action" == "show" ]; then
found=
if [ -f "$jawotoolsfile" ]; then
read_jawotoolsfile "$jawotoolsfile" version date desc
if [ -n "$version" -o -n "$date" ]; then
eecho "$bundlename: Version${version:+ "$version"}${date:+ du "$date"}${desc:+
("$desc")}"
found=1
fi
elif [ -f "$infofile" ]; then
read_infofile "$infofile" version release
if [ -n "$version" ]; then
eecho "$bundlename: Version $version${release:+ ("$release")}"
found=1
elif [ -n "$release" ]; then
eecho "$bundlename: Release $release"
found=1
fi
fi
[ -n "$found" ] || eecho "$bundlename: no version found"
elif [ "$action" == "tag" ]; then
# lire les valeurs actuelles
if [ -f "$jawotoolsfile" ]; then
read_jawotoolsfile "$jawotoolsfile" version date desc
fi
# si le fichier de version existe, lire la version et la date de release
if [ -z "$newversion" -a -z "$newdate" -a -f "$versionfile" ]; then
newversion="$(awk <"$versionfile" '{
gsub("-r../../....$", "")
print
exit
}')"
newdate="$(awk <"$versionfile" '{
if ($0 ~ /.*-r..\/..\/....$/) {
gsub(".*-r", "")
print
}
exit
}')"
fi
# si le fichier Info.plist existe, y lire les informations de version
if [ -z "$newversion" -a -z "$newdate" -a -f "$infofile" ]; then
read_infofile "$infofile" newversion release
[ -n "$newversion" ] || newversion="$release"
fi
# nous n'avons pas trouvé de version, il faut saisir les valeurs à la main
if [ -z "$newversion" -o -z "$newdate" ]; then
[ "$newversion" == "-" ] && newversion=
[ "$newdate" == "-" ] && newdate=
defversion="${newversion:-$version}"
read_value "Entrez la version (vide s'il n'y a que la date de release)" newversion "$defversion" N
defdate="${newdate:-${date:-$(date +"%d/%m/%Y")}}"
read_value "Entrez la date de release" newdate "$defdate"
defdesc="${newdesc:-$desc}"
read_value -i "Entrez une description du bundle" newdesc "$defdesc" N
fi
[ "$newversion" == "-" ] && newversion=
[ "$newdate" == "-" ] && newdate=
[ -n "$newversion" -o -n "$newdate" ] || {
eerror "Il faut spécifier le numéro de version et/ou la date de release"
return 1
}
eecho "$bundlename: Version${newversion:+ "$newversion"}${newdate:+ du "$newdate"}${newdesc:+
("$newdesc")}"
if [ "$newversion" != "$version" -o "$newdate" != "$date" -o "$newdesc" != "$desc" ]; then
[ "$jawotoolsfile" == "$jawotoolsfile2" ] || rm -f "$jawotoolsfile"
save_jawotoolsfile "$jawotoolsfile2" "$newversion" "$newdate" "$newdesc"
write_infofile "$infofile" "$newversion" "$(date2version "$newdate")"
else
einfo "Aucune modification effectuée"
fi
fi
}
WOINST_TMPDIR_SET=
function __woinst_set_tmpdir_maybe() {
if [ -z "$WOINST_TMPDIR_SET" ]; then
ac_set_tmpdir tmpdir
WOINST_TMPDIR_SET=1
fi
}
function __woinst_expand_archive() {
local archdir contents
__woinst_set_tmpdir_maybe
estep "Décompactage de $(ppath "$src") dans $tmpdir..."
archdir="$tmpdir/$(get_archive_appname "$src")"
mkdir -p "$archdir"
extract_archive "$src" "$archdir" || return 1
# s'il n'y a qu'un répertoire dans l'archive, le considérer comme le
# répertoire à déployer.
array_from_lines contents "$(list_all "$archdir")"
if [ "${#contents[*]}" -eq 1 -a -d "$archdir/$contents" ]; then
archdir="$archdir/$contents"
fi
src="$archdir"
}
function woinst() {
function __woinst_display_help() {
uecho "$scriptname: Déployer un bundle (application ou framework) de WebObjects
USAGE
$scriptname [options] <file|archive|dir>...
OPTIONS
PREFIX=value
Spécifier une valeur pour un préfixe, plutôt que de laisser uprefix
l'autodétecter. Utiliser uprefix -l pour une liste de préfixes valides.
--prefix
Corriger les chemins des variables qui commencent par des préfixes
valides (c'est la valeur par défaut). Utiliser 'uprefix -l' pour avoir
une liste de préfixes valides
--no-prefix
Ne jamais corriger un chemin.
--bundle
Déployer le bundle entier. C'est l'option par défaut.
-W, --webres
Ne déployer que les resources web. Implique --no-tag
--tag
Tagger les bundles déployés avec un numéro de version. L'utilisateur est
invité à compléter des informations telles que n° de version et date de
release si ces informations ne sont pas disponible. C'est l'option par
défaut.
-n, --no-tag
Ne pas tagger les bundles déployés avec un numéro de version.
-d, --active-dbconfig DBCONFIG
Spécifier le profil de connexion à utiliser par défaut pour tous les
eomodels du bundle. S'il faut un profil différent en fonction de l'eomodel, utiliser l'option -m
-m, --active-dbconfig-map EOMODEL:DBCONFIG
Spécifier un mapping entre un nom d'eomodel et le profil de connexion à
utiliser. Pour les eomodels qui ne sont pas spécifiés, la valeur par
défaut est utilisée si elle existe. Il est possible de spécifier
plusieurs mappings en les séparant par des virgules.
--stop-start
Redémarrer les instances de la manière classique: les instances sont
arrêtées avant le déploiement, et redémarrées après. C'est la valeur par
défaut.
-b, --bounce
Redémarrer les instances en mode bounce.
--no-restart
Ne pas redémarrer les instances
-x, --exec CMD
Exécuter la commande CMD après avoir effectué le déploiement"
}
local istmpdir tmpdir autoprefix=1 restart=yes webinst notag default_dbconfig
local -a dbconfigs scripts
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with __woinst_display_help' \
--is-tmpdir '$istmpdir=1; tmpdir=.' \
--prefix autoprefix=1 \
--no-prefix autoprefix= \
--bundle webinst= \
-W,--webres webinst=1 \
--tag notag= \
-n,--no-tag notag=1 \
-d:,--active-dbconfig: default_dbconfig= \
-m:,--active-dbconfig-map: dbconfigs \
--stop-start restart=yes \
-b,--bounce restart=bounce \
-no-restart restart=no \
-x:,--exec: scripts \
@ args -- "$@" &&
set -- "${args[@]}" || {
eerror "$args"
return 1
}
# Tout d'abord énumérer les frameworks et applications à installer
# Lire aussi les définitions de variables
compute_apache_prefixes
compute_webobjects_prefixes
etitle "Calcul de la liste des bundles à déployer"
if [ -z "$istmpdir" ]; then
__woinst_set_tmpdir_maybe
estep "La copie de travail sera faite dans $(ppath "$tmpdir")..."
fi
local -a variables frameworks applications
local src name value valid copied
variables=("${WEBOBJECTS_PREFIXES[@]}")
frameworks=()
applications=()
for src in "${@:-.}"; do
if [[ "$src" == *=* ]]; then
splitvar "$src" name value
array_addu variables "$name"
[ -n "$autoprefix" ] && value="$(expand_prefix "$value")"
_setv "$name" "$value"
else
src="$(abspath "$src")"
valid=
copied=
if [ -f "$src" ] && is_archive "$src"; then
__woinst_expand_archive || return 1
copied=1
fi
if [ -d "$src" ]; then
setx name=basename -- "$src"
case "$src" in
*.woa|*.framework) ;;
*) # support projet maven
if [ ! -f "$src/pom.xml" ]; then
: # non, pas un projet maven
elif [ -d "$src/target/$name.woa" ]; then
src="$src/target/$name.woa"
elif [ -d "$src/target/$name.framework" ]; then
src="$src/target/$name.framework"
fi
;;
esac
if endswith "$src" .framework; then
is_wofwkdir "$src" || {
eerror "Framework invalide: $(ppath "$src")"
return 1
}
valid=1
elif endswith "$src" .woa; then
is_woappdir "$src" || {
eerror "Application invalide: $(ppath "$src")"
return 1
}
valid=1
fi
fi
[ -n "$valid" ] || {
eerror "N'est pas un bundle valide: $(ppath "$src")"
return 1
}
srcname="$(basename "$src")"
if [ -z "$copied" -a -z "$istmpdir" ]; then
estep "$(ppath "$src")"
cpnovcs "$src" "$tmpdir"
src="$tmpdir/$srcname"
fi
if endswith "$src" .framework; then
array_add frameworks "$src"
elif endswith "$src" .woa; then
array_add applications "$src"
fi
fi
done
eend
# Corriger les eomodelds
array_fix_paths dbconfigs ,
if [ -n "$default_dbconfig" -o ${#dbconfigs[*]} -gt 0 ]; then
etitle "Configuration des eomodels"
local -a eonames eomodels tmpeomodels
local eom dbc eoname eomodel dbconfig found
estep "Calcul de la liste des eomodels"
if [ ${#dbconfigs[*]} -eq 0 ]; then
for src in "${frameworks[@]}"; do
array_from_lines tmpeomodels "$(find "$src" -type d -name "*.eomodeld")"
for eom in "${tmpeomodels[@]}"; do
array_addu eonames "$(basename -- "$eom")"
done
done
for src in "${applications[@]}"; do
array_from_lines tmpeomodels "$(find "$src" -type d -name "*.eomodeld")"
for eom in "${tmpeomodels[@]}"; do
array_addu eonames "$(basename -- "$eom")"
done
done
else
for dbc in "${dbconfigs[@]}"; do
splitpair "$dbc" eom dbc
[ "${eom%.eomodeld}" != "$eom" ] || eom="$eom.eomodeld"
array_addu eonames "$(basename -- "$eom")"
done
fi
for eom in "${eonames[@]}"; do
for src in "${frameworks[@]}"; do
array_from_lines tmpeomodels "$(find "$src" -type d -name "$eom")"
array_extendu eomodels tmpeomodels
done
for src in "${applications[@]}"; do
array_from_lines tmpeomodels "$(find "$src" -type d -name "$eom")"
array_extendu eomodels tmpeomodels
done
done
for eomodel in "${eomodels[@]}"; do
setx eoname=basename -- "$eomodel"
if [ ! -f "$eomodel/index.eomodeld" ]; then
ewarn "$eomodel: eomode invalide"
continue
fi
found=
for dbc in "${dbconfigs[@]}"; do
splitpair "$dbc" eom dbconfig
[ "${eom%.eomodeld}" != "$eom" ] || eom="$eom.eomodeld"
if [ "$(basename -- "$eom")" == "$eoname" ]; then
found="$dbconfig"
break
fi
done
[ -z "$found" -a -n "$default_dbconfig" ] && found="$default_dbconfig"
if [ -n "$found" ]; then
estep "$eomodel [$found]"
sed -i "/^ *activeDatabaseConfigName *=/s/=.*;/=\"$found\";/" "$eomodel/index.eomodeld"
fi
done
fi
# Tagger les bundles
if [ -z "$webinst" -a -z "$notag" ]; then
etitle "Tagger les bundles"
for src in "${frameworks[@]}"; do
srcname="$(basename "$src")"
etitle "$srcname"
wotag --message "Version installée" -s "$WOFRAMEWORKS/$srcname"
wotag --message "Version à installer" "$src"
eend
done
for src in "${applications[@]}"; do
srcname="$(basename "$src")"
etitle "$srcname"
wotag --message "Version installée" -s "$WOAPPLICATIONS/$srcname"
wotag --message "Version à installer" "$src"
eend
done
eend
fi
# Confirmer le déploiement
etitle "Résumé"
function __woinst_strip_woa() { basename "$1" .woa; }
function __woinst_strip_fwk() { basename "$1" .framework; }
estepn "Déploiement ${applications:+des applications: $(array_mapjoin applications __woinst_strip_woa " ")${frameworks:+
et }}${frameworks:+des frameworks: $(array_mapjoin frameworks __woinst_strip_fwk " ")}
dans NEXT_ROOT = ${NEXT_ROOT:-/}
HTDOCS_DIR = ${HTDOCSDIR}"
if ! ask_yesno -c "Voulez-vous lancer le déploiement?" O; then
eend
return 1
fi
eend
# Faire le déploiement
local configfile variable
ac_set_tmpfile configfile
for variable in "${variables[@]}" restart webinst ULIBDIR __estack __tlevel; do
echo_setv "$variable" "${!variable}" >>"$configfile"
done
for array in variables scripts applications frameworks; do
set_array_cmd "$array" >>"$configfile"
done
# pour les serveurs qui ont une vieille version de bash, forcer la valeur de
# ULIBDIR
echo_setv "FORCED_ULIBDIR" "$ULIBDIR" >>"$configfile"
runscript_as_root "$ULIBDIR/support/woinst2s" "$configfile"
ac_clean "$tmpdir" "$configfile"
}