##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 ## Pilotage du moniteur de ProjectWonder ##@cooked nocomments ##@require base ##@require sysinfos ##@require webobjects uprovide wondermonitor urequire base sysinfos webobjects WOM_DEFAULT_HOST=localhost WOM_DEFAULT_PORT="${JAVAMONITOR_PORT:-56789}" WOM_DEFAULT_PASSWORD="$JAVAMONITOR_PASSWORD" function __get_womurl() { # $1 est un nom d'hôte de la forme host[:port] # Le transfomer en url pour attaquer le moniteur: # http://host:port/cgi-bin/WebObjects/JavaMonitor.woa/$2[?pw=$3[&$4...]] # $2 est l'url relative à attaquer. Si $3 est spécifié, c'est le mot de # passe pour l'accès au moniteur. Si $4...* sont spécifiés, ce sont d'autres # paramètres. local host port password paramsep="?" if [ -n "$1" ]; then splitpair "$1" host port [ -n "$host" ] || host="$WOM_DEFAULT_HOST" [ -n "$port" ] || port="$WOM_DEFAULT_PORT" shift # si on spécifie explicitement l'hôte, considérer que le mot de passe # est explicitement spécifié aussi, et ne pas prendre la valeur par # défaut. password="$2" else host="$WOM_DEFAULT_HOST" port="$WOM_DEFAULT_PORT" shift password="${2:-$WOM_DEFAULT_PASSWORD}" fi local womurl="http://$host:$port/cgi-bin/WebObjects/JavaMonitor.woa" if [ -n "$1" ]; then [ "${1#/}" == "$1" ] && womurl="$womurl/" womurl="$womurl$1" fi; shift if [ -n "$password" ]; then womurl="$womurl${paramsep}pw=$password" paramsep="&" fi; shift while [ -n "$1" ]; do womurl="$womurl${paramsep}$1"; shift paramsep="&" done echo "$womurl" } function __check_type() { # vérifier que le type $1 (calculé par splitins()) est l'une des valeurs # $2..* local actual="$1" expected; shift for expected in "$@"; do [ "$actual" == "$expected" ] && return 0 done return 1 } function __json_filter() { # traiter un flux json pour que chaque valeur soit sur une ligne séparée, # facilitant le traitement par un script bash awk '{ gsub(/}\][ ]*$/, "\n&") gsub(/},[ ]*$/, "\n&") gsub(/[][{]/, "&\n") gsub(/,[ ]*"/, ",\n\"") #gsub(/"}/, "\",\n}") print }' } function wom__statistics() { # Afficher les statistiques pour le serveur $1, avec éventuellement le mot # de passe $2 wogeturl "$(__get_womurl "$1" wa/statistics "$2")" || return } function wom__info() { # Contacter le moniteur sur l'hôte $2, avec éventuellement le mot de passe # $3, et afficher des informations sur l'application $1 (par défaut, all) local type name splitins "$1" type name __check_type "$type" all app ins || return 2 wogeturl "$(__get_womurl "$2" admin/info "$3" type="$type" ${name:+name=$name})" || return } function wom__info_filter() { # filtrer le résultat de wom__info en ne gardant que les tags # name, state, activeSessions, autoRecover, deaths, host, port awkrun -f ' function get_value(line) { match(line, /^[^"]*"[^"]*":[ ]*"?/); line = substr(line, RSTART + RLENGTH) match(line, /"?[ ]*,?[ ]*$/); line = substr(line, 1, RSTART - 1) return line } function reset_values() { name = ""; state = ""; activeSessions = ""; autoRecover = ""; deaths = "" host = ""; port = "" } function dump_values() { if (name != "") { print quote_value(name) " " quote_value(state) " " quote_value(activeSessions) " " quote_value(autoRecover) " " quote_value(deaths) " " quote_value(host) " " quote_value(port) } reset_values() } BEGIN { inapp = 0 reset_values() } /{/ { inapp = 1 } /}/ { dump_values(); inapp = 0 } inapp && $0 ~ /"name"/ { name = get_value($0) } inapp && $0 ~ /"state"/ { state = get_value($0) } inapp && $0 ~ /"activeSessions"/ { activeSessions = get_value($0) } inapp && $0 ~ /"autoRecover"/ { autoRecover = get_value($0) } inapp && $0 ~ /"deaths"/ { deaths = get_value($0) } inapp && $0 ~ /"host"/ { host = get_value($0) } inapp && $0 ~ /"port"/ { port = get_value($0) } ' } function wom_info() { # Contacter le moniteur sur l'hôte $3, avec éventuellement le mot de passe # $4, et initialiser le tableau $1 avec une liste de valeurs quotés de la # forme: # "'name' 'state' 'activeSessions' 'autoRecover' 'deaths' 'host' 'port'" # concernant l'application $2 (par défaut, toutes les applications). Notez # qu'il y a une ligne par instance d'application # Ces valeurs peuvent être utilisées comme arguments d'une fonction. par # exemple: # wom_info appinfos "" host pw # for args in "${appinfos[@]}"; do # eval "userfunc $args" # done wom__info "$2" "$3" "$4" || return array_from_lines "$1" "$(<"$WORAURL_DATA" __json_filter | wom__info_filter)" } function wom_getValidAndRunning() { # Placer la liste des applications valides dans le tableau $1(=valid_apps) # et la liste des applications qui tournent dans le tableau # $2=(running_apps), en contactant le moniteur sur l'hôte $3, avec # éventuellement le mot de passe $4. local -a __vr_appinfos __vr_valids="${1:-valid_apps}" __vr_runnings="${2:-running_apps}" local __vr_appinfo wom_info __vr_appinfos "$3" "$4" || return array_new "$__vr_valids" array_new "$__vr_runnings" for __vr_appinfo in "${__vr_appinfos[@]}"; do eval "__vr_appinfo=($__vr_appinfo)" array_addu "$__vr_valids" "${__vr_appinfo[0]}" if [ "${__vr_appinfo[1]}" == "ALIVE" ]; then array_addu "$__vr_runnings" "${__vr_appinfo[0]}" fi done } function show_appinfo() { # Afficher des informations sur une application. Les arguments doivent être # le résultat de la fonction wom_info() local name="$1" state="$2" local activeSessions="$3" autoRecover="$4" deaths="$5" local host="$6" port="$7" local color suffix case "$state" in ALIVE) color="$COULEUR_VERTE" suffix="NbSessions: " [ "${activeSessions:-0}" -gt 0 ] && suffix="$suffix$COULEUR_BLEUE" suffix="$suffix$activeSessions$COULEUR_NORMALE, deaths=" [ "${deaths:-0}" -gt 0 ] && suffix="$suffix$COULEUR_ROUGE" suffix="$suffix$deaths$COULEUR_NORMALE" ;; DEAD) color="";; STARTING|STOPPING) color="$COULEUR_BLEUE";; *) color="$COULEUR_JAUNE";; esac eecho "$color$name$COULEUR_NORMALE ($state)${suffix:+: $suffix}" } function wom_running() { # Contacter le moniteur sur l'hôte $2, avec éventuellement le mot de passe # $3, et tester si l'application $1 (par défaut, all) tourne actuellement local type name splitins "$1" type name __check_type "$type" all app ins || return 2 wogeturl "$(__get_womurl "$2" admin/running "$3" type="$type" ${name:+name=$name})" || return is_yes "$(<"$WORAURL_DATA")" } function wom_start() { # Contacter le moniteur sur l'hôte $2, avec éventuellement le mot de passe # $3, et démarrer l'application $1 (par défaut, all) local type name splitins "$1" type name __check_type "$type" all app ins || return 2 wogeturl "$(__get_womurl "$2" admin/start "$3" type="$type" ${name:+name=$name})" || return [ "$(<"$WORAURL_DATA")" == "OK" ] } function wom_stopped() { # Contacter le moniteur sur l'hôte $2, avec éventuellement le mot de passe # $3, et tester si l'application $1 (par défaut, all) est actuellement arrêtée local type name splitins "$1" type name __check_type "$type" all app ins || return 2 wogeturl "$(__get_womurl "$2" admin/stopped "$3" type="$type" ${name:+name=$name})" || return is_yes "$(<"$WORAURL_DATA")" } function wom_stop() { # Contacter le moniteur sur l'hôte $2, avec éventuellement le mot de passe # $3, et arrêter l'application $1 (par défaut, all) local type name splitins "$1" type name __check_type "$type" all app ins || return 2 wogeturl "$(__get_womurl "$2" admin/stop "$3" type="$type" ${name:+name=$name})" || return [ "$(<"$WORAURL_DATA")" == "OK" ] } function wom_forceQuit() { # Contacter le moniteur sur l'hôte $2, avec éventuellement le mot de passe # $3, et forcer l'arrêt de l'application $1 (par défaut, all) local type name splitins "$1" type name __check_type "$type" all app ins || return 2 wogeturl "$(__get_womurl "$2" admin/forceQuit "$3" type="$type" ${name:+name=$name})" || return [ "$(<"$WORAURL_DATA")" == "OK" ] } function wom_turnScheduledOn() { # Contacter le moniteur sur l'hôte $2, avec éventuellement le mot de passe # $3, et activer le flag scheduled sur l'application $1 (par défaut, all) local type name splitins "$1" type name __check_type "$type" all app ins || return 2 wogeturl "$(__get_womurl "$2" admin/turnScheduledOn "$3" type="$type" ${name:+name=$name})" || return [ "$(<"$WORAURL_DATA")" == "OK" ] } function wom_turnScheduledOff() { # Contacter le moniteur sur l'hôte $2, avec éventuellement le mot de passe # $3, et désactiver le flag scheduled sur l'application $1 (par défaut, all) local type name splitins "$1" type name __check_type "$type" all app ins || return 2 wogeturl "$(__get_womurl "$2" admin/turnScheduledOff "$3" type="$type" ${name:+name=$name})" || return [ "$(<"$WORAURL_DATA")" == "OK" ] } function wom_turnRefuseNewSessionOn() { # Contacter le moniteur sur l'hôte $2, avec éventuellement le mot de passe # $3, et activer le flag refuseNewSession sur l'application $1 (par défaut, # all) local type name splitins "$1" type name __check_type "$type" all app ins || return 2 wogeturl "$(__get_womurl "$2" admin/turnRefuseNewSessionOn "$3" type="$type" ${name:+name=$name})" || return [ "$(<"$WORAURL_DATA")" == "OK" ] } function wom_turnRefuseNewSessionOff() { # Contacter le moniteur sur l'hôte $2, avec éventuellement le mot de passe # $3, et désactiver le flag refuseNewSession sur l'application $1 (par # défaut, all) local type name splitins "$1" type name __check_type "$type" all app ins || return 2 wogeturl "$(__get_womurl "$2" admin/turnRefuseNewSessionOff "$3" type="$type" ${name:+name=$name})" || return [ "$(<"$WORAURL_DATA")" == "OK" ] } function wom_turnAutoRecoverOn() { # Contacter le moniteur sur l'hôte $2, avec éventuellement le mot de passe # $3, et activer le flag autoRecover sur l'application $1 (par défaut, all) local type name splitins "$1" type name __check_type "$type" all app ins || return 2 wogeturl "$(__get_womurl "$2" admin/turnAutoRecoverOn "$3" type="$type" ${name:+name=$name})" || return [ "$(<"$WORAURL_DATA")" == "OK" ] } function wom_turnAutoRecoverOff() { # Contacter le moniteur sur l'hôte $2, avec éventuellement le mot de passe # $3, et désactiver le flag autoRecover sur l'application $1 (par défaut, # all) local type name splitins "$1" type name __check_type "$type" all app ins || return 2 wogeturl "$(__get_womurl "$2" admin/turnAutoRecoverOff "$3" type="$type" ${name:+name=$name})" || return [ "$(<"$WORAURL_DATA")" == "OK" ] } function wom_bounce() { # Contacter le moniteur sur l'hôte $2, avec éventuellement le mot de passe # $3, et redémarrer l'application $1 (par défaut, all) en mode bounce local type name splitins "$1" type name __check_type "$type" app all || return 2 wogeturl "$(__get_womurl "$2" admin/bounce "$3" type="$type" ${name:+name=$name})" || return [ "$(<"$WORAURL_DATA")" == "OK" ] } function wom_clearDeaths() { # Contacter le moniteur sur l'hôte $2, avec éventuellement le mot de passe # $3, et effacer le compte des morts suspectes pour l'application $1 (par # défaut, all) local type name splitins "$1" type name __check_type "$type" app all || return 2 wogeturl "$(__get_womurl "$2" admin/clearDeaths "$3" type="$type" ${name:+name=$name})" || return [ "$(<"$WORAURL_DATA")" == "OK" ] } function wom__getApplications() { # Obtenir des information sur la définition de l'application $1 (ou de # toutes les applications si $1=="") en contactant le moniteur sur l'hôte $2 # avec éventuellement le mot de passe $3. Le résultat est un flux xml, # chaque application étant défini dans un tag . Si un erreur # se produit, l'erreur est dans un tag woraurl GET "$(__get_womurl "$2" "ra/mApplications${1:+/$1}" "$3")" || return } function wom__getApplications_filter() { # filtrer le résultat de wom__getApplications en ne gardant que les tags # name, unixPath, macPath, winPath awkrun -f ' function get_value(line) { if (line ~ / nil="true"/) return "" match(line, /^[^<]*<[^<>]*>/); line = substr(line, RSTART + RLENGTH) match(line, /<.*$/); line = substr(line, 1, RSTART - 1) return line } function get_attr_value(attr, line) { match(line, attr "=\""); line = substr(line, RSTART + RLENGTH) match(line, /".*$/); line = substr(line, 1, RSTART - 1) return line } function reset_values() { name = "" unixPath = "" macPath = "" winPath = "" } function dump_values() { if (name != "") { print quote_value(name) " " quote_value(unixPath) " " quote_value(macPath) " " quote_value(winPath) } reset_values() } BEGIN { inapp = 0 reset_values() } / ]/ { name = get_value($0) } inapp && $0 ~ / ]/ { unixPath = get_value($0) } inapp && $0 ~ / ]/ { macPath = get_value($0) } inapp && $0 ~ / ]/ { winPath = get_value($0) } ' } function wom_getApplications() { # Obtenir la liste des applications définies en contactant le moniteur sur # l'hôte $3 avec éventuellement le mot de passe $4, et initialiser le # tableau $1 avec une liste de valeurs quotées de la forme: # "'name' 'unixPath' 'macPath' 'winPath'" # concernant l'application $2 (par défaut, toutes les applications) # Ces valeurs peuvent être utilisées comme arguments d'une fonction. par # exemple: # wom_getApplications appinfos "" host pw # for args in "${appinfos[@]}"; do # eval "userfunc $args" # done array_new "$1" wom__getApplications "$2" "$3" "$4" || return array_from_lines "$1" "$(<"$WORAURL_DATA" wom__getApplications_filter)" } function wom_addApplication() { # Ajouter une application nommée $1 en contactant le moniteur sur l'hôte $2, # avec éventuellement le mot de passe $3. # Soit le nom Name, par défaut l'exécutable se trouve dans # WOAPPLICATIONS/Name.woa/Name et les logs dans /var/log/WebObjects, et le # flag autoRecover est activé # XXX supporter la possibilité de modifier les valeurs par défaut local name="$1" unixPath macPath unixOutputPath macOutputPath if [ "$UNAME_SYSTEM" == "Darwin" ]; then unixPath= unixOutputPath= macPath="$WOAPPLICATIONS/$name.woa/$name" macOutputPath="$WOLOGS" else macPath= macOutputPath= unixPath="$WOAPPLICATIONS/$name.woa/$name" unixOutputPath="$WOLOGS" fi local data="{id: '$name', type: 'MApplication', name: '$name', unixOutputPath: '$unixOutputPath', unixPath: '$unixPath', macOutputPath: '$macOutputPath', macPath: '$macPath', autoRecover: false}" woraurl POST "$(__get_womurl "$2" ra/mApplications.json "$3")" "$data" } function wom_addInstance() { # Ajouter une instance sur localhost pour l'application nommée $1 en # contactant le moniteur sur l'hôte $2, avec éventuellement le mot de passe # $3. # XXX supporter la possibilité de modifier les valeurs par défaut woraurl GET "$(__get_womurl "$2" "ra/mApplications/$1/addInstance" "$3" host=localhost)" # cette requête plante pour je ne sais quelle raison: (faire des investigations!) #woraurl GET "$(__get_womurl "$2" "ra/mApplications/$1/addInstanceOnAllHosts" "$3")" } function check_compute_apps_localhost() { # si les arguments de compute_apps contiennent des bundles de framework, il # faut avoir accès au système de fichier local. vérifier si l'un des # arguments $2..* est un framework. si c'est le cas, vérifier que l'hôte $1 # est localhost. # retourner 0 si c'est ok, 1 s'il y a des frameworks et que host n'est pas # localhost local host="$1"; shift local spec type name for spec in "$@"; do splitins "$spec" type name if [ "$type" == "fwk" ]; then if [ -z "$host" -o "$host" == "localhost" -o "$host" == "127.0.0.1" ]; then return 0 else eerror "Spécifier des bundles de framework n'est supporté que sur l'hôte local" return 1 fi fi done return 0 } function compute_apps() { # Remplir le tableau $1(=apps) avec la liste des applications correspondant # aux arguments $3...* # Un bundle de framework (Name.framework) est remplacé par la liste des # bundles d'applications qui dépendent de ce framework. Cette information # est obtenue en consultant le système de fichier local. # Un bundle d'application est remplacé par la liste des applications qui # sont définies pour ce bundle. Cette information est obtenue en consultant # le tableau généré par wom_getApplications(), dont le nom est $2 # Les arguments de la forme @N sont ignorés, ils correspondent à des délais # à respecter lors du démarrage de l'application local -a __ca_specs local __ca_notempty local __ca_spec __ca_type __ca_name __ca_fapps __ca_appinfo __ca_path __ca_found __ca_fapps=() local __ca_apps="${1:-apps}"; shift local __ca_appinfos="$1"; shift if [ -z "$__ca_appinfos" ]; then # si on ne donne pas le tableau de wom_getApplications, le calculer nous # même wom_getApplications __ca_appinfos else array_copy __ca_appinfos "$__ca_appinfos" fi array_new "$__ca_apps" [ -n "$*" ] && __ca_notempty=1 __ca_specs=("$@") while [ -n "${__ca_specs[*]}" ]; do set -- "${__ca_specs[@]}" # si un framework est spécifié, il faut rajouter d'autres bundles # d'applications. il sont insérés dans __ca_specs __ca_specs=() for __ca_spec in "$@"; do if [[ "$__ca_spec" == @* ]]; then array_add "$__ca_apps" "$__ca_spec" continue fi splitins "$__ca_spec" __ca_type __ca_name if [ "$__ca_type" == "fwk" ]; then compute_fapps __ca_fapps "$__ca_name" if [ -n "${__ca_fapps[*]}" ]; then estep "$__ca_name --> ${__ca_fapps[*]}" for __ca_spec in "${__ca_fapps[@]}"; do # rajouter l'application dans __ca_specs, pour traitement array_addu __ca_specs "$__ca_spec" done else ewarn "$__ca_name: Aucune correspondance n'a été trouvée" fi elif [ "$__ca_type" == "woa" ]; then __ca_found= for __ca_appinfo in "${__ca_appinfos[@]}"; do eval "__ca_appinfo=($__ca_appinfo)" if [ "$UNAME_SYSTEM" == "Darwin" ]; then __ca_path="${__ca_appinfo[2]}" else __ca_path="${__ca_appinfo[1]}" fi if [[ "$__ca_path" == */"$__ca_name/${__ca_name%.woa}" ]]; then # trouvé estep "$__ca_name --> ${__ca_appinfo[0]}" array_addu "$__ca_apps" "${__ca_appinfo[0]}" __ca_found=1 # note: ne pas s'arrêter ici. il peut y avoir d'autres # instances pour cette application fi done [ -n "$__ca_found" ] || ewarn "$__ca_name: Aucune correspondance n'a été trouvée" else array_addu "$__ca_apps" "$__ca_name" fi done done if array_isempty "$__ca_apps" && [ -n "$__ca_notempty" ]; then # on a donné une liste non vide, mais on se retrouve avec une liste vide return 1 fi return 0 } function get_error_msg() { local status="$1"; shift local reason [ -f "$WORAURL_DATA" ] && reason=". Le message d'erreur est: $(<"$WORAURL_DATA")" case "$status" in 0) :;; 1) echo "Une erreur s'est produite$reason";; 2) echo "Erreur de syntaxe$reason";; 3) echo "Impossible de contacter le serveur$reason";; *) echo "Impossible ${reason:-"de faire l'opération"}";; #' bug colorisation esac } function __do_wait() { if [[ "$1" == @* ]]; then local n="${1#@}" estepn "Attente de $n secondes..." sleep "$n" return 0 fi return 1 } function __ignore_wait() { if [[ "$1" == @* ]]; then estepw "$1: temps d'attente ignoré" return 0 fi return 1 } function start_apps() { # Démarrer les applications $3..$* en contactant le moniteur sur l'hôte $1 # avec le mot de passe éventuel $2 # Les variables globales enable_autorecover et force_enable_autorecover # permettent respectivement d'activer l'autoRecover après le démarrage de # l'application et de forcer l'activation de l'autoRecover même si # l'instance tournait déjà. # Un argument de la forme @N provoque une attente de N secondes. Ceci permet # de placer un temps d'attente entre le démarrage de certaines applications. [ -n "$*" ] || return 0 local app error turnArOn local host="$1" password="$2"; shift; shift etitle "Démarrage des applications" for app in "$@"; do __do_wait "$app" && continue ebegin "$app" error= turnArOn= if wom_running "$app" "$host" "$password"; then edotw 0 "Application déjà démarrée" elif wom_start "$app" "$host" "$password"; then turnArOn=1 edot 0 "Démarrage" else error=$? edot 1 "$(get_error_msg "$error" "de démarrer l'application")" fi [ -z "$error" -a -n "$force_enable_autorecover" ] && turnArOn=1 if [ -n "$turnArOn" -a -n "$enable_autorecover" ]; then if wom_turnAutoRecoverOn "$app" "$host" "$password"; then edot 0 "Activer autoRecover" else error=$? edot 1 "$(get_error_msg "$error" "d'activer autoRecover")" fi fi eend $error done eend return "${error:-0}" } function stop_apps() { # Arrêter les applications $3..$* en contactant le moniteur sur l'hôte $1 # avec le mot de passe éventuel $2 # Les variables globales disable_autorecover et force_disable_autorecover # permettent respectivement de désactiver l'autoRecover après l'arrêt de # l'application et de forcer la désactivation de l'autoRecover même si # l'instance ne tournait pas. # L'option {-a ARRAY} permet de remplir ARRAY avec la liste des applications # qui ont été effectivement arrêtées. Cette option si elle est spécifiée # doit être en premier # Pour compatibilité avec start_apps, les arguments de la forme @N sont # ignorés. Il n'y a pas de temps d'attente entre les applications lors de # l'arrêt. local -a __sa_stopped if [ "$1" == "-a" ]; then __sa_stopped="$2" shift; shift fi [ -n "$*" ] || return 0 local __sa_app __sa_error __sa_turnArOff local __sa_tried_stop_once __sa_could_not_stop local __sa_host="$1" __sa_password="$2"; shift; shift etitle "Arrêt des applications" for __sa_app in "$@"; do __ignore_wait "$__sa_app" && continue ebegin "$__sa_app" __sa_error= __sa_should_stop=1 __sa_turnArOff= if wom_stopped "$__sa_app" "$__sa_host" "$__sa_password"; then edotw 0 "Application déjà arrêtée" [ -n "$force_disable_autorecover" ] && __sa_turnArOff=1 __sa_should_stop= else __sa_turnArOff=1 fi if [ -n "$__sa_turnArOff" -a -n "$disable_autorecover" ]; then if wom_turnAutoRecoverOff "$__sa_app" "$__sa_host" "$__sa_password"; then edot 0 "Désactiver autoRecover" else __sa_error=$? edot 1 "$(get_error_msg "$__sa_error" "de désactiver autoRecover")" fi fi if [ -n "$__sa_should_stop" ]; then if wom_stop "$__sa_app" "$__sa_host" "$__sa_password"; then edot 0 "Arrêt" [ -n "$__sa_stopped" ] && array_addu "$__sa_stopped" "$__sa_app" else __sa_error=$? __sa_could_not_stop=1 edot 1 "$(get_error_msg "$__sa_error" "d'arrêter l'application")" fi __sa_tried_stop_once=1 fi eend $__sa_error done # ne faire d'attente que s'il y a eu au moins une tentative d'arrêt d'une # application [ -n "$__sa_tried_stop_once" ] || { eend return 0 } # Attendre un certain temps avant de continuer... On accord 500 ms par # instance, avec un minumum de 10 secondes local delay=$(($# / 2)) [ "$delay" -lt 10 ] && delay=10 ebegin "Attente de l'arrêt des instances" sleep $delay & ewait $! eend if [ -n "$__sa_could_not_stop" ]; then # Nous n'avons pas réussi à arrêter l'une des applications. Il faut # l'arrêter sauvagement __sa_could_not_stop= for __sa_app in "$@"; do if ! wom_stopped "$__sa_app" "$__sa_host" "$__sa_password"; then ebegin "Arrêt forcé de $__sa_app" if wom_stop "$__sa_app" "$__sa_host" "$__sa_password"; then edot 0 "Arrêt forcé" [ -n "$__sa_stopped" ] && array_addu "$__sa_stopped" "$__sa_app" else __sa_error=$? __sa_could_not_stop=1 edot 1 "$(get_error_msg "$__sa_error" "de forcer l'arrêt de l'application")" fi eend fi done # il faut attendre au plus 30 secondes pour l'arrêt forcé ebegin "Attente de l'arrêt forcé des instances" sleep 30 & ewait $! eend [ -n "$__sa_could_not_stop" ] && ewarn "Certaines instances n'ont pas pu être arrêtées" fi eend return "${__sa_error:-0}" } function bounce_apps() { # Redémarrer les applications $3..$* en mode bounce en contactant le # moniteur sur l'hôte $1 avec le mot de passe éventuel $2 # Pour compatibilité avec start_apps, les arguments de la forme @N sont # ignorés. Il n'y a pas de temps d'attente entre les applications lors du # redémarrage. [ -n "$*" ] || return 0 local app error local host="$1" password="$2"; shift; shift etitle "Redémarrage des applications en mode bounce" for app in "$@"; do __ignore_wait "$app" && continue ebegin "$app" error= if wom_bounce "$app" "$host" "$password"; then edot 0 "Redémarrage" else error=$? edot 1 "$(get_error_msg "$error" "de redémarrer l'application")" fi done eend return "${error:-0}" }