348 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			348 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/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 woinst
 | 
						|
 | 
						|
function display_help() {
 | 
						|
    uecho "$scriptname: Déploiement distant avec woinst
 | 
						|
 | 
						|
USAGE
 | 
						|
    $scriptname [-H host] [-T tmproot] <file|archive|dir>... [-- options de woinst]
 | 
						|
 | 
						|
note: à cause d'une limitation de makeself, les options de toinst ne devraient
 | 
						|
pas contenir d'espaces ni de caractères spéciaux. L'échappement de ces
 | 
						|
caractères n'est pas garanti.
 | 
						|
 | 
						|
OPTIONS
 | 
						|
    -T, --tmproot TMPROOT
 | 
						|
        Spécifier le répertoire temporaire sur l'hôte distant, comme par exemple
 | 
						|
        /var/tmp. Cette option est utile pour les vservers, qui ont par défaut
 | 
						|
        un /tmp minuscule de 16 Mo.
 | 
						|
    -S, --ssh SSH
 | 
						|
        Spécifier le programme à utiliser pour la connection par ssh.
 | 
						|
    -h, --host hosts
 | 
						|
    -h, --host @hostsfile
 | 
						|
        Spécifier un ou plusieurs hôtes sur lequels faire le déploiement. Pour
 | 
						|
        spécifier plusieurs hôtes, il est possible d'utiliser plusieurs fois
 | 
						|
        l'option -h, ou spécifier en une seule fois plusieurs hôtes en les
 | 
						|
        séparant par un espace ou le caractère ':', e.g. 'host1 host2' ou
 | 
						|
        'host1:host2'. Si la spécification contient les caractères { et },
 | 
						|
        l'expansion est effectuée, e.g
 | 
						|
            -h 'root@{host1,host2}.univ.run'
 | 
						|
        Par défaut, la connexion sur l'hôte distant se fait avec l'utilisateur
 | 
						|
        root. Il est possible de spécifier un autre utilisateur avec la syntaxe
 | 
						|
        user@host, e.g -h user@host
 | 
						|
        La forme @hostsfile permet de lire la liste des hôtes depuis le fichier
 | 
						|
        hostsfile, à raison d'un hôte par ligne.
 | 
						|
    -w, -W, --whost host[:htdocs]
 | 
						|
        Comme --host, mais pour le déploiement des resources web. Contrairement
 | 
						|
        à --host, un seul hôte peut être spécifié par occurence de l'option,
 | 
						|
        pour permettre de spécifier éventuellement le répertoire vers lequel
 | 
						|
        copier les resources web. Ainsi, les deux commandes suivantes sont
 | 
						|
        équivalentes:
 | 
						|
            rwoinst -h host.tld -- -W HTDOCSDIR=HTDOCSBASE/wo
 | 
						|
            rwoinst -w host.tld:HTDOCSBASE/wo
 | 
						|
        Il est possible de spécifier en une seule invocation --host et --whost
 | 
						|
        pour déployer l'application sur un hôte et les resources web sur un
 | 
						|
        autre.
 | 
						|
    --deploy
 | 
						|
    --no-deploy
 | 
						|
        Autoriser (respectivement interdire) l'utilisation de la configuration
 | 
						|
        locale de déploiement pour identifier la destination si aucun hôte n'est
 | 
						|
        spécifié.
 | 
						|
        Par défaut, si aucun hôte n'est spécifié, la configuration locale de
 | 
						|
        déploiement est interrogée pour avoir cette information.
 | 
						|
    -c, --deploy-config CONFNAME
 | 
						|
        Cette option permet de spécifier le nom de la configuration à utiliser
 | 
						|
        pour effectuer la requête. Par défaut, utiliser le nom 'rwoinst'
 | 
						|
    -p, --deploy-profile PROFILE
 | 
						|
        Spécifier le profil à utiliser pour l'interrogation de la configuration
 | 
						|
        locale de déploiement. Par défaut, aucun profil n'est sélectionné."
 | 
						|
}
 | 
						|
 | 
						|
__PARSED_HOSTS=()
 | 
						|
__PARSED_FILES=()
 | 
						|
function parse_hostsfile() {
 | 
						|
    # Lire chacun des fichiers $* et initialiser __PARSED_HOSTS avec la liste
 | 
						|
    # des hôtes mentionnés dans les fichiers.
 | 
						|
    local inputfile basedir inputs input
 | 
						|
    for inputfile in "$@"; do
 | 
						|
        inputfile="$(abspath "$inputfile")"
 | 
						|
        array_contains __PARSED_FILES "$inputfile" && {
 | 
						|
            ewarn "$(ppath "$inputfile"): inclusion récursive"
 | 
						|
            continue
 | 
						|
        }
 | 
						|
        array_add __PARSED_FILES "$inputfile"
 | 
						|
        basedir="$(dirname "$inputfile")"
 | 
						|
 | 
						|
        array_from_lines inputs "$(<"$inputfile" filter_conf)" || {
 | 
						|
            ewarn "$inputfile: fichier ingnoré"
 | 
						|
            continue
 | 
						|
        }
 | 
						|
        for input in "${inputs[@]}"; do
 | 
						|
            if [ "${input#@}" != "$input" ]; then
 | 
						|
                # fichier inclus
 | 
						|
                parse_hostsfile "$(abspath "${input#@}" "$basedir")"
 | 
						|
            else
 | 
						|
                array_addu __PARSED_HOSTS "$input"
 | 
						|
            fi
 | 
						|
        done
 | 
						|
    done
 | 
						|
}
 | 
						|
function __expand_braces() {
 | 
						|
    if [[ "$1" == *{* ]] && [[ "$1" == *}* ]]; then
 | 
						|
        eval "echo $1"
 | 
						|
    else
 | 
						|
        echo "$1"
 | 
						|
    fi
 | 
						|
}
 | 
						|
function __dot_is_localhost() { [ "$1" == "." ] && echo "localhost" || echo "$1"; }
 | 
						|
function fix_hosts() {
 | 
						|
    # Si hosts contient des éléments multiple, comme a:b, séparer ces
 | 
						|
    # éléments. i.e (a b:c) --> (a b c)
 | 
						|
    # Supporter la syntaxe @hostsfile qui permet de charger la liste des hôtes
 | 
						|
    # depuis un fichier.
 | 
						|
    # Remplacer aussi les '.' par 'localhost'
 | 
						|
    array_map hosts __expand_braces
 | 
						|
    array_fix_paths hosts ":"
 | 
						|
    array_fix_paths hosts " "
 | 
						|
 | 
						|
    local -a _hosts _tmphosts host
 | 
						|
    for host in "${hosts[@]}"; do
 | 
						|
        host="${host%/}"
 | 
						|
        if [ "${host#@}" != "$host" ]; then
 | 
						|
            __PARSED_HOSTS=()
 | 
						|
            parse_hostsfile "${host#@}"
 | 
						|
            array_fix_paths __PARSED_HOSTS
 | 
						|
            array_extendu _hosts __PARSED_HOSTS
 | 
						|
        else
 | 
						|
            array_addu _hosts "$host"
 | 
						|
        fi
 | 
						|
    done
 | 
						|
    array_copy hosts _hosts
 | 
						|
    array_map hosts __dot_is_localhost
 | 
						|
}
 | 
						|
 | 
						|
function deploy_to() {
 | 
						|
    local archive="$1" host="$2" tmproot="$3"
 | 
						|
    shift; shift; shift
 | 
						|
 | 
						|
    local r=
 | 
						|
    if [ "$host" == "localhost" ]; then
 | 
						|
        etitle "Sur l'hôte local"
 | 
						|
        "$archive" ${tmproot:+--tmproot "$tmproot"} -- "$@" || r=1
 | 
						|
        eend
 | 
						|
    else
 | 
						|
        local user
 | 
						|
        local archivename="$(basename "$archive")"
 | 
						|
 | 
						|
        splituserhost "$host" user host
 | 
						|
        [ -n "$user" ] || user=root
 | 
						|
 | 
						|
        # sur l'hôte distant, ne rendre non interactif qu'à partir de -yy
 | 
						|
        rinteraction=$__interaction
 | 
						|
        [ $rinteraction -lt 2 ] && rinteraction=$(($rinteraction + 1))
 | 
						|
 | 
						|
        etitle "Vers $user@$host"
 | 
						|
 | 
						|
        estep "Copie de l'archive"
 | 
						|
        scp -S "$SSH" "$archive" "$user@$host:" || r=1
 | 
						|
 | 
						|
        if [ -z "$r" ]; then
 | 
						|
            estep "Lancement du script de déploiement"
 | 
						|
            "$SSH" -qt "$user@$host" "\
 | 
						|
__interaction=$rinteraction
 | 
						|
__estack=$(qval "$__estack")
 | 
						|
__tlevel=$(qval "$__tlevel")
 | 
						|
export __interaction __estack __tlevel
 | 
						|
${UTOOLS_LANG:+UTOOLS_LANG='$UTOOLS_LANG'; export UTOOLS_LANG
 | 
						|
}$(qvals "./$archivename" ${tmproot:+--tmproot "$tmproot"} -- MYHOST="$host" "$@")" || r=1
 | 
						|
        fi
 | 
						|
 | 
						|
        eend
 | 
						|
    fi
 | 
						|
    return ${r:-0}
 | 
						|
}
 | 
						|
 | 
						|
action=deploy
 | 
						|
tmproot=
 | 
						|
SSH=
 | 
						|
hosts=()
 | 
						|
whosts=()
 | 
						|
deploy_enable=1
 | 
						|
deploy_confname=rwoinst
 | 
						|
deploy_profile=
 | 
						|
parse_opts "${PRETTYOPTS[@]}" \
 | 
						|
    --help '$exit_with display_help' \
 | 
						|
    -T:,--tmproot: tmproot= \
 | 
						|
    -S:,--ssh: SSH= \
 | 
						|
    -h:,-H:,--host: hosts \
 | 
						|
    -w:,-W:,--whost: whosts \
 | 
						|
    --deploy deploy_enable=1 \
 | 
						|
    --no-deploy deploy_enable= \
 | 
						|
    -c:,--deploy-config deploy_confname= \
 | 
						|
    -p:,--deploy-profile: deploy_profile= \
 | 
						|
    @ args -- "$@" && set -- "${args[@]}" || die "$args"
 | 
						|
 | 
						|
: "${SSH:=ssh}"
 | 
						|
 | 
						|
## Bundle à déployer et hôtes sur lesquels faire le déploiement
 | 
						|
confirm_bundle=
 | 
						|
if [ $# -eq 0 ] || [[ "$1" == -* ]] || [[ "$1" == *=* ]]; then
 | 
						|
    # pas d'argument, ou c'est une option (qui fait donc partie des arguments de woinst)
 | 
						|
    case "$(basename -- "$(pwd)")" in
 | 
						|
    *.woa|*.framework) bundle=.;;
 | 
						|
    *) bundle=;;
 | 
						|
    esac
 | 
						|
    confirm_bundle=1
 | 
						|
else
 | 
						|
    bundle="$1"
 | 
						|
fi
 | 
						|
 | 
						|
woinst_options=()
 | 
						|
if array_isempty hosts && [ -n "$deploy_enable" -a -n "$bundle" ]; then
 | 
						|
    urequire deploy
 | 
						|
    deploy_setconf "$deploy_confname"
 | 
						|
    if deploy_loadconf; then
 | 
						|
        setxx bundlename=abspath "$bundle" // basename --
 | 
						|
        host=(); bounce=; notag=; exec=; dbconfig=; dbconfigmap=
 | 
						|
        if eval "$(deploy_query -v host,bounce,notag,exec,dbconfig,dbconfigmap DEST wobundle rwoinst_bundle "$deploy_profile" shell "$bundlename")"; then
 | 
						|
            array_copy deploy_hosts host
 | 
						|
            deploy_options=()
 | 
						|
            [ -n "$bounce" ] && array_add deploy_options -b
 | 
						|
            [ -n "$notag" ] && array_add deploy_options -n
 | 
						|
            if [ -n "$exec" ]; then
 | 
						|
                for x in "${exec[@]}"; do
 | 
						|
                    array_add deploy_options -x "$x"
 | 
						|
                done
 | 
						|
            fi
 | 
						|
            [ -n "$dbconfig" ] && array_add deploy_options -d "$dbconfig"
 | 
						|
            if [ -n "$dbconfigmap" ]; then
 | 
						|
                for m in "${dbconfigmap[@]}"; do
 | 
						|
                    array_add deploy_options -m "$m"
 | 
						|
                done
 | 
						|
            fi
 | 
						|
            deploy_whosts=()
 | 
						|
            host=(); destdir=
 | 
						|
            if eval "$(deploy_query -v host,destdir DEST wobundle rwoinst_webres "$deploy_profile" shell "$bundlename")"; then
 | 
						|
                for wh in "${host[@]}"; do
 | 
						|
                    array_add deploy_whosts "$wh:$destdir"
 | 
						|
                done
 | 
						|
            fi
 | 
						|
            msg="$bundlename: ce bundle sera déployé vers les hôtes suivants:
 | 
						|
$(array_to_lines deploy_hosts "" "    ")"
 | 
						|
            if [ ${#deploy_whosts[*]} -gt 0 -o ${#deploy_options[*]} -gt 0 ]; then
 | 
						|
                msg="$msg
 | 
						|
avec le(s) paramètre(s) suivant(s):"
 | 
						|
                [ ${#deploy_whosts[*]} -gt 0 ] && msg="$msg
 | 
						|
$(array_to_lines deploy_whosts "" "    --whost ")"
 | 
						|
                [ ${#deploy_options[*]} -gt 0 ] && msg="$msg
 | 
						|
    $(qvals "${deploy_options[@]}")"
 | 
						|
            fi
 | 
						|
            check_interaction -c && einfo "$msg"
 | 
						|
            ask_any "Voulez-vous continuer?" Oq || die
 | 
						|
            array_extend hosts deploy_hosts
 | 
						|
            array_extend woinst_options deploy_options
 | 
						|
            array_extend whosts deploy_whosts
 | 
						|
            if [ -n "$confirm_bundle" ]; then
 | 
						|
                confirm_bundle=
 | 
						|
                set -- "$bundle" "$@"
 | 
						|
            fi
 | 
						|
        fi
 | 
						|
    fi
 | 
						|
fi
 | 
						|
 | 
						|
if [ -n "$confirm_bundle" ]; then
 | 
						|
    # pas d'argument, ou c'est une option (qui fait donc partie des arguments de woinst)
 | 
						|
    read_value "Veuillez entrer la bundle à déployer" bundle "$bundle" O
 | 
						|
    set -- "$bundle" "$@"
 | 
						|
fi
 | 
						|
 | 
						|
array_isempty hosts && read_value "Entrez une liste d'hôtes séparés par ':'" hosts "localhost"
 | 
						|
fix_hosts
 | 
						|
 | 
						|
## Création de l'archive
 | 
						|
 | 
						|
etitle "Création du répertoire de travail"
 | 
						|
ac_set_tmpdir workdir
 | 
						|
 | 
						|
bundles=()
 | 
						|
while [ -n "$1" ]; do
 | 
						|
    if [ "$1" == "--" ]; then
 | 
						|
        # début des options de woinst
 | 
						|
        shift
 | 
						|
        break
 | 
						|
    elif [[ "$1" == -* ]] || [[ "$1" == *=* ]]; then
 | 
						|
        # début des options de woinst
 | 
						|
        break
 | 
						|
    fi
 | 
						|
 | 
						|
    src="$1"; shift
 | 
						|
    if [ -f "$src" ] && is_archive "$src"; then
 | 
						|
        estep "$(ppath "$src")"
 | 
						|
        cp_R "$src" "$workdir" || die
 | 
						|
    elif [ -d "$src" ]; then
 | 
						|
        src="$(abspath "$src")"
 | 
						|
        setx srcname=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/$srcname.woa" ]; then
 | 
						|
                src="$src/target/$srcname.woa"
 | 
						|
            elif [ -d "$src/target/$srcname.framework" ]; then
 | 
						|
                src="$src/target/$srcname.framework"
 | 
						|
            fi
 | 
						|
            ;;
 | 
						|
        esac
 | 
						|
        if endswith "$src" .framework; then
 | 
						|
            is_wofwkdir "$src" || die "Framework invalide: $(ppath "$src")"
 | 
						|
        elif endswith "$src" .woa; then
 | 
						|
            is_woappdir "$src" || die "Application invalide: $(ppath "$src")"
 | 
						|
        else
 | 
						|
            die "N'est pas un bundle valide: $(ppath "$src")"
 | 
						|
        fi
 | 
						|
        estep "$(ppath2 "$src")"
 | 
						|
        cp_R "$src" "$workdir" || die
 | 
						|
    else
 | 
						|
        die "Fichier ou répertoire introuvable: $src"
 | 
						|
    fi
 | 
						|
 | 
						|
    src="$(abspath "$src")"
 | 
						|
    array_add bundles "$(basename "$src")"
 | 
						|
done
 | 
						|
 | 
						|
estep "Copie de l'environnement de déploiement"
 | 
						|
mkdir "$workdir/lib"
 | 
						|
ulibsync "$workdir/lib"
 | 
						|
cp "$scriptdir/woinst.sh" "$workdir"
 | 
						|
chmod +x "$workdir/woinst.sh"
 | 
						|
 | 
						|
eend
 | 
						|
 | 
						|
etitle "Création de l'archive pour le déploiement"
 | 
						|
ac_set_tmpfile archive
 | 
						|
 | 
						|
"$scriptdir/mkusfx" --bare --tmp-archive -o "$archive" "$workdir" -- ./woinst.sh --is-tmpdir "${bundles[@]}" || die
 | 
						|
 | 
						|
eend
 | 
						|
 | 
						|
## Déploiement
 | 
						|
 | 
						|
etitle "Déploiement des bundles"
 | 
						|
for host in "${hosts[@]}"; do
 | 
						|
    deploy_to "$archive" "$host" "$tmproot" "$@" "${woinst_options[@]}" || die
 | 
						|
done
 | 
						|
eend
 | 
						|
 | 
						|
if [ ${#whosts[*]} -gt 0 ]; then
 | 
						|
    etitle "Déploiement des resources web"
 | 
						|
    for hostdestdir in "${whosts[@]}"; do
 | 
						|
        splitpair "$hostdestdir" host destdir
 | 
						|
        deploy_to "$archive" "$host" "$tmproot" \
 | 
						|
                  -y -W ${destdir:+HTDOCSDIR="$destdir"} "$@" "${woinst_options[@]}" || die
 | 
						|
    done
 | 
						|
    eend
 | 
						|
fi
 |