1938 lines
		
	
	
		
			73 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			1938 lines
		
	
	
		
			73 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| ##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| ## Fonctions pour la commande runs
 | |
| ##@cooked nocomments
 | |
| ##@require base
 | |
| uprovide runs
 | |
| urequire base
 | |
| 
 | |
| ################################################################################
 | |
| # Configuration
 | |
| 
 | |
| function __runs_initt() {
 | |
|     if is_yes "$verbose"; then
 | |
|         rscriptt="# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| desc \"CHANGEME: Description du script $rscriptname\"
 | |
| #var name=value arr+=value arr-=value
 | |
| #var arr value0 value1...
 | |
| 
 | |
| script:
 | |
| 
 | |
| # pour un script d'installation qui ne doit tourner qu'une seule fois:
 | |
| #shouldrun || exit
 | |
| #...
 | |
| #setdone"
 | |
|         runsconft="# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| # Ce fichier contient les paramètres qui sont partagés par tous les scripts de $host
 | |
| #var name=value arr+=value arr-=value
 | |
| #var arr value0 value1..."
 | |
|     else
 | |
|         rscriptt="# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| desc \"\"
 | |
| 
 | |
| script:"
 | |
|         runsconft="# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| # Ce fichier contient les paramètres qui sont partagés par tous les scripts de $host"
 | |
|     fi
 | |
|     sysinfost="# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| # Ce fichier contient les informations sur le type de système installé sur $host
 | |
| # Il est possible de recopier la valeur affichée par la commande usysinfos"
 | |
|     if [ -n "$sysinfos_data" ]; then
 | |
|         sysinfost="$sysinfost
 | |
| $sysinfos_data"
 | |
|     else
 | |
|         sysinfost="$sysinfost
 | |
| #sysname=()
 | |
| #sysdist=()
 | |
| #sysver=()
 | |
| #bits="
 | |
|     fi
 | |
|     defaultt="# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| # Ce fichier contient la liste des script à lancer avec le compte root pour
 | |
| # configurer $host
 | |
| # Chaque ligne contient le nom du script suivi des arguments éventuels
 | |
| #initenv
 | |
| #dump-users
 | |
| #base
 | |
| #@services
 | |
| #@config"
 | |
|     configt="# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| # Ce fichier contient la recette pour configurer le serveur: configuration des
 | |
| # mappings, configuration du serveur de courrier, de la sauvegarde, etc... Il
 | |
| # faut relancer cette recette à chaque fois que la configuration change.
 | |
| #mailrelay rootmail=
 | |
| #hostmappings mappings
 | |
| #backupclient bckhost="
 | |
|     servicest="# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| # Ce fichier contient la recette pour installer les services du serveur. Cette
 | |
| # installation ne se fait en principe qu'une seule fois."
 | |
|     userdefaultt="# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| # Ce fichier contient la liste des script à lancer avec le compte utilisateur
 | |
| # pour configurer $host
 | |
| # Chaque ligne contient le nom du script suivi des arguments éventuels"
 | |
| }
 | |
| 
 | |
| function runs_initdir() {
 | |
|     # Initialiser le répertoire d'hôte. $1 est un nom d'hôte pleinement
 | |
|     # qualifié, et les fichiers sont créés dans le premier répertoire de
 | |
|     # RUNSHOSTSDIRS qui convient: si un fichier .udir existe avec un tableau
 | |
|     # runs_domains qui contient le domaine de l'hôte spécifié, alors c'est ce
 | |
|     # répertoire qui est sélectionné. Sinon, on prend le premier répertoire de
 | |
|     # RUNSHOSTSDIRS.
 | |
|     # $2 spécifie si le fichier doit être créé avec de l'aide (yes) ou avec le
 | |
|     # script minimum (no)
 | |
|     # $3 est le contenu à placer dans le fichier sysinfos.conf, s'il n'a pas
 | |
|     # déjà été provisionné.
 | |
|     # Il faut lancer __runs_setpath avant d'utiliser cette fonction et
 | |
|     # RUNSHOSTDIRS ne doit pas être vide
 | |
|     [ -n "${RUNSHOSTSDIRS[*]}" ] || return 1
 | |
| 
 | |
|     local runshostdir
 | |
|     local edit_default
 | |
|     local host hostname domain
 | |
|     splithost "$1" hostname domain
 | |
|     local verbose="${2:-yes}"
 | |
|     local sysinfos_data="$3"
 | |
|     if [ -n "$domain" ]; then
 | |
|         host="$hostname.$domain"
 | |
| 
 | |
|         local dir found
 | |
|         # d'abord chercher si le répertoire existe déjà
 | |
|         for runshostdir in "${RUNSHOSTSDIRS[@]}"; do
 | |
|             found=
 | |
|             for dir in "$runshostdir/$domain/$hostname" "$runshostdir/$host"; do
 | |
|                 if [ -d "$dir" ]; then
 | |
|                     found=1
 | |
|                     break
 | |
|                 fi
 | |
|             done
 | |
|         done
 | |
|         # sinon chercher un répertoire qui convient
 | |
|         if [ -z "$found" ]; then
 | |
|             for runshostdir in "${RUNSHOSTSDIRS[@]}"; do
 | |
|                 if [ -f "$runshostdir/.udir" ]; then
 | |
|                     (source "$runshostdir/.udir"; array_contains runs_domains "$domain") && {
 | |
|                         found=1
 | |
|                         break
 | |
|                     }
 | |
|                 fi
 | |
|             done
 | |
|         fi
 | |
|         if [ -n "$found" ]; then
 | |
|             found=
 | |
|             for dir in "$runshostdir/$host" "$runshostdir/$domain/$hostname"; do
 | |
|                 if [ -d "$dir" ]; then
 | |
|                     runshostdir="$dir"
 | |
|                     found=1
 | |
|                     break
 | |
|                 fi
 | |
|             done
 | |
|             [ -n "$found" ] || runshostdir="$runshostdir/$host"
 | |
|         else
 | |
|             runshostdir="${RUNSHOSTSDIRS[0]}/$host"
 | |
|         fi
 | |
|     else
 | |
|         host="$hostname"
 | |
|         runshostdir="${RUNSHOSTSDIRS[0]}/$host"
 | |
|     fi
 | |
| 
 | |
|     local rscriptt runsconft sysinfost defaultt configt servicest
 | |
|     __runs_initt
 | |
| 
 | |
|     mkdir -p "$runshostdir"
 | |
|     if [ ! -f "$runshostdir/runs.conf" ]; then
 | |
|         estep "Création de $(ppath "$runshostdir/runs.conf")"
 | |
|         echo "$runsconft" >"$runshostdir/runs.conf"
 | |
|     fi
 | |
|     local create_sysinfos
 | |
|     if [ -f "$runshostdir/sysinfos.conf" ]; then
 | |
|         # si le fichier sysinfos.conf ne contient que des commentaires,
 | |
|         # considérer qu'il n'existe pas.
 | |
|         local -a sysinfoslines
 | |
|         array_from_lines sysinfoslines "$(<"$runshostdir/sysinfos.conf" filter_conf)"
 | |
|         [ "${#sysinfoslines[*]}" -eq 0 ] && create_sysinfos=1
 | |
|     else
 | |
|         create_sysinfos=1
 | |
|     fi
 | |
|     if [ -n "$create_sysinfos" ]; then
 | |
|         estep "Création de $(ppath "$runshostdir/sysinfos.conf")"
 | |
|         echo "$sysinfost" >"$runshostdir/sysinfos.conf"
 | |
|     fi
 | |
|     if [ ! -f "$runshostdir/default" ]; then
 | |
|         estep "Création de $(ppath "$runshostdir/default")"
 | |
|         echo "$defaultt" >"$runshostdir/default"
 | |
|         edit_default=1
 | |
|     fi
 | |
|     if [ ! -f "$runshostdir/config" ]; then
 | |
|         estep "Création de $(ppath "$runshostdir/config")"
 | |
|         echo "$configt" >"$runshostdir/config"
 | |
|     fi
 | |
|     if [ ! -f "$runshostdir/services" ]; then
 | |
|         estep "Création de $(ppath "$runshostdir/services")"
 | |
|         echo "$servicest" >"$runshostdir/services"
 | |
|     fi
 | |
|     if [ ! -f "$runshostdir/userdefault" ]; then
 | |
|         estep "Création de $(ppath "$runshostdir/userdefault")"
 | |
|         echo "$userdefaultt" >"$runshostdir/userdefault"
 | |
|     fi
 | |
|     
 | |
|     [ -n "$edit_default" ] && "${EDITOR:-vi}" "$runshostdir/default"
 | |
| 
 | |
|     return 0
 | |
| }
 | |
| 
 | |
| function __runs_create_rscript() {
 | |
|     local rscript="$1"
 | |
|     local rscriptname="$(basename "$rscript")"
 | |
|     local overwrite="$2"
 | |
|     local template
 | |
|     if [ "$rscriptname" == "runs.conf" ]; then
 | |
|         template="$runsconft"
 | |
|     elif [ "$rscriptname" == "sysinfos.conf" ]; then
 | |
|         template="$sysinfost"
 | |
|     elif [ "$rscriptname" == "default" ]; then
 | |
|         template="$defaultt"
 | |
|     elif [ "$rscriptname" == "userdefault" ]; then
 | |
|         template="$userdefaultt"
 | |
|     else
 | |
|         withext "$rscript" || rscript="$rscript.rs"
 | |
|         template="$rscriptt"
 | |
|     fi
 | |
| 
 | |
|     if [ -f "$rscript" ] && is_no "$overwrite"; then
 | |
|         eerror "$(ppath "$rscript"): fichier déjà existant"
 | |
|         return 1
 | |
|     fi
 | |
| 
 | |
|     mkdirof "$rscript"
 | |
|     estep "Création de $(ppath "$rscript")"
 | |
|     echo "$template" >"$rscript"
 | |
| 
 | |
|     array_add new_rscripts "$(abspath "$rscript")"
 | |
| 
 | |
|     return 0
 | |
| }
 | |
| 
 | |
| function runs_create_rscript() {
 | |
|     # Créer un modèle de script. Si $2 est spécifié, c'est un nom d'hôte
 | |
|     # pleinement qualifié. Le répertoire d'hôte correspondant *doit* exister.
 | |
|     # $3 spécifie si le fichier doit être créé avec de l'aide (yes) ou avec le
 | |
|     # script minimum (no)
 | |
|     # Si $2!="", il faut lancer __runs_setpath avant d'utiliser cette fonction
 | |
|     # et RUNSHOSTDIRS ne doit pas être vide
 | |
|     # Le chemin du nouveau script est ajouté au tableau new_rscripts
 | |
|     local rscript="$1"
 | |
|     local host="$2"
 | |
|     local verbose="${3:-yes}"
 | |
|     local overwrite="${4:-no}"
 | |
| 
 | |
|     local rscriptt runsconft sysinfost defaultt userdefaultt
 | |
|     __runs_initt
 | |
| 
 | |
|     if [ -n "$host" ]; then
 | |
|         if withpath "$rscript"; then
 | |
|             # si c'est un chemin relatif à '.', '..', ou un chemin absolu, le
 | |
|             # prendre tel quel
 | |
|             __runs_create_rscript "$rscript" "$overwrite" || return 1
 | |
|         else
 | |
|             # trouver le répertoire d'hôte
 | |
|             [ -n "${RUNSHOSTSDIRS[*]}" ] || return 1
 | |
| 
 | |
|             local found runsdir hostname domain
 | |
|             splithost "$host" hostname domain
 | |
|             for runsdir in "${RUNSHOSTSDIRS[@]}"; do
 | |
|                 found=
 | |
|                 for dir in "$runsdir/$host" "$runsdir/$domain/$hostname"; do
 | |
|                     if [ -d "$dir" ]; then
 | |
|                         runsdir="$dir"
 | |
|                         found=1
 | |
|                         break
 | |
|                     fi
 | |
|                 done
 | |
|                 [ -n "$found" ] && break
 | |
|             done
 | |
|             [ -n "$found" ] || return 1
 | |
| 
 | |
|             # puis exprimer le chemin spécifié par rapport à runsdir
 | |
|             __runs_create_rscript "$runsdir/$rscript" "$overwrite" || return 1
 | |
|         fi
 | |
| 
 | |
|     else
 | |
|         __runs_create_rscript "$rscript" "$overwrite" || return 1
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function runs_unsupported_system() {
 | |
|     # Afficher un message d'erreur indiquant que le système actuel n'est pas
 | |
|     # supporté, et quitter le script
 | |
|     local msg="Ce script n'est pas supporté sur $MYSYSNAME${MYSYSDIST:+/$MYSYSDIST}${MYSYSVER:+/$MYSYSVER}"
 | |
|     [ -n "$*" ] && msg="$msg
 | |
| Il faut au moins l'un des systèmes suivants: $*"
 | |
|     die "$msg"
 | |
| }
 | |
| 
 | |
| function runs_require_sysinfos() {
 | |
|     # Vérifier le système actuel avec check_sysinfos(), et afficher un message
 | |
|     # d'erreur avec runs_unsupported_system() s'il ne correspond pas à la
 | |
|     # requête
 | |
|     check_sysinfos "$@" && return 0
 | |
|     local infos info
 | |
|     # Construire une description du type de système attendu en fonction des
 | |
|     # arguments. Actuellement, on se contente de copier la ligne de commande, en
 | |
|     # sautant les options.
 | |
|     # XXX améliorer l'algorithme pour décrire précisément le système attendu
 | |
|     for info in "$@"; do
 | |
|         if ! [[ "$info" == -* ]]; then
 | |
|             infos=("${infos[@]}" "$info")
 | |
|         fi
 | |
|     done
 | |
|     runs_unsupported_system "${infos[@]}"
 | |
| }
 | |
| 
 | |
| ################################################################################
 | |
| # Lancement de scripts nommés
 | |
| 
 | |
| function __runs_setpath() {
 | |
|     # Initialiser les tableaux $1(=RUNSSCRIPTSDIRS), $2(=RUNSMODULESDIRS),
 | |
|     # $3(=RUNSHOSTSDIRS) avec les chemins de RUNSSCRIPTSPATH, RUNSMODULESPATH,
 | |
|     # RUNSHOSTSPATH
 | |
|     function __runs_addsuffix() { echo "$1${2:+/$2}"; }
 | |
|     local -a __runsdirs __tmpa
 | |
|     local __runsscriptsdirs="${1:-RUNSSCRIPTSDIRS}"
 | |
|     local __runsmodulesdirs="${2:-RUNSMODULESDIRS}"
 | |
|     local __runshostsdirs="${3:-RUNSHOSTSDIRS}"
 | |
| 
 | |
|     array_from_path "$__runsscriptsdirs" "$RUNSSCRIPTSPATH"
 | |
|     array_map "$__runsscriptsdirs" abspath
 | |
| 
 | |
|     array_from_path "$__runsmodulesdirs" "$RUNSMODULESPATH"
 | |
|     array_map "$__runsmodulesdirs" abspath
 | |
| 
 | |
|     array_from_path "$__runshostsdirs" "$RUNSHOSTSPATH"
 | |
|     array_map "$__runshostsdirs" abspath
 | |
| }
 | |
| 
 | |
| function __runs_find_host() {
 | |
|     # Si $1 est un nom d'hôte pleinement qualifié, retourner cette valeur
 | |
|     # Sinon, chercher en utilisant RUNSDOMAINS un nom d'hôte qui aurait déjà été
 | |
|     # configuré
 | |
|     local host="$1" hostname domain
 | |
|     splithost "$host" hostname domain
 | |
|     if [ -n "$domain" ]; then
 | |
|         echo "$host"
 | |
|         return 0
 | |
|     fi
 | |
| 
 | |
|     local runsdomain runsdir
 | |
|     for runsdomain in "${RUNSDOMAINS[@]}"; do
 | |
|         for runsdir in "${RUNSHOSTSDIRS[@]}"; do
 | |
|             if [ -d "$runsdir/$hostname.$runsdomain" ]; then
 | |
|                 echo "$hostname.$runsdomain"
 | |
|                 return 0
 | |
|             elif [ -d "$runsdir/$runsdomain/$hostname" ]; then
 | |
|                 echo "$hostname.$runsdomain"
 | |
|                 return 0
 | |
|             fi
 | |
|         done
 | |
|     done
 | |
|     echo "$host"
 | |
|     return 1
 | |
| }
 | |
| function runs_find_host() {
 | |
|     local RUNSSCRIPTSDIRS RUNSMODULESDIRS RUNSHOSTSDIRS; __runs_setpath
 | |
|     __runs_find_host "$@"
 | |
| }
 | |
| 
 | |
| function runs_add_domain() {
 | |
|     # Si $1 est nom d'hôte pleinement qualifié, retourner cette valeur
 | |
|     # Sinon, lui rajouter le domaine RUNSDOMAIN
 | |
|     local host="$1" hostname domain
 | |
|     splithost "$host" hostname domain
 | |
|     if [ -n "$domain" -o -z "$RUNSDOMAIN" ]; then
 | |
|         echo "$host"
 | |
|         return 0
 | |
|     fi
 | |
|     echo "$host.$RUNSDOMAIN"
 | |
|     return 1
 | |
| }
 | |
| 
 | |
| function runs_find_hostfile() {
 | |
|     # Trouver et afficher le fichier d'hôte $1 dans les répertoires du tableau
 | |
|     # $3(=RUNSHOSTSDIRS), pour l'hôte $2(=$RUNSHOST). Retourner 0 en cas de
 | |
|     # succès, 1 en cas d'échec.
 | |
|     # Si host=$2 est une valeur non vide, la recherche est effectuée dans
 | |
|     # {$RUNSHOSTSDIRS}/$host et {$RUNSHOSTSDIRS}/$domain/$hostname. Sinon,
 | |
|     # retourner 1, car il faut spécifier un nom d'hôte.
 | |
|     local __hostfile="$1" __runshost="${2:-$RUNSHOST}" __runshostsdirs="${3:-RUNSHOSTSDIRS}[@]"
 | |
|     local __hostname __domain
 | |
|     local __runsdir __runsfile
 | |
| 
 | |
|     [ -n "$__runshost" ] || return 1
 | |
|     splithost "$__runshost" __hostname __domain
 | |
|     for __runsdir in "${!__runshostsdirs}"; do
 | |
|         for __runsfile in \
 | |
|             "$__runsdir/$__runshost/$__hostfile" \
 | |
|             "$__runsdir/$__domain/$__hostname/$__hostfile"; do
 | |
|             if [ -e "$__runsfile" ]; then
 | |
|                 echo "$__runsfile"
 | |
|                 return 0
 | |
|             fi
 | |
|         done
 | |
|     done
 | |
|     return 1
 | |
| }
 | |
| 
 | |
| function runs_find_datafile() {
 | |
|     # Trouver et afficher le fichier de données $1 dans le répertoire $3 s'il
 | |
|     # est non vide puis dans les répertoires des tableaux $4(=RUNSSCRIPTSDIRS),
 | |
|     # $5(=RUNSMODULESDIRS) et $6(=RUNSHOSTSDIRS), pour l'hôte
 | |
|     # $2(=$RUNSHOST). Retourner 0 en cas de succès, 1 en cas d'échec.
 | |
|     # - D'abord, si $1 *n'est pas* de la forme "./path" ou "../path", chercher
 | |
|     # dans $3.
 | |
|     # - Puis si l'hôte est spécifié, chercher dans {$RUNSHOSTSDIRS}/$host et
 | |
|     # {$RUNSHOSTSDIRS}/$domain/$hostname.
 | |
|     # - Puis chercher dans {$RUNSSCRIPTSDIRS} puis {$RUNSMODULESDIRS}.
 | |
|     # - Puis, si $1 est de la forme "./path" ou "../path", chercher dans $3.
 | |
|     # - Sinon, retourner 1
 | |
|     local __datafile="$1" __runshost="${2:-$RUNSHOST}"
 | |
|     local __runsscriptdir="$3"
 | |
|     local __runsscriptsdirs="${4:-RUNSSCRIPTSDIRS}[@]"
 | |
|     local __runsmodulesdirs="${5:-RUNSMODULESDIRS}[@]"
 | |
|     local __runshostsdirs="${6:-RUNSHOSTSDIRS}[@]"
 | |
|     local __domain __hostname
 | |
|     local __runsdir __runsfile
 | |
|     local __withpath
 | |
| 
 | |
|     withpath "$__datafile" && __withpath=1
 | |
| 
 | |
|     # D'abord chercher dans le répertoire du script
 | |
|     if [ -n "$__withpath" -a -n "$__runsscriptdir" ]; then
 | |
|         __runsfile="$__runsscriptdir/$__datafile"
 | |
|         if [ -e "$__runsfile" ]; then
 | |
|             echo "$__runsfile"
 | |
|             return 0
 | |
|         fi
 | |
|     fi
 | |
|     # puis chercher dans les répertoire d'hôtes
 | |
|     if [ -n "$__runshost" ]; then
 | |
|         splithost "$__runshost" __hostname __domain
 | |
|         for __runsdir in "${!__runshostsdirs}"; do
 | |
|             for __runsfile in \
 | |
|                 "$__runsdir/$__runshost/$__datafile" \
 | |
|                 "$__runsdir/$__domain/$__hostname/$__datafile"; do
 | |
|                 if [ -e "$__runsfile" ]; then
 | |
|                     echo "$__runsfile"
 | |
|                     return 0
 | |
|                 fi
 | |
|             done
 | |
|         done
 | |
|     fi
 | |
|     # puis chercher dans les répertoires des scripts et des modules
 | |
|     for __runsdir in "${!__runsscriptsdirs}" "${!__runsmodulesdirs}"; do
 | |
|         __runsfile="$__runsdir/$__datafile"
 | |
|         if [ -e "$__runsfile" ]; then
 | |
|             echo "$__runsfile"
 | |
|             return 0
 | |
|         fi
 | |
|     done
 | |
|     # puis chercher dans le répertoire du script
 | |
|     if [ -z "$__withpath" -a -n "$__runsscriptdir" ]; then
 | |
|         __runsfile="$__runsscriptdir/$__datafile"
 | |
|         if [ -e "$__runsfile" ]; then
 | |
|             echo "$__runsfile"
 | |
|             return 0
 | |
|         fi
 | |
|     fi
 | |
|     # fichier non trouvé
 | |
|     return 1
 | |
| }
 | |
| 
 | |
| function runs_initvars() {
 | |
|     # Initialiser les variables RUNSDIR, RUNSSCRIPT, RUNSDIRPATH,
 | |
|     # RUNSSCRIPTPATH, RUNSSCRIPTDIR et RUNSSCRIPTNAME pour le script $1.
 | |
|     # Les valeurs sont initialisées comme suit:
 | |
|     # RUNSSCRIPT="$(abspath "$1")"
 | |
|     # RUNSDIR="$2" (le répertoire de $RUNS*PATH dans lequel a été trouvé le
 | |
|     # script)
 | |
|     # Si $3!="", RUNSDIRPATH="$3" et RUNSSCRIPTPATH="$4"
 | |
|     # Sinon, RUNSDIRPATH="$RUNSSCRIPTDIR" et RUNSSCRIPTPATH="$RUNSSCRIPTNAME"
 | |
|     RUNSSCRIPT="$(abspath "$1")"
 | |
|     RUNSSCRIPTDIR="$(dirname "$RUNSSCRIPT")"
 | |
|     RUNSSCRIPTNAME="$(basename "$RUNSSCRIPT")"
 | |
|     RUNSDIR="$2"
 | |
|     if [ -n "$3" ]; then
 | |
|         RUNSDIRPATH="$3"
 | |
|         RUNSSCRIPTPATH="$4"
 | |
|     else
 | |
|         RUNSDIRPATH="$RUNSSCRIPTDIR"
 | |
|         RUNSSCRIPTPATH="$RUNSSCRIPTNAME"
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function runs_find_scriptfile() {
 | |
|     # Trouver sans l'afficher le script $1 dans les répertoires des tableaux
 | |
|     # $3(=RUNSSCRIPTSDIRS), $4(=RUNSMODULESDIRS) et $5(=RUNSHOSTSDIRS), en
 | |
|     # considérant que le script sera lancé sur l'hôte $2(=$RUNSHOST), et
 | |
|     # initialiser les variables RUNSDIR, RUNSSCRIPT, RUNSSCRIPTDIR,
 | |
|     # RUNSSCRIPTNAME, RUNSDIRPATH et RUNSSCRIPTPATH. Retourner 0 en cas de
 | |
|     # succès, 1 en cas d'échec.
 | |
|     # RUNSDIR est le répertoire dans lequel a été trouvé le script (parmi les
 | |
|     # valeurs fournies dans les tableaux RUNSSCRIPTSDIRS, RUNSMODULESDIRS,
 | |
|     # RUNSHOSTSDIRS), RUNSDIRPATH est le répertoire à partir duquel est exprimé
 | |
|     # le chemin du script (i.e RUNSDIRPATH + RUNSSCRIPTPATH == RUNSSCRIPT),
 | |
|     # RUNSSCRIPT contient le chemin absolu vers le script, RUNSSCRIPTPATH
 | |
|     # contient le chemin du script dans RUNSDIRPATH, RUNSSCRIPTDIR le répertoire
 | |
|     # du script, et RUNSSCRIPTNAME le nom du script.
 | |
|     # D'abord, si l'hôte est spécifié, chercher dans {$RUNSHOSTSDIRS}/$host et
 | |
|     # {$RUNSHOSTSDIRS}/$domain/$hostname. Puis chercher dans {$RUNSSCRIPTSDIRS}
 | |
|     # puis {$RUNSMODULESDIRS}. Sinon, retourner 1
 | |
|     local __scriptfile="$1" __runshost="${2:-$RUNSHOST}"
 | |
|     local __runsscriptsdirs="${3:-RUNSSCRIPTSDIRS}[@]"
 | |
|     local __runsmodulesdirs="${4:-RUNSMODULESDIRS}[@]"
 | |
|     local __runshostsdirs="${5:-RUNSHOSTSDIRS}[@]"
 | |
|     local __domain __hostname
 | |
|     local __runsdir __runsfile
 | |
| 
 | |
|     # chercher le cas échéant dans les répertoire d'hôtes
 | |
|     if [ -n "$__runshost" ]; then
 | |
|         splithost "$__runshost" __hostname __domain
 | |
|         for __runsdir in "${!__runshostsdirs}"; do
 | |
|             for __runsfile in \
 | |
|                 "$__runsdir/$__runshost/$__scriptfile" \
 | |
|                 "$__runsdir/$__domain/$__hostname/$__scriptfile"; do
 | |
|                 if [ ! -f "$__runsfile" -a -f "$__runsfile.rs" ]; then
 | |
|                     __runsfile="$__runsfile.rs"
 | |
|                 fi
 | |
|                 if [ -e "$__runsfile" ]; then
 | |
|                     runs_initvars "$__runsfile" "$__runsdir" "$__runsdirpath" "$__scriptfile"
 | |
|                     return 0
 | |
|                 fi
 | |
|             done
 | |
|         done
 | |
|     fi
 | |
|     # puis chercher dans les répertoires des scripts et des modules
 | |
|     for __runsdir in "${!__runsscriptsdirs}" "${!__runsmodulesdirs}"; do
 | |
|         __runsfile="$__runsdir/$__scriptfile"
 | |
|         if [ ! -f "$__runsfile" -a -f "$__runsfile.rs" ]; then
 | |
|             __runsfile="$__runsfile.rs"
 | |
|         fi
 | |
|         if [ -e "$__runsfile" ]; then
 | |
|             runs_initvars "$__runsfile" "$__runsdir" "$__runsdir" "$__scriptfile"
 | |
|             return 0
 | |
|         fi
 | |
|     done
 | |
|     return 1
 | |
| }
 | |
| 
 | |
| function runs_find_scriptfile_reverse() {
 | |
|     # Soit le fichier de script $1, exprimée de façon absolue, trouver le
 | |
|     # fichier parmi les tableaux $3(=RUNSSCRIPTSDIRS), $4(=RUNSMODULESDIRS)
 | |
|     # et $5(=RUNSHOSTSDIRS), en considérant que le script sera lancé sur l'hôte
 | |
|     # $2(=$RUNSHOST), puis initialiser les variables RUNSDIR, RUNSSCRIPT,
 | |
|     # RUNSSCRIPTDIR, RUNSSCRIPTNAME, RUNSDIRPATH et RUNSSCRIPTPATH. Retourner 0
 | |
|     # en cas de succès, 1 en cas d'échec.
 | |
|     local __runsscript="$1" __runshost="${2:-$RUNSHOST}"
 | |
|     local __runsscriptsdirs="${3:-RUNSSCRIPTSDIRS}[@]"
 | |
|     local __runsmodulesdirs="${4:-RUNSMODULESDIRS}[@]"
 | |
|     local __runshostsdirs="${5:-RUNSHOSTSDIRS}[@]"
 | |
|     local __domain __hostname
 | |
|     local __runsdir __runsfile __prefix
 | |
| 
 | |
|     # chercher le cas échéant dans les répertoire d'hôtes
 | |
|     if [ -n "$__runshost" ]; then
 | |
|         splithost "$__runshost" __hostname __domain
 | |
|         for __runsdir in "${!__runshostsdirs}"; do
 | |
|             __prefix="$__runsdir/$__runshost/"
 | |
|             if [ "${__runsscript#$__prefix}" != "$__runsscript" ]; then
 | |
|                 runs_initvars "$__runsscript" "$__runsdir" "$__prefix" "${__runsscript#$__prefix/}"
 | |
|                 return 0
 | |
|             fi
 | |
|             __prefix="$__runsdir/$__domain/$__hostname/"
 | |
|             if [ "${__runsscript#$__prefix}" != "$__runsscript" ]; then
 | |
|                 runs_initvars "$__runsscript" "$__runsdir" "$__prefix" "${__runsscript#$__prefix/}"
 | |
|                 return 0
 | |
|             fi
 | |
|         done
 | |
|     fi
 | |
|     # puis chercher dans les répertoires des scripts et des modules
 | |
|     for __runsdir in "${!__runsscriptsdirs}"; do
 | |
|         __prefix="$__runsdir/"
 | |
|         if [ "${__runsscript#$__prefix}" != "$__runsscript" ]; then
 | |
|             runs_initvars "$__runsscript" "$__runsdir" "$__prefix" "${__runsscript#$__prefix/}"
 | |
|             return 0
 | |
|         fi
 | |
|     done
 | |
|     for __runsdir in "${!__runsmodulesdirs}"; do
 | |
|         __prefix="$__runsdir/"
 | |
|         if [ "${__runsscript#$__prefix}" != "$__runsscript" ]; then
 | |
|             runs_initvars "$__runsscript" "$__runsdir" "$__prefix" "${__runsscript#$__prefix/}"
 | |
|             return 0
 | |
|         fi
 | |
|     done
 | |
|     return 1
 | |
| }
 | |
| 
 | |
| function runs_rscript() {
 | |
|     # Lancer le fichier $1 comme un script avec les arguments $2..$*. Retourner
 | |
|     # la valeur de retour du script.
 | |
|     local state
 | |
|     local RUNSDIR RUNSSCRIPT RUNSSCRIPTDIR RUNSSCRIPTNAME RUNSDIRPATH RUNSSCRIPTPATH
 | |
|     local RUNSSCRIPTSDIRS RUNSMODULESDIRS RUNSHOSTSDIRS; __runs_setpath
 | |
| 
 | |
|     local rscript="$1"; shift
 | |
|     if [ ! -f "$rscript" ]; then
 | |
|         eerror "$rscript: fichier introuvable."
 | |
|         return 123
 | |
|     fi
 | |
| 
 | |
|     # trouver runs*dir correspondant à $rscript
 | |
|     rscript="$(abspath "$rscript")"
 | |
|     runs_find_scriptfile_reverse "$rscript" "$RUNSHOST" || runs_initvars "$rscript"
 | |
| 
 | |
|     # puis lancer le script
 | |
|     RUNSSTORY=("${RUNSSTORY[@]}" "$RUNSSCRIPTPATH")
 | |
|     state=0
 | |
|     "$RUNSACTION" "$@" || {
 | |
|         state=$?
 | |
|         eerror "$RUNSSCRIPTPATH: Une erreur s'est produite."
 | |
|     }
 | |
|     return $state
 | |
| }
 | |
| 
 | |
| function __runs_iscont() {
 | |
|     # tester si $1 est une ligne de continuation dans une recette
 | |
|     [ "${1# }" != "$1" ] && return 0
 | |
|     [ "${1#$TAB}" != "$1" ] && return 0
 | |
|     return 1
 | |
| }
 | |
| 
 | |
| function runs_recipe() {
 | |
|     # Lancer les scripts de la recette contenue dans le fichier $1. Arrêter au
 | |
|     # premier script qui est en erreur
 | |
|     local recipe rcmds rcmd i count rscripts rscript
 | |
| 
 | |
|     recipe="$(abspath "$1")"
 | |
|     if [ -d "$recipe" ]; then
 | |
|         if is_root; then
 | |
|             recipe="$recipe/default"
 | |
|         else
 | |
|             recipe="$recipe/userdefault"
 | |
|         fi
 | |
|     fi
 | |
|     if [ ! -f "$recipe" ]; then
 | |
|         eerror "$(ppath "$recipe"): fichier introuvable"
 | |
|         return 1
 | |
|     fi
 | |
|     if array_contains RUNSRECIPES "$recipe"; then
 | |
|         eerror "$(ppath "$recipe"): inclusion récursive"
 | |
|         return 1
 | |
|     fi
 | |
|     RUNSRECIPES=("${RUNSRECIPES[@]}" "$recipe")
 | |
|     # lire les ingredients de la recette
 | |
|     recipe="$(<"$recipe" filter_comment -m)"
 | |
|     array_from_lines rcmds "$recipe"
 | |
|     # fusionner les lignes d'ingrédients
 | |
|     let i=0
 | |
|     let count=${#rcmds[@]}
 | |
|     rscript=
 | |
|     rscripts=()
 | |
|     while [ $i -lt $count ]; do
 | |
|         rcmd="${rcmds[$i]}"
 | |
|         if ! __runs_iscont "$rcmd"; then
 | |
|             # il faut recommencer une nouvelle commande
 | |
|             # mais d'abord, traiter l'ancienne commande si nécessaire
 | |
|             [ -n "$rscript" ] && rscripts=("${rscripts[@]}" "$rscript")
 | |
|             rscript="$rcmd"
 | |
|         elif [ -z "$rscript" ]; then
 | |
|             # nous avons une ligne de continuation mal placée
 | |
|             ewarn "$rcmd: Ligne de continuation mal placée, elle sera ignorée"
 | |
|         else
 | |
|             # nous avons une ligne de continuation
 | |
|             rscript="$rscript \; $rcmd"
 | |
|         fi
 | |
|         let i=$i+1
 | |
|         [ $i -eq $count -a -n "$rscript" ] && rscripts=("${rscripts[@]}" "$rscript")
 | |
|     done
 | |
|     # lancer les ingrédients et s'arrêter à la premier erreur
 | |
|     for rscript in "${rscripts[@]}"; do
 | |
|         eval "set -- $rscript"
 | |
|         if [ "${1#@}" != "$1" ]; then
 | |
|             # Le caractère @ identifie une recette au lieu d'un script individuel
 | |
|             local RUNSDIR RUNSSCRIPT RUNSSCRIPTDIR RUNSSCRIPTNAME RUNSDIRPATH RUNSSCRIPTPATH
 | |
|             local RUNSSCRIPTSDIRS RUNSMODULESDIRS RUNSHOSTSDIRS; __runs_setpath
 | |
|             recipe="${1#@}"
 | |
|             if ! runs_find_scriptfile "$recipe"; then
 | |
|                 eerror "$recipe: fichier introuvable. Vérifiez les valeurs suivantes:
 | |
| RUNSSCRIPTSPATH=$RUNSSCRIPTSPATH
 | |
| RUNSMODULESPATH=$RUNSMODULESPATH
 | |
| RUNSHOSTSPATH=$RUNSHOSTSPATH
 | |
| RUNSHOST=$RUNSHOST"
 | |
|                 return 123
 | |
|             fi
 | |
|             etitle "$1" runs_recipe "$RUNSSCRIPT" || return
 | |
|         else
 | |
|             etitle "$1" runs_rscriptpath "$@" || return
 | |
|         fi
 | |
|     done
 | |
|     return 0
 | |
| }
 | |
| 
 | |
| function runs_rscriptpath() {
 | |
|     # Lancer le script $1 avec les arguments $2..$*. Le script est cherché dans
 | |
|     # les répertoires de RUNSSCRIPTSPATH. Retourner 123 si le script n'est pas
 | |
|     # trouvé, sinon retourner la valeur de retour du script.
 | |
|     local state
 | |
|     local RUNSDIR RUNSSCRIPT RUNSSCRIPTDIR RUNSSCRIPTNAME RUNSDIRPATH RUNSSCRIPTPATH
 | |
|     local RUNSSCRIPTSDIRS RUNSMODULESDIRS RUNSHOSTSDIRS; __runs_setpath
 | |
|     if ! runs_find_scriptfile "$1"; then
 | |
|         eerror "$1: fichier introuvable. Vérifiez les valeurs suivantes:
 | |
| RUNSSCRIPTSPATH=$RUNSSCRIPTSPATH
 | |
| RUNSMODULESPATH=$RUNSMODULESPATH
 | |
| RUNSHOSTSPATH=$RUNSHOSTSPATH
 | |
| RUNSHOST=$RUNSHOST"
 | |
|         return 123
 | |
|     fi
 | |
|     shift
 | |
| 
 | |
|     RUNSSTORY=("${RUNSSTORY[@]}" "$RUNSSCRIPTPATH")
 | |
|     state=0
 | |
|     "$RUNSACTION" "$@" || {
 | |
|         state=$?
 | |
|         eerror "$RUNSSCRIPTPATH: Une erreur s'est produite."
 | |
|     }
 | |
|     return $state
 | |
| }
 | |
| 
 | |
| function runs_recipepath() {
 | |
|     # Lancer la recette $1. Le fichier de recette est cherché dans les
 | |
|     # répertoires de RUNSSCRIPTSPATH. Retourner 123 si le fichier de recette n'a
 | |
|     # pas été trouvé, sinon retourner la valeur de retour de runs_recipe()
 | |
|     local RUNSDIR RUNSSCRIPT RUNSSCRIPTDIR RUNSSCRIPTNAME RUNSDIRPATH RUNSSCRIPTPATH
 | |
|     local RUNSSCRIPTSDIRS RUNSMODULESDIRS RUNSHOSTSDIRS; __runs_setpath
 | |
|     if ! runs_find_scriptfile "$1"; then
 | |
|         eerror "$1: fichier introuvable. Vérifiez les valeurs suivantes:
 | |
| RUNSSCRIPTSPATH=$RUNSSCRIPTSPATH
 | |
| RUNSMODULESPATH=$RUNSMODULESPATH
 | |
| RUNSHOSTSPATH=$RUNSHOSTSPATH
 | |
| RUNSHOST=$RUNSHOST"
 | |
|         return 123
 | |
|     fi
 | |
| 
 | |
|     runs_recipe "$RUNSSCRIPT"
 | |
| }
 | |
| 
 | |
| ################################################################################
 | |
| # Moteur de script
 | |
| 
 | |
| function runs_init() {
 | |
|     RUNSSRCDIR="${1:-$scriptdir}" # répertoire d'où sont copiés les scripts
 | |
|     RUNSACTION=runs_action_run
 | |
|     # informations sur le système
 | |
|     RUNSHOST="$MYHOST"
 | |
|     RUNSACTUALSYSNAME=("${MYSYSNAME[@]}")
 | |
|     RUNSACTUALSYSDIST=("${MYSYSDIST[@]}")
 | |
|     RUNSACTUALSYSVER=("${MYSYSVER[@]}")
 | |
|     RUNSACTUALBITS="$MYBITS"
 | |
|     RUNSEXPORTDIR= # avec --export, répertoire de base de l'export
 | |
|     RUNSROOTDIR= # avec --export, répertoire correspondant à la racine
 | |
|     RUNSWORKDIR=
 | |
|     RUNSUPDATERECIPE=1 # faut-il rajouter la ligne de recette lors d'un export
 | |
|     RUNSCONFFILES= # fichier de configuration qui ont été chargés
 | |
|     # liste des varibles définies
 | |
|     RUNSVARS=()
 | |
|     # parmis les variables de RUNSVARS, liste de celles qui sont des tableaux
 | |
|     RUNSARRAYS=()
 | |
|     # parmis les variables de RUNSVARS, liste de celles qui sont des indirections
 | |
|     RUNSVARSINDIRECT=()
 | |
|     # liste des références définies
 | |
|     RUNSREFS=()
 | |
|     # recettes qui ont déjà été lancées, pour éviter les inclusions récursives
 | |
|     RUNSRECIPES=()
 | |
|     # scripts qui ont déjà été lancés, pour la commande after
 | |
|     RUNSSTORY=()
 | |
|     # flags valides et ceux qui ont été activés
 | |
|     RUNSVALIDCONFS=(root local proxy nolang)
 | |
|     RUNSCONFS=()
 | |
|     # Faut-il réinitialiser les scripts qui se basent sur shouldrun/setdone
 | |
|     RUNSRESET=
 | |
| }
 | |
| 
 | |
| function runs_initdomains() {
 | |
|     # Si ce n'est pas déjà le cas, initialiser RUNSDOMAINS en fonction de
 | |
|     # /etc/resolv.conf
 | |
|     [ -n "${RUNSDOMAINS[*]}" ] && return
 | |
|     local domains="$(awk '$1 == "search" { $1 = ""; print }' /etc/resolv.conf)"
 | |
|     eval "RUNSDOMAINS=($domains)"
 | |
| }
 | |
| 
 | |
| function runs_inithost() {
 | |
|     [ -n "$1" ] && RUNSHOST="$1"
 | |
| }
 | |
| 
 | |
| function runs_initsysinfos() {
 | |
|     local RUNSSCRIPTSDIRS RUNSMODULESDIRS RUNSHOSTSDIRS; __runs_setpath
 | |
|     local sysname="$1" sysdist="$2" sysver="$3" bits="$4"
 | |
| 
 | |
|     # on a spécifié le nombre de bits
 | |
|     [ -n "$bits" ] && MYBITS="$bits"
 | |
| 
 | |
|     if [ -n "$sysname" -o -n "$sysdist" -o -n "$sysver" ]; then
 | |
|         # on a spécifié un système en ligne de commande
 | |
|         ensure_sysinfos sysname sysdist sysver
 | |
|     else
 | |
|         # Si le fichier sysinfos.conf existe dans le répertoire d'hôte, y
 | |
|         # prendre les valeurs
 | |
|         local sysinfos
 | |
|         if sysinfos="$(runs_find_hostfile sysinfos.conf)"; then
 | |
|             sysname=()
 | |
|             sysdist=()
 | |
|             sysver=()
 | |
|             bits=
 | |
|             source "$sysinfos"
 | |
|             [ -n "$bits" ] && MYBITS="$bits"
 | |
|             if [ -n "$sysname" -o -n "$sysdist" -o -n "$sysver" ]; then
 | |
|                 ensure_sysinfos sysname sysdist sysver
 | |
|             else
 | |
|                 # aucune modification n'a été faite par le fichier de
 | |
|                 # configuration. ne pas modifier les valeurs courantes
 | |
|                 return
 | |
|             fi
 | |
|         else
 | |
|             # aucun fichier de configuration. ne pas modifier les valeurs
 | |
|             # courantes
 | |
|             return
 | |
|         fi
 | |
|     fi
 | |
|     MYSYSNAME=("${sysname[@]}")
 | |
|     MYSYSDIST=("${sysdist[@]}")
 | |
|     MYSYSVER=("${sysver[@]}")
 | |
|     MYBITS="$bits"
 | |
| }
 | |
| 
 | |
| function runs_initworkdir() {
 | |
|     local runsexportdir="$1" runsworkdir="$2" scriptdir="${3:-$scriptdir}"
 | |
|     if [ -z "$runsexportdir" -a "$RUNSACTION" == runs_action_export ]; then
 | |
|         # en mode export, il faut définir runsexportdir
 | |
|         ac_set_tmpdir runsexportdir
 | |
|     fi
 | |
|     if [ -n "$runsexportdir" ]; then
 | |
|         if [ -n "$runsworkdir" ]; then
 | |
|             ewarn "Avec --export, la valeur de --runsworkdir est ignorée"
 | |
|         fi
 | |
|         RUNSEXPORTDIR="$(abspath "$runsexportdir")"
 | |
|         RUNSROOTDIR="$RUNSEXPORTDIR/root"
 | |
|         RUNSWORKDIR="$RUNSEXPORTDIR/work"
 | |
|         mkdir -p "$RUNSEXPORTDIR"
 | |
|         mkdir -p "$RUNSROOTDIR"
 | |
|         mkdir -p "$RUNSWORKDIR"
 | |
|         
 | |
|         if [ "$RUNSACTION" == "runs_action_export" ]; then
 | |
|             # préparer les fichiers pour l'export
 | |
|             >"$RUNSEXPORTDIR/varsfile"
 | |
|             >"$RUNSEXPORTDIR/localuser"
 | |
|             >"$RUNSEXPORTDIR/localroot"
 | |
|             >"$RUNSEXPORTDIR/remoteuser"
 | |
|             >"$RUNSEXPORTDIR/remoteroot"
 | |
|             
 | |
|             # synchronisation ulib
 | |
|             urequire ulib pyulib/pyulib
 | |
|             ulibsync "$RUNSEXPORTDIR"
 | |
|             pyulibsync "$RUNSEXPORTDIR"
 | |
| 
 | |
|             # copie runs, uinst
 | |
|             cp "$RUNSSRCDIR/runs" "$RUNSEXPORTDIR"
 | |
|             cp "$RUNSSRCDIR/uinst" "$RUNSEXPORTDIR"
 | |
| 
 | |
|             # faire les scripts
 | |
|             args_def="args=($(quoted_args ./runs --runsscriptspath "$RUNSSCRIPTSPATH" --runsmodulespath "$RUNSMODULESPATH" --runshostspath "$RUNSHOSTSPATH" --runsexportdir . --runsvarsfile varsfile -h "$RUNSHOST" ${RUNSRESET:+ -z}))"
 | |
|             echo '#!/bin/bash
 | |
| # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| cd "$(dirname "$0")"
 | |
| '"$args_def"'
 | |
| [ -s localuser ] && { "${args[@]}" -r localuser || exit 1; }
 | |
| [ -s localroot ] && { "${args[@]}" -r localroot -s || exit 1; }
 | |
| exit 0
 | |
| ' >"$RUNSEXPORTDIR/runs-local"
 | |
|             echo '#!/bin/bash
 | |
| # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| cd "$(dirname "$0")"
 | |
| '"$args_def"'
 | |
| if [ -s remote ]; then
 | |
|     [ -f remote-needs-root ] && args=("${args[@]}" -s)
 | |
|     "${args[@]}" -r remote || exit 1
 | |
| fi
 | |
| exit 0
 | |
| ' >"$RUNSEXPORTDIR/runs-remote"
 | |
|             chmod +x "$RUNSEXPORTDIR/runs-local" "$RUNSEXPORTDIR/runs-remote"
 | |
|         else
 | |
|             # corriger RUNS*PATH à partir de RUNSROOTDIR
 | |
|             function __runs_add_runsroot() { echo "$RUNSROOTDIR$1"; }
 | |
|             local runspath runsdirs
 | |
|             for runspath in RUNSSCRIPTSPATH RUNSMODULESPATH RUNSHOSTSPATH; do
 | |
|                 array_from_path runsdirs "${!runspath}"
 | |
|                 array_map runsdirs abspath
 | |
|                 array_map runsdirs __runs_add_runsroot
 | |
|                 set_var "$runspath" "$(array_join runsdirs :)"
 | |
|             done
 | |
|             # XXX quelles autres variables doivent être corrigées?
 | |
|         fi
 | |
|     elif [ -n "$runsworkdir" ]; then
 | |
|         RUNSWORKDIR="$runsworkdir"
 | |
|     else
 | |
|         ac_set_tmpdir RUNSWORKDIR
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function runs_after_export() {
 | |
|     # après l'export, initialiser varsfile avec les valeurs qu'il faut garder
 | |
|     # entre le déploiement local et le déploiement distant.
 | |
|     if [ "$RUNSACTION" == runs_action_export ]; then
 | |
|         set_array_cmd RUNSSTORY >>"$RUNSEXPORTDIR/varsfile"
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function __runs_is_runsscript() {
 | |
|     if [ -f "$1" ]; then
 | |
|         quietgrep "^script:" "$1"
 | |
|     elif [ -d "$1" ]; then
 | |
|         [ -f "$1/.udir" ]
 | |
|     else
 | |
|         return 1
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function runs_check_runsscript() {
 | |
|     if [ -f "$1" ] && ! __runs_is_runsscript "$1"; then
 | |
|         eerror "$1: ce n'est pas un fichier de script valide: il manque la ligne 'script:'"
 | |
|         return 1
 | |
|     elif [ -d "$1" ]; then
 | |
|         return 0
 | |
|     fi
 | |
|     return 0
 | |
| }
 | |
| 
 | |
| function __runs_check_varname() {
 | |
|     if [ "${1#RUNS}" != "$1" -o "${1#_}" != "$1" ]; then
 | |
|         ewarn "Variable invalide: $1. Cette valeur a été ignorée"
 | |
|         return 1
 | |
|     fi
 | |
|     return 0
 | |
| }
 | |
| function __runs_check_notref() {
 | |
|     if array_contains RUNSREFS "$1"; then
 | |
|         ewarn "Vous ne pouvez pas modifier la référence $1. La valeur sera ignorée"
 | |
|         return 1
 | |
|     fi
 | |
|     return 0
 | |
| }
 | |
| function __runs_splitref() {
 | |
|     if [[ "$1" == *=* ]]; then
 | |
|         set_var "${2:-__name}" "${1%%=*}"
 | |
|         set_var "${3:-__value}" "${1#*=}"
 | |
|     else
 | |
|         set_var "${2:-__name}" "$1"
 | |
|         set_var "${3:-__value}" "$1"
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function runs_var() {
 | |
|     # Initialiser les variables selon les directives données en ligne de
 | |
|     # commande.
 | |
|     # Les arguments peuvent être une suite de définitions de la forme
 | |
|     # 'scalar=value', 'scalar!=name', 'array+=value', 'array-=value' ou
 | |
|     # 'array@=name'.
 | |
|     # Sinon, le *dernier* argument peut-être de l'une des formes suivantes:
 | |
|     # 'array value0 [value1...]' pour initialiser un tableau,
 | |
|     # 'array+ value0 [value1...]' pour ajouter des valeurs à un tableau,
 | |
|     # 'array- value0 [value1...]' pour enlever des valeurs à un tableau.
 | |
|     # Les formes 'scalar!=value' et 'array@=value' sont des indirections et
 | |
|     # permettent d'initialiser la variable avec la valeur d'une autre
 | |
|     # variable. L'avantage est que la résolution de la valeur est faite
 | |
|     # uniquement lors de l'appel de cette fonction, ce qui est utile avec des
 | |
|     # fonction comme 'after -r'
 | |
|     local __name __value
 | |
|     # variables scalaires ou manipulation de tableaux
 | |
|     while [ -n "$1" ]; do
 | |
|         if [[ "$1" == *+=* ]]; then
 | |
|             __name="${1%%+=*}"
 | |
|             __value="${1#*+=}"
 | |
|             if __runs_check_varname "$__name" && __runs_check_notref "$__name"; then
 | |
|                 array_set RUNSVARS "$__name"
 | |
|                 array_set RUNSARRAYS "$__name"
 | |
|                 array_del RUNSVARSINDIRECT "$__name"
 | |
|                 array_add "$__name" "$__value"
 | |
|             fi
 | |
|         elif [[ "$1" == *-=* ]]; then
 | |
|             __name="${1%%-=*}"
 | |
|             __value="${1#*-=}"
 | |
|             if __runs_check_varname "$__name" && __runs_check_notref "$__name"; then
 | |
|                 array_set RUNSVARS "$__name"
 | |
|                 array_set RUNSARRAYS "$__name"
 | |
|                 array_del RUNSVARSINDIRECT "$__name"
 | |
|                 array_del "$__name" "$__value"
 | |
|             fi
 | |
|         elif [[ "$1" == *!=* ]]; then
 | |
|             __name="${1%%!=*}"
 | |
|             __value="${1#*!=}"
 | |
|             if __runs_check_varname "$__name" && __runs_check_notref "$__name"; then
 | |
|                 array_set RUNSVARS "$__name"
 | |
|                 array_del RUNSARRAYS "$__name"
 | |
|                 array_set RUNSVARSINDIRECT "$__name"
 | |
|                 set_var "$__name" "$__value"
 | |
|             fi
 | |
|         elif [[ "$1" == *@=* ]]; then
 | |
|             __name="${1%%@=*}"
 | |
|             __value="${1#*@=}"
 | |
|             if __runs_check_varname "$__name" && __runs_check_notref "$__name"; then
 | |
|                 array_set RUNSVARS "$__name"
 | |
|                 array_set RUNSARRAYS "$__name"
 | |
|                 array_set RUNSVARSINDIRECT "$__name"
 | |
|                 set_var "$__name" "$__value"
 | |
|             fi
 | |
|         elif [[ "$1" == *=* ]]; then
 | |
|             __name="${1%%=*}"
 | |
|             __value="${1#*=}"
 | |
|             if __runs_check_varname "$__name" && __runs_check_notref "$__name"; then
 | |
|                 array_set RUNSVARS "$__name"
 | |
|                 array_del RUNSARRAYS "$__name"
 | |
|                 array_del RUNSVARSINDIRECT "$__name"
 | |
|                 set_var "$__name" "$__value"
 | |
|             fi
 | |
|         else
 | |
|             break
 | |
|         fi
 | |
|         [ -n "$RUNSVARDESC" ] && set_var "RUNSVARDESC_$__name" "$RUNSVARDESC"
 | |
|         shift
 | |
|     done
 | |
|     # variables tableau
 | |
|     if [ -n "$1" ]; then
 | |
|         __name="$1"; shift
 | |
|         if __runs_check_varname "$__name" && __runs_check_notref "$__name"; then
 | |
|             if [ "${__name%+}" != "$__name" ]; then
 | |
|                 __name="${__name%+}"
 | |
|                 for __value in "$@"; do
 | |
|                     array_add "$__name" "$__value"
 | |
|                 done
 | |
|             elif [ "${__name%-}" != "$__name" ]; then
 | |
|                 __name="${__name%-}"
 | |
|                 for __value in "$@"; do
 | |
|                     array_del "$__name" "$__value"
 | |
|                 done
 | |
|             else
 | |
|                 set_array "$__name" @ "$@"
 | |
|             fi
 | |
|             # Placer $__name dans les tableau après qu'il aie été corrigé
 | |
|             # si par exemple il se terminer par '+' ou '-'
 | |
|             array_set RUNSVARS "$__name"
 | |
|             array_set RUNSARRAYS "$__name"
 | |
|             array_del RUNSVARSINDIRECT "$__name"
 | |
|         fi
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function runs_conf() {
 | |
|     # Activer les flags $*
 | |
|     for __conf in "$@"; do
 | |
|         if array_contains RUNSVALIDCONFS "$__conf"; then
 | |
|             array_set RUNSCONFS "$__conf"
 | |
|         else
 | |
|             ewarn "Flag inconnu: $__conf. Il sera ignoré"
 | |
|         fi
 | |
|     done
 | |
| }
 | |
| 
 | |
| function runs_indref() {
 | |
|     # fonction de convenance pour créer des références $3..* avec le fichier de
 | |
|     # configuration $1 et les variables $2
 | |
|     local __sconf="$1" __vars="$2"; shift; shift
 | |
|     ref -s "$__sconf" -v "$__vars" "$@"
 | |
| }
 | |
| function runs_refcerts() {
 | |
|     # fonction de convenance pour créer une référence à un répertoire contenant
 | |
|     # des certificats mentionnés dans le fichier de configuration $1. Si les
 | |
|     # références $2..* ne sont pas mentionnées, la variable certsdir dans le
 | |
|     # fichier de configuration est utilisée.
 | |
|     local __sconf="$1"; shift
 | |
|     runs_indref "$__sconf" ca,cert,key -V certsdir "$@"
 | |
| }
 | |
| function runs_refapacheconfig() {
 | |
|     # fonction de convenance pour créer les références à un répertoire de
 | |
|     # configuration pour apache.
 | |
|     # USAGE: refapacheconfig autoconfdir=path/to/autoconfdir [certsdir=[path/to/certsdir]]
 | |
|     # - autoconfdir= est requis et permet de définir à la fois la variable qui
 | |
|     # contiendra la référence ainsi que le répertoire à référencer.
 | |
|     # - certsdir= est optionel. Si cet argument est spécifié sous la forme
 | |
|     # certsdir=path/to/certsdir, il permet de définir à la fois la variable qui
 | |
|     # contiendra la référence ainsi que le répertoire à référencer. Si
 | |
|     # l'argument est spécifié sous la forme certsdir=, il permet de définir la
 | |
|     # variable qui contiendra la référence. C'est cette variable qui sera lue
 | |
|     # dans les fichiers de configuration. Si l'argument n'est pas spécifié, on
 | |
|     # considère que l'argument 'certsdir=' a été utilisé.
 | |
|     :
 | |
|     #local -a __args
 | |
|     #parse_opts + \
 | |
|     #    @ __args -- "$@" && set -- "${__args[@]}" || die "$__args"
 | |
| }
 | |
| 
 | |
| function runs_set_lang() {
 | |
|     # Charger la valeur de LANG depuis l'environnement. La variable LANG est
 | |
|     # initialisée
 | |
|     if ! array_contains RUNSCONFS nolang; then
 | |
|         if check_sysinfos -d debianlike; then
 | |
|             eval "$(LANG=
 | |
|                 source_ifexists /etc/default/locale
 | |
|                 set_var_cmd LANG "$LANG"
 | |
|             )"
 | |
|         fi
 | |
|         export LANG
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function runs_set_proxy() {
 | |
|     # Charger la valeur du proxy depuis l'environnement. Les variables
 | |
|     # http_proxy, ftp_proxy et no_proxy sont initialisées
 | |
|     if array_contains RUNSCONFS proxy; then
 | |
|         if check_sysinfos -d debianlike; then
 | |
|             eval "$(http_proxy=; ftp_proxy=; no_proxy=
 | |
|                 source_ifexists /etc/environment
 | |
|                 set_var_cmd http_proxy "$http_proxy"
 | |
|                 set_var_cmd ftp_proxy "$ftp_proxy"
 | |
|                 set_var_cmd no_proxy "$no_proxy"
 | |
|             )"
 | |
|         fi
 | |
|         export http_proxy ftp_proxy no_proxy 
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function runs_check_confs() {
 | |
|     # Vérifier l'état courant par rapport aux flags
 | |
|     if array_contains RUNSCONFS root; then
 | |
|         is_root || die "Ce script requière d'être lancé en root (essayer avec l'option -s)"
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function runs_after() {
 | |
|     # Vérifier que ce script est lancé après le scriptpath $1, par rapport à
 | |
|     # RUNSSTORY
 | |
|     local -a __args
 | |
|     local runslevel=0
 | |
|     parse_opts + \
 | |
|         -r,--run runslevel \
 | |
|         @ __args -- "$@" && set -- "${__args[@]}" || die "$__args"
 | |
| 
 | |
|     # Le traitement est fait en fonction de runslevel
 | |
|     if [ $runslevel -eq 0 ]; then
 | |
|         # sans l'option -r, on ne fait que vérifier que les scriptpaths
 | |
|         # correspondant aux arguments ont déjà été lancés. On peut spécifier
 | |
|         # autant de scriptpaths que nécessaire, puisque que des arguments ne
 | |
|         # sont pas nécessaires
 | |
|         local scriptpath
 | |
|         for scriptpath in "$@"; do
 | |
|             if ! array_contains RUNSSTORY "$scriptpath"; then
 | |
|                 eerror "Ce script requière d'être lancé après $scriptpath"
 | |
|                 return 1
 | |
|             fi
 | |
|         done
 | |
|         return 0
 | |
|     fi
 | |
| 
 | |
|     # Protéger la liste actuelle des variables en en faisant une copie
 | |
|     # locale. En effet, cette liste sera supprimée à la fin de l'invocation
 | |
|     # récursive avec -r. Protéger également les valeurs de variables en en
 | |
|     # faisant une copie locale, puis fusionner avec les valeurs saisies sur la
 | |
|     # ligne de commande.
 | |
|     # Attention! si on veut utiliser dans les paramètre du script dépendant une
 | |
|     # valeur d'une variable déjà définie, il faut utiliser une indirection
 | |
|     # var!=othervar, parce que la valeur définitive est calculée dans cette
 | |
|     # fonction, et non avant son appel!
 | |
|     local __var __tmp
 | |
|     for __var in "${RUNSVARS[@]}"; do
 | |
|         if array_contains RUNSARRAYS "$__var"; then
 | |
|             eval "array_copy __tmp $__var; local -a $__var; array_copy $__var __tmp"
 | |
|         else
 | |
|             eval "set_var __tmp \"\${!__var}\"; local $__var; $__var=\"\$__tmp\""
 | |
|         fi
 | |
|     done
 | |
|     runs_clvars "${RUNSCLVARS[@]}"
 | |
|     runs_indvars
 | |
|     # Etendre tout de suite les indirections var!=othervar et array@=otherarray,
 | |
|     # parce que la valeur qui doit être prise en compte est la valeur actuelle.
 | |
|     local -a __args
 | |
|     local __arg __name __value
 | |
|     __args=("$1"); shift
 | |
|     for __arg in "$@"; do
 | |
|         if [[ "$__arg" == *!=* ]]; then
 | |
|             __name="${__arg%%!=*}"
 | |
|             __value="${__arg#*!=}"
 | |
|             __args=("${__args[@]}" "$__name=$(quoted_arg "${!__value}")")
 | |
|         elif [[ "$__arg" == *@=* ]]; then
 | |
|             __name="${__arg%%@=*}"
 | |
|             __value="${__arg#*@=}[@]"
 | |
|             __args=("${__args[@]}" \; "$__name")
 | |
|             for __var in "${!__value}"; do
 | |
|                 __args=("${__args[@]}" "$__var")
 | |
|             done
 | |
|             __args=("${__args[@]}" \;)
 | |
|         else
 | |
|             __args=("${__args[@]}" "$__arg")
 | |
|         fi
 | |
|     done
 | |
|     set -- "${__args[@]}"
 | |
| 
 | |
|     if [ $runslevel -eq 1 ]; then
 | |
|         # Avec une seule option -r, si le scriptpath a déjà été lancé, on ne
 | |
|         # fait rien. Sinon, le lancer maintenant avec les arguments $2..$*
 | |
|         # Ne pas mettre à jour la ligne de recette lors d'un export pour éviter
 | |
|         # de lancer le script deux fois
 | |
|         local RUNSUPDATERECIPE=
 | |
|         if ! array_contains RUNSSTORY "$1"; then
 | |
|             etitle "Lancement du script dépendant $1" \
 | |
|                 runs_rscriptpath "$@"
 | |
|         fi
 | |
|         return 0
 | |
|     else
 | |
|         # Avec deux options -r et plus, forcer le lancer de scriptpath avec les
 | |
|         # arguments $2..$*, même s'il a déjà été lancé auparavant.
 | |
|         # Ne pas mettre à jour la ligne de recette lors d'un export pour éviter
 | |
|         # de lancer le script deux fois
 | |
|         local RUNSUPDATERECIPE=
 | |
|         etitle "Lancement du script dépendant $1" \
 | |
|             runs_rscriptpath "$@"
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function runs_clvars() {
 | |
|     # Traiter les spécifications de variables données en ligne de commande ou
 | |
|     # dans un fichier de recettes
 | |
|     local __vars
 | |
|     __vars=()
 | |
|     while [ -n "$1" ]; do
 | |
|         if [ "$1" == ";" ]; then
 | |
|             runs_var "${__vars[@]}"
 | |
|             __vars=()
 | |
|         else
 | |
|             __vars=("${__vars[@]}" "$1")
 | |
|         fi
 | |
|         shift
 | |
|     done
 | |
|     [ -n "${__vars[*]}" ] && runs_var "${__vars[@]}"
 | |
| }
 | |
| 
 | |
| function runs_indvars() {
 | |
|     # Résoudre les valeurs effectives des variables qui sont des indirections
 | |
|     local __var __ind
 | |
|     for __var in "${RUNSVARSINDIRECT[@]}"; do
 | |
|         if array_contains RUNSARRAYS "$__var"; then
 | |
|             # tableau
 | |
|             array_copy "$__var" "${!__var}"
 | |
|         else
 | |
|             # variable scalaire
 | |
|             __ind="${!__var}"
 | |
|             set_var "$__var" "${!__ind}"
 | |
|         fi
 | |
|     done
 | |
|     RUNSVARSINDIRECT=()
 | |
| }
 | |
| 
 | |
| function runs_clvars_cmd() {
 | |
|     # écrire la ligne de recette correspondant au script $1 et aux variables
 | |
|     # $2..$*
 | |
|     local __vars __prefix
 | |
|     __vars=()
 | |
|     while [ -n "$1" ]; do
 | |
|         if [ "$1" == ";" ]; then
 | |
|             echo "$__prefix$(quoted_args "${__vars[@]}")"
 | |
|             __vars=()
 | |
|             __prefix="    "
 | |
|         else
 | |
|             __vars=("${__vars[@]}" "$1")
 | |
|         fi
 | |
|         shift
 | |
|     done
 | |
|     [ -n "${__vars[*]}" ] && echo "$__prefix$(quoted_args "${__vars[@]}")"
 | |
| }
 | |
| 
 | |
| function runs_loadconfs() {
 | |
|     local __conffile __path __done
 | |
|     RUNSCONFFILES=()
 | |
|     if [ -n "$RUNSDIR" ]; then
 | |
|         __path="$RUNSSCRIPT"
 | |
|         while [ -n "$__path" ]; do
 | |
|             __path="$(dirname "$__path")"
 | |
|             __conffile="$__path/runs.conf"
 | |
|             if [ -f "$__conffile" ]; then
 | |
|                 RUNSCONFFILES=("$__conffile" "${RUNSCONFFILES[@]}")
 | |
|             fi
 | |
|             [ "$__path" == "$RUNSDIR" ] && __path=
 | |
|         done
 | |
|     fi
 | |
| 
 | |
|     for __conffile in "${RUNSCONFFILES[@]}"; do
 | |
|         source "$__conffile"
 | |
|     done
 | |
| }
 | |
| 
 | |
| function runs_clearvars() {
 | |
|     local __var
 | |
|     for __var in "${RUNSVARS[@]}"; do
 | |
|         eval "unset $__var"
 | |
|     done
 | |
| }
 | |
| 
 | |
| function runs_action_desc() {
 | |
|     local -a RUNSVARS RUNSARRAYS RUNSVARSINDIRECT
 | |
|     local -a RUNSCLVARS RUNSCONFS RUNSCONFFILES
 | |
|     local RUNSVARDESC __state
 | |
| 
 | |
|     function desc() { eecho "$(ppath "$RUNSSCRIPT"): $*"; exit 0; }
 | |
|     function unsupported_system() { runs_unsupported_system "$@"; }
 | |
|     function require_sysinfos() { runs_require_sysinfos "$@"; }
 | |
|     function vardesc() { RUNSVARDESC="$*"; }
 | |
|     function var() { runs_var "$@"; RUNSVARDESC=; }
 | |
|     function conf() { runs_conf "$@"; }
 | |
|     function after() {
 | |
|         local scriptpath
 | |
|         for scriptpath in "$@"; do
 | |
|             einfo "Ce script doit être lancé après $scriptpath"
 | |
|         done
 | |
|     }
 | |
|     function ref() {
 | |
|         local -a __args
 | |
|         parse_opts + \
 | |
|             -s:,--sconf: '$:' \
 | |
|             -V:,--refvar: '$:' \
 | |
|             -v:,--vars: '$:' \
 | |
|             -l:,--lconf: '$:' \
 | |
|             @ __args -- "$@" && set -- "${__args[@]}" || die "$__args"
 | |
|         runs_var "$@"
 | |
|         RUNSVARDESC=
 | |
|         local __name __value; __runs_splitref "$1" __name __value
 | |
|         array_add RUNSREFS "$__name"
 | |
|     }
 | |
|     function indref() { runs_indref "$@"; }
 | |
|     function refcerts() { runs_refcerts "$@"; }
 | |
|     function refapacheconfig() { runs_refapacheconfig "$@"; }
 | |
|     function out() { runs_var "$@"; }
 | |
|     function script:() {
 | |
|         eecho "(pas de description)"
 | |
|         exit 0
 | |
|     }
 | |
| 
 | |
|     runs_check_runsscript "$RUNSSCRIPT" || die
 | |
|     runs_loadconfs
 | |
|     (source "$RUNSSCRIPT"); __state=$?
 | |
|     runs_clearvars
 | |
|     return $__state
 | |
| }
 | |
| 
 | |
| function runs_action_dump() {
 | |
|     local -a RUNSVARS RUNSARRAYS RUNSVARSINDIRECT
 | |
|     local -a RUNSCLVARS RUNSCONFS RUNSCONFFILES
 | |
|     local RUNSVARDESC __state
 | |
| 
 | |
|     RUNSCLVARS=("$@")
 | |
| 
 | |
|     function desc() { eecho "$(ppath "$RUNSSCRIPT"): $*"; }
 | |
|     function unsupported_system() { runs_unsupported_system "$@"; }
 | |
|     function require_sysinfos() { runs_require_sysinfos "$@"; }
 | |
|     function vardesc() { RUNSVARDESC="$*"; }
 | |
|     function var() { runs_var "$@"; RUNSVARDESC=; }
 | |
|     function conf() { runs_conf "$@"; }
 | |
|     function after() { :; }
 | |
|     function ref() {
 | |
|         local -a __args
 | |
|         parse_opts + \
 | |
|             -s:,--sconf: '$:' \
 | |
|             -V:,--refvar: '$:' \
 | |
|             -v:,--vars: '$:' \
 | |
|             -l:,--lconf: '$:' \
 | |
|             @ __args -- "$@" && set -- "${__args[@]}" || die "$__args"
 | |
|         runs_var "$@"
 | |
|         RUNSVARDESC=
 | |
|         local __name __value; __runs_splitref "$1" __name __value
 | |
|         array_add RUNSREFS "$__name"
 | |
|     }
 | |
|     function indref() { runs_indref "$@"; }
 | |
|     function refcerts() { runs_refcerts "$@"; }
 | |
|     function refapacheconfig() { runs_refapacheconfig "$@"; }
 | |
|     function out() { runs_var "$@"; }
 | |
|     function script:() {
 | |
|         runs_set_lang
 | |
|         runs_set_proxy
 | |
|         runs_clvars "${RUNSCLVARS[@]}"
 | |
|         runs_indvars
 | |
| 
 | |
|         local __var __desc __values __count
 | |
|         for __var in "${RUNSVARS[@]}"; do
 | |
|             __desc="RUNSVARDESC_$__var"
 | |
|             [ -n "${!__desc}" ] && eecho "${COULEUR_BLEUE}$__var${COULEUR_NORMALE}: ${!__desc}"
 | |
| 
 | |
|             __values="$__var[@]"
 | |
|             eval "__count=\"\${#$__var[@]}\""
 | |
|             if [ "$__count" -eq 1 ]; then
 | |
|                 # variable scalaire
 | |
|                 eecho "$__var=$(quoted_args "${!__values}")"
 | |
|             else
 | |
|                 # variable tableau
 | |
|                 eecho "$__var=($(quoted_args "${!__values}"))"
 | |
|             fi
 | |
|         done
 | |
|         exit 0
 | |
|     }
 | |
| 
 | |
|     runs_check_runsscript "$RUNSSCRIPT" || die
 | |
|     runs_loadconfs
 | |
|     (source "$RUNSSCRIPT"); __state=$?
 | |
|     runs_clearvars
 | |
|     return $__state
 | |
| }
 | |
| 
 | |
| function runs_action_run() {
 | |
|     local -a RUNSVARS RUNSARRAYS RUNSVARSINDIRECT
 | |
|     local -a RUNSCLVARS RUNSCONFS RUNSCONFFILES
 | |
|     local RUNSVARDESC __state
 | |
| 
 | |
|     RUNSCLVARS=("$@")
 | |
| 
 | |
|     function desc() { :; }
 | |
|     function unsupported_system() { runs_unsupported_system "$@"; }
 | |
|     function require_sysinfos() { runs_require_sysinfos "$@"; }
 | |
|     function vardesc() { RUNSVARDESC="$*"; }
 | |
|     function var() { runs_var "$@"; RUNSVARDESC=; }
 | |
|     function conf() { runs_conf "$@"; }
 | |
|     function after() { runs_after "$@" || exit 1; }
 | |
|     function ref() {
 | |
|         local -a __args
 | |
|         local __ref __name __value __found __required __rdir __rfile __rsconf
 | |
|         local __shellconfs __shellconf __refvarname=refdir __refvar
 | |
|         local __tmpconf __wildconf
 | |
|         # ignorer les options -v, -l et leur argument
 | |
|         parse_opts + \
 | |
|             -r,--required,-m,--mandatory __required=1 \
 | |
|             -f,--required-file '$__required=1; __rfile=1' \
 | |
|             -d,--required-dir '$__required=1; __rdir=1' \
 | |
|             -s:,--sconf: __shellconf= \
 | |
|             --rs,--rsconf,--required-sconf __rsconf=1 \
 | |
|             -V:,--refvar: __refvarname= \
 | |
|             -v:,--vars: '$:' \
 | |
|             -l:,--lconf: '$:' \
 | |
|             @ __args -- "$@" && set -- "${__args[@]}" || die "$__args"
 | |
| 
 | |
|         if [ -n "$__shellconf" ]; then
 | |
|             splitwcs "$__shellconf" __tmpconf __wildconf
 | |
|             [ -n "$__wildconf" ] && __shellconf="$__tmpconf"
 | |
|             if [ -e "$__shellconf" -a "${__shellconf#/}" != "$__shellconf" ]; then
 | |
|                 # un chemin absolu _existant_, le garder tel quel
 | |
|                 :
 | |
|             elif withpath "$__shellconf" && [ -e "$RUNSSCRIPTDIR/$__shellconf" ]; then
 | |
|                 # d'abord dans le répertoire du script
 | |
|                 __shellconf="$RUNSSCRIPTDIR/$__shellconf"
 | |
|             elif __tmpconf="$(runs_find_datafile "$__shellconf" "" "$RUNSSCRIPTDIR")"; then
 | |
|                 # puis chercher dans RUNS*DIRS
 | |
|                 __shellconf="$__tmpconf"
 | |
|             fi
 | |
|             if [ ! -e "$__shellconf" ]; then
 | |
|                 if [ -n "$__rsconf" ]; then
 | |
|                     die "$__shellconf: fichier introuvable"
 | |
|                 else
 | |
|                     ewarn "$__shellconf: fichier introuvable"
 | |
|                 fi
 | |
|             fi
 | |
|             [ -n "$__wildconf" ] && __shellconf="$__shellconf/$__wildconf"
 | |
| 
 | |
|             if [ -z "$*" ]; then
 | |
|                 # Si aucun argument n'est spécifié, essayer de prendre la
 | |
|                 # configuration dans le fichier $__shellconf
 | |
| 
 | |
|                 __runs_check_varname "$__refvarname" || die
 | |
|                 set_var "$__refvarname" ""
 | |
| 
 | |
|                 splitwcs "$__shellconf" __tmpconf __wildconf
 | |
|                 if [ -n "$__wildconf" ]; then
 | |
|                     array_lsall __shellconfs "$__tmpconf" "$__wildconf"
 | |
|                 else
 | |
|                     __shellconfs=("$__shellconf")
 | |
|                 fi
 | |
|                 __args=()
 | |
|                 for __tmpconf in "${__shellconfs[@]}"; do
 | |
|                     [ -f "$__tmpconf" ] || {
 | |
|                         eerror "$__tmpconf: fichier introuvable. Il a été ignoré"
 | |
|                         continue
 | |
|                     }
 | |
|                     __refvar="$(source "$__tmpconf"; echo "${!__refvarname}")"
 | |
|                     __args=("${__args[@]}" "$__refvarname=$__refvar")
 | |
|                 done
 | |
|                 set -- "${__args[@]}"
 | |
|             fi
 | |
|         fi
 | |
| 
 | |
|         for __ref in "$@"; do
 | |
|             __runs_splitref "$__ref" __name __value
 | |
|             if __runs_check_varname "$__name"; then
 | |
|                 __found=
 | |
|                 if [ "${__value#/}" != "$__value" ]; then
 | |
|                     # un chemin absolu. corriger éventuellement avec RUNSROOTDIR
 | |
|                     # s'il existe, le garder tel quel
 | |
|                     if [ -n "$RUNSROOTDIR" ]; then
 | |
|                         # corriger le chemin à partir de RUNSROOTDIR
 | |
|                         __value="$RUNSROOTDIR$__value"
 | |
|                     fi
 | |
|                     [ -e "$__value" ] && __found=1
 | |
|                 fi
 | |
|                 if [ -z "$__found" ]; then
 | |
|                     if withpath "$__value" && [ -e "$RUNSSCRIPTDIR/$__value" ]; then
 | |
|                         # d'abord dans le répertoire du script
 | |
|                         __value="$RUNSSCRIPTDIR/$__value"
 | |
|                     elif [ -e "$RUNSWORKDIR/$__value" ]; then
 | |
|                         # ensuite dans le répertoire partagé
 | |
|                         __value="$RUNSWORKDIR/$__value"
 | |
|                     else
 | |
|                         # puis chercher dans RUNS*DIRS
 | |
|                         local __file
 | |
|                         if __file="$(runs_find_datafile "$__value" "" "$RUNSSCRIPTDIR")"; then
 | |
|                             __value="$__file"
 | |
|                         elif [ -z "$__required" ]; then
 | |
|                             # par défaut, prendre dans le répertoire partagé
 | |
|                             __value="$RUNSWORKDIR/$__value"
 | |
|                         else
 | |
|                             die "Le fichier $__value ($__name) est requis"
 | |
|                         fi
 | |
|                     fi
 | |
|                 fi
 | |
|                 [ -z "$__rfile" -o -f "$__value" ] || die "Le fichier $__value ($__name) est requis"
 | |
|                 [ -z "$__rdir" -o -d "$__value" ] || die "Le répertoire $__value ($__name) est requis"
 | |
| 
 | |
|                 runs_var "$__name=$__value"
 | |
|                 RUNSVARDESC=
 | |
|                 array_add RUNSREFS "$__name"
 | |
|             fi
 | |
|         done
 | |
|     }
 | |
|     function indref() { runs_indref "$@"; }
 | |
|     function refcerts() { runs_refcerts "$@"; }
 | |
|     function refapacheconfig() { runs_refapacheconfig "$@"; }
 | |
|     function out() {
 | |
|         for __out in "$@"; do
 | |
|             if [[ "$__out" == *=* ]]; then
 | |
|                 __name="${__out%%=*}"
 | |
|                 __value="${__out#*=}"
 | |
|             else
 | |
|                 __name="$__out"
 | |
|                 __value="$__out"
 | |
|             fi
 | |
|             if __runs_check_varname "$__name"; then
 | |
|                 __value="$RUNSWORKDIR/$__value"
 | |
|                 runs_var "$__name=$__value"
 | |
| 
 | |
|                 mkdirof "$__value"
 | |
|                 >"$__value" # s'assurer que le fichier est vide
 | |
|             fi
 | |
|         done
 | |
|     }
 | |
|     function script:() {
 | |
|         runs_set_lang
 | |
|         runs_set_proxy
 | |
|         runs_clvars "${RUNSCLVARS[@]}"
 | |
|         runs_indvars
 | |
|         runs_check_confs
 | |
|     }
 | |
| 
 | |
|     runs_check_runsscript "$RUNSSCRIPT" || die
 | |
|     runs_loadconfs
 | |
|     if [ -d "$RUNSSCRIPT" ]; then
 | |
|         # installer le répertoire avec uinst 
 | |
|         # les variables sont passées en ligne de commande, et les tableau sont
 | |
|         # transformés en chaine avec chaque élément séparés par ':'
 | |
|         (
 | |
|             runs_clvars "${RUNSCLVARS[@]}"
 | |
|             runs_indvars
 | |
|             for __name in "${RUNSVARS[@]}"; do
 | |
|                 __value="$(array_join "$__name" ":")"
 | |
|                 __vars=("${__vars[@]}" "$(set_var_cmd "$__name" "$__value")")
 | |
|             done
 | |
| 
 | |
|             urequire uinst udir prefixes uinc
 | |
|             # Il faut définir UINST, chemin vers le script uinst.
 | |
|             UINST="$RUNSSRCDIR/uinst"
 | |
|             uinst $(get_interaction_option) $(get_verbosity_option) \
 | |
|                 "$RUNSSCRIPT" "${__vars[@]}"
 | |
|         ); __state=$?
 | |
|     else
 | |
|         # lancer le script avec le protocole runs
 | |
|         (source "$RUNSSCRIPT"); __state=$?
 | |
|     fi
 | |
|     runs_clearvars
 | |
|     return $__state
 | |
| }
 | |
| 
 | |
| function runs_action_export() {
 | |
|     local -a RUNSVARS RUNSARRAYS RUNSVARSINDIRECT
 | |
|     local -a RUNSCLVARS RUNSCONFS RUNSCONFFILES
 | |
|     local RUNSVARDESC __state
 | |
| 
 | |
|     RUNSCLVARS=("$@")
 | |
| 
 | |
|     function desc() { :; }
 | |
|     function unsupported_system() { runs_unsupported_system "$@"; }
 | |
|     function require_sysinfos() { runs_require_sysinfos "$@"; }
 | |
|     function vardesc() { RUNSVARDESC="$*"; }
 | |
|     function var() { runs_var "$@"; RUNSVARDESC=; }
 | |
|     function conf() { runs_conf "$@"; }
 | |
|     function after() { runs_after "$@" || exit 1; }
 | |
|     function ref() {
 | |
|         local -a __args
 | |
|         local __ref __name __value __copy __required __rdir __rfile __rsconf
 | |
|         local __shellconfs __shellconf __refvarname=refdir __refvar __shellvars
 | |
|         local __lineconfs __lineconf
 | |
|         local __tmpconf __wildconf
 | |
|         parse_opts + \
 | |
|             -r,--required,-m,--mandatory __required=1 \
 | |
|             -f,--required-file '$__required=1; __rfile=1' \
 | |
|             -d,--required-dir '$__required=1; __rdir=1' \
 | |
|             -s:,--sconf: __shellconf= \
 | |
|             --rs,--rsconf,--required-sconf __rsconf=1 \
 | |
|             -V:,--refvar: __refvarname= \
 | |
|             -v:,--vars: __shellvars= \
 | |
|             -l:,--lconf: __lineconf= \
 | |
|             @ __args -- "$@" && set -- "${__args[@]}" || die "$__args"
 | |
| 
 | |
|         if [ -n "$__shellconf" ]; then
 | |
|             splitwcs "$__shellconf" __tmpconf __wildconf
 | |
|             [ -n "$__wildconf" ] && __shellconf="$__tmpconf"
 | |
|             if [ -e "$__shellconf" -a "${__shellconf#/}" != "$__shellconf" ]; then
 | |
|                 # un chemin absolu _existant_, le garder tel quel
 | |
|                 :
 | |
|             elif withpath "$__shellconf" && [ -e "$RUNSSCRIPTDIR/$__shellconf" ]; then
 | |
|                 # d'abord dans le répertoire du script
 | |
|                 __shellconf="$RUNSSCRIPTDIR/$__shellconf"
 | |
|             elif __tmpconf="$(runs_find_datafile "$__shellconf" "" "$RUNSSCRIPTDIR")"; then
 | |
|                 # puis chercher dans RUNS*DIRS
 | |
|                 __shellconf="$__tmpconf"
 | |
|             fi
 | |
|             if [ ! -e "$__shellconf" ]; then
 | |
|                 if [ -n "$__rsconf" ]; then
 | |
|                     die "$__shellconf: fichier introuvable"
 | |
|                 else
 | |
|                     ewarn "$__shellconf: fichier introuvable"
 | |
|                 fi
 | |
|             fi
 | |
|             [ -n "$__wildconf" ] && __shellconf="$__shellconf/$__wildconf"
 | |
|             [ -n "$__lineconf" ] && ewarn "L'option -s étant spécifiée, l'option -l a été ignorée"
 | |
| 
 | |
|             if [ -z "$*" ]; then
 | |
|                 # Si aucun argument n'est spécifié, essayer de prendre la
 | |
|                 # configuration dans le fichier $__shellconf
 | |
| 
 | |
|                 __runs_check_varname "$__refvarname" || die
 | |
|                 set_var "$__refvarname" ""
 | |
| 
 | |
|                 splitwcs "$__shellconf" __tmpconf __wildconf
 | |
|                 if [ -n "$__wildconf" ]; then
 | |
|                     array_lsall __shellconfs "$__tmpconf" "$__wildconf"
 | |
|                 else
 | |
|                     __shellconfs=("$__shellconf")
 | |
|                 fi
 | |
|                 __args=()
 | |
|                 for __tmpconf in "${__shellconfs[@]}"; do
 | |
|                     [ -f "$__tmpconf" ] || {
 | |
|                         eerror "$__tmpconf: fichier introuvable. Il a été ignoré"
 | |
|                         continue
 | |
|                     }
 | |
|                     __refvar="$(source "$__tmpconf"; echo "${!__refvarname}")"
 | |
|                     __args=("${__args[@]}" "$__refvarname=$__refvar")
 | |
|                 done
 | |
|                 set -- "${__args[@]}"
 | |
|             fi
 | |
| 
 | |
|         elif [ -n "$__lineconf" ]; then
 | |
|             splitwcs "$__lineconf" __tmpconf __wildconf
 | |
|             [ -n "$__wildconf" ] && __lineconf="$__tmpconf"
 | |
|             if [ -e "$__lineconf" -a "${__lineconf#/}" != "$__lineconf" ]; then
 | |
|                 # un chemin absolu _existant_, le garder tel quel
 | |
|                 :
 | |
|             elif withpath "$__lineconf" && [ -e "$RUNSSCRIPTDIR/$__lineconf" ]; then
 | |
|                 # d'abord dans le répertoire du script
 | |
|                 __lineconf="$RUNSSCRIPTDIR/$__lineconf"
 | |
|             elif __tmpconf="$(runs_find_datafile "$__lineconf" "" "$RUNSSCRIPTDIR")"; then
 | |
|                 # puis chercher dans RUNS*DIRS
 | |
|                 __lineconf="$__tmpconf"
 | |
|             fi
 | |
|             [ -e "$__lineconf" ] || die "$__lineconf: fichier introuvable"
 | |
|             [ -n "$__wildconf" ] && __lineconf="$__lineconf/$__wildconf"
 | |
|         fi
 | |
|         if [ -n "$__rfile" ]; then
 | |
|             [ -n "$__shellconf" -o -n "$__lineconf" ] && die "-f est incompatible avec -s et -l"
 | |
|         fi
 | |
| 
 | |
|         for __ref in "$@"; do
 | |
|             if [ -n "$__shellconf" -a -z "$__shellvars" ]; then
 | |
|                 ewarn "L'option -v n'a pas été spécifiée pour $__ref"
 | |
|             fi
 | |
|             __copy=1
 | |
|             __runs_splitref "$__ref" __name __value
 | |
|             if __runs_check_varname "$__name"; then
 | |
|                 if [ -e "$__value" -a "${__value#/}" != "$__value" ]; then
 | |
|                     # un chemin absolu _existant_, le garder tel quel
 | |
|                     :
 | |
|                 elif withpath "$__value" && [ -e "$RUNSSCRIPTDIR/$__value" ]; then
 | |
|                     # d'abord dans le répertoire du script
 | |
|                     __value="$RUNSSCRIPTDIR/$__value"
 | |
|                 elif [ -e "$RUNSWORKDIR/$__value" ]; then
 | |
|                     # puis dans le répertoire partagé
 | |
|                     __value="$RUNSWORKDIR/$__value"
 | |
|                     __copy=
 | |
|                 else
 | |
|                     # puis chercher dans RUNS*DIRS
 | |
|                     local __file
 | |
|                     if __file="$(runs_find_datafile "$__value" "" "$RUNSSCRIPTDIR")"; then
 | |
|                         __value="$__file"
 | |
|                     elif [ -z "$__required" ]; then
 | |
|                         # par défaut, prendre dans le répertoire partagé
 | |
|                         __value="$RUNSWORKDIR/$__value"
 | |
|                         __copy=
 | |
|                     else
 | |
|                         die "Le fichier $__value ($__name) est requis"
 | |
|                     fi
 | |
|                 fi
 | |
|                 [ -z "$__rfile" -o -f "$__value" ] || die "Le fichier $__value ($__name) est requis"
 | |
|                 [ -z "$__rdir" -o -d "$__value" ] || die "Le répertoire $__value ($__name) est requis"
 | |
| 
 | |
|                 runs_var "$__name=$__value"
 | |
|                 RUNSVARDESC=
 | |
|                 array_add RUNSREFS "$__name"
 | |
| 
 | |
|                 if [ -n "$__copy" ]; then
 | |
|                     if [ -n "$__shellconf" ]; then
 | |
|                         # copier les fichiers mentionnés dans le fichier de
 | |
|                         # configuration, d'après les valeurs de __shellvars
 | |
|                         estep "Vérification du répertoire $(ppath "$__value")"
 | |
|                         mkdirof "$RUNSROOTDIR$__value"
 | |
|                         if [ -n "$__shellvars" ]; then
 | |
|                             (
 | |
|                                 __CPNOVCS_RSYNC_ARGS=(--copy-unsafe-links)
 | |
|                                 array_split __shellvars "$__shellvars" ,
 | |
|                                 splitwcs "$__shellconf" __tmpconf __wildconf
 | |
|                                 if [ -n "$__wildconf" ]; then
 | |
|                                     array_lsall __shellconfs "$__tmpconf" "$__wildconf"
 | |
|                                 else
 | |
|                                     __shellconfs=("$__shellconf")
 | |
|                                 fi
 | |
|                                 for __shellconf in "${__shellconfs[@]}"; do
 | |
|                                     estep "Dans $(ppath "$__shellconf")"
 | |
|                                     for __shellvar in "${__shellvars[@]}"; do
 | |
|                                         # s'assurer que la variables sont vides
 | |
|                                         # avant de sourcer $__shellconf
 | |
|                                         set_var "$__shellvar"
 | |
|                                     done
 | |
|                                     source "$__shellconf"
 | |
|                                     for __shellvar in "${__shellvars[@]}"; do
 | |
|                                         [ -n "${!__shellvar}" ] || continue
 | |
|                                         estep "... Copie de ${!__shellvar}"
 | |
|                                         cpnovcs "$__value/${!__shellvar}" "$(dirname "$RUNSROOTDIR$__value/${!__shellvar}")"
 | |
|                                     done
 | |
|                                 done
 | |
|                             )
 | |
|                         fi
 | |
|                     elif [ -n "$__lineconf" ]; then
 | |
|                         # copier les fichiers mentionnés dans le fichier de
 | |
|                         # configuration, à raison de un par ligne
 | |
|                         estep "Vérification du répertoire $(ppath "$__value")"
 | |
|                         mkdirof "$RUNSROOTDIR$__value"
 | |
|                         (
 | |
|                             __CPNOVCS_RSYNC_ARGS=(--copy-unsafe-links)
 | |
|                             splitwcs "$__lineconf" __tmpconf __wildconf
 | |
|                             if [ -n "$__wildconf" ]; then
 | |
|                                 array_lsall __lineconfs "$__tmpconf" "$__wildconf"
 | |
|                             else
 | |
|                                 __lineconfs=("$__lineconf")
 | |
|                             fi
 | |
|                             for __lineconf in "${__lineconfs[@]}"; do
 | |
|                                 estep "Dans $(ppath "$__lineconf")"
 | |
|                                 array_from_lines __relpaths "$(<"$__lineconf" filter_conf)"
 | |
|                                 for __relpath in "${__relpaths[@]}"; do
 | |
|                                     estep "... Copie de $__relpath"
 | |
|                                     cpnovcs "$__value/$__relpath" "$(dirname "$RUNSROOTDIR$__value/$__relpath")"
 | |
|                                 done
 | |
|                             done
 | |
|                         )
 | |
|                     elif [ ! -e "$RUNSROOTDIR$__value" ]; then
 | |
|                         # copie standard
 | |
|                         estep "Copie de $(ppath "$__value")"
 | |
|                         mkdirof "$RUNSROOTDIR$__value"
 | |
|                         cpnovcs "$__value" "$(dirname "$RUNSROOTDIR$__value")"
 | |
|                     fi
 | |
|                 fi
 | |
|             fi
 | |
|         done
 | |
|     }
 | |
|     function indref() { runs_indref "$@"; }
 | |
|     function refcerts() { runs_refcerts "$@"; }
 | |
|     function refapacheconfig() { runs_refapacheconfig "$@"; }
 | |
|     function out() {
 | |
|         for __out in "$@"; do
 | |
|             if [[ "$__out" == *=* ]]; then
 | |
|                 __name="${__out%%=*}"
 | |
|                 __value="${__out#*=}"
 | |
|             else
 | |
|                 __name="$__out"
 | |
|                 __value="$__out"
 | |
|             fi
 | |
|             if __runs_check_varname "$__name"; then
 | |
|                 __value="$RUNSWORKDIR/$__value"
 | |
|                 runs_var "$__name=$__value"
 | |
| 
 | |
|                 mkdirof "$__value"
 | |
|                 >"$__value" # s'assurer que le fichier est vide
 | |
|             fi
 | |
|         done
 | |
|     }
 | |
|     function script:() {
 | |
|         runs_set_lang
 | |
|         runs_set_proxy
 | |
|         runs_clvars "${RUNSCLVARS[@]}"
 | |
|         runs_indvars
 | |
| 
 | |
|         local __recipe
 | |
|         if array_contains RUNSCONFS local; then
 | |
|             if array_contains RUNSCONFS root; then
 | |
|                 __recipe="$RUNSEXPORTDIR/localroot"
 | |
|             else
 | |
|                 __recipe="$RUNSEXPORTDIR/localuser"
 | |
|             fi
 | |
|         else
 | |
|             __recipe="$RUNSEXPORTDIR/remote"
 | |
|             if array_contains RUNSCONFS root; then
 | |
|                 touch "$RUNSEXPORTDIR/remote-needs-root"
 | |
|             fi
 | |
|         fi
 | |
|         if [ -n "$RUNSUPDATERECIPE" ]; then
 | |
|             estep "Ajout de la ligne de recette"
 | |
|             runs_clvars_cmd "$RUNSSCRIPTPATH" "${RUNSCLVARS[@]}" >>"$__recipe"
 | |
|         fi
 | |
| 
 | |
|         if [ ! -e "$RUNSROOTDIR$RUNSSCRIPT" ]; then
 | |
|             estep "Copie du script"
 | |
|             mkdirof "$RUNSROOTDIR$RUNSSCRIPT"
 | |
|             cpnovcs "$RUNSSCRIPT" "$(dirname "$RUNSROOTDIR$RUNSSCRIPT")"
 | |
|         fi
 | |
|         exit 0
 | |
|     }
 | |
| 
 | |
|     runs_check_runsscript "$RUNSSCRIPT" || die
 | |
|     runs_loadconfs
 | |
| 
 | |
|     local __conffile
 | |
|     for __conffile in "${RUNSCONFFILES[@]}"; do
 | |
|         if [ ! -e "$RUNSROOTDIR$__conffile" ]; then
 | |
|             estep "Copie de $(ppath "$__conffile")"
 | |
|             mkdirof "$RUNSROOTDIR$__conffile"
 | |
|             cpnovcs "$__conffile" "$(dirname "$RUNSROOTDIR$__conffile")"
 | |
|         fi
 | |
|     done
 | |
| 
 | |
|     if [ -d "$RUNSSCRIPT" ]; then
 | |
|         # le répertoire sera installé avec uinst 
 | |
|         if [ -n "$RUNSUPDATERECIPE" ]; then
 | |
|             estep "Ajout de la ligne de recette"
 | |
|             runs_clvars_cmd "$RUNSSCRIPTPATH" "${RUNSCLVARS[@]}" >>"$RUNSEXPORTDIR/remote"
 | |
|         fi
 | |
|         
 | |
|         if [ ! -e "$RUNSROOTDIR$RUNSSCRIPT" ]; then
 | |
|             estep "Copie des fichiers"
 | |
|             mkdir -p "$RUNSROOTDIR$RUNSSCRIPT" || return 1
 | |
|             cpdirnovcs "$RUNSSCRIPT" "$RUNSROOTDIR$RUNSSCRIPT" || return 1
 | |
|         fi
 | |
|     else
 | |
|         # le script sera lancé avec le protocole runs
 | |
|         (source "$RUNSSCRIPT") || return 1
 | |
|     fi
 | |
|     runs_clearvars
 | |
|     return 0
 | |
| }
 | |
| 
 | |
| ################################################################################
 | |
| # Les fonctions de cette section permettent de maintenir des informations sur
 | |
| # des opérations _effectuées avec l'utilisateur root_. Cela permet à un script de
 | |
| # savoir s'il a déjà été lancé. Le code typique sera celui-ci:
 | |
| #   shouldrun || exit
 | |
| #   ...
 | |
| #   setdone
 | |
| # Les informations sont stockées sur la machine cible dans /var/lib/runs.state
 | |
| 
 | |
| if is_root; then
 | |
|     RUNSSTATE_FILE=/var/lib/runs.state
 | |
| else
 | |
|     RUNSSTATE_FILE="$HOME/etc/runs.state"
 | |
| fi
 | |
| RUNSSTATE_LASTKEY=
 | |
| RUNSSTATE_LASTVALUE=
 | |
| # Vérifier que la clé $1 existe dans $RUNSSTATE_FILE, et si $2!="", qu'elle
 | |
| # existe avec la valeur $2. Si la clé existe, retourner faux (il ne faut pas
 | |
| # lancer le script).
 | |
| # Si $RUNSRESET est vrai, toujours retourner vrai. Ceci permet de forcer
 | |
| # l'installation pour un script
 | |
| # La clé est toujours automatiquement préfixée de $3(=$RUNSSCRIPTPATH)
 | |
| function shouldrun() {
 | |
|     [ -f "$RUNSSTATE_FILE" ] || return 0
 | |
|     is_yes "$RUNSRESET" && return 0
 | |
|     local key="${3:-$RUNSSCRIPTPATH}${1:+-$1}"
 | |
|     if ! quietgrep "^$key:$2" "$RUNSSTATE_FILE"; then
 | |
|         RUNSSTATE_LASTKEY="$1"
 | |
|         RUNSSTATE_LASTVALUE="$2"
 | |
|         return 0
 | |
|     else
 | |
|         return 1
 | |
|     fi
 | |
| }
 | |
| # Pour le script de chemin scriptpath $1, vérifier que la clé $2 existe dans
 | |
| # $RUNSSTATE_FILE, et si $3!="", qu'elle existe avec la valeur $3.
 | |
| # Cette fonction permet de ne lancer un traitement que si un autre script a été
 | |
| # lancé auparavant avec succès
 | |
| function checkdone() {
 | |
|     [ -n "$1" ] || return 1
 | |
|     [ -f "$RUNSSTATE_FILE" ] || return 1
 | |
|     local key="$1${1:+-$2}" value="$3"
 | |
|     quietgrep "^$key:$value" "$RUNSSTATE_FILE"
 | |
| }
 | |
| # Comme checkdone(), mais si la clé n'existe pas, afficher un message d'erreur
 | |
| # et quitter le script
 | |
| function requiredone() {
 | |
|     if ! checkdone "$@"; then
 | |
|         msg="Ce script requière que le script dépendant $1"
 | |
|         if [ -n "$2" ]; then
 | |
|             msg="${msg} soit dans l'état $2=${3:-done}"
 | |
|         else
 | |
|             msg="${msg} aie été installé avec succès"
 | |
|         fi
 | |
|         die "$msg.
 | |
| Pour résoudre ce problème, vous pouvez essayer de relancer le script dépendant"
 | |
|     fi
 | |
| }
 | |
| # Ajouter la clé $1 avec la valeur $2(=done) dans $RUNSSTATE_FILE si elle n'y
 | |
| # existe pas déjà. Si $1 est vide, prendre par défaut la dernière clé utilisée
 | |
| # avec shouldrun()
 | |
| # La clé est toujours automatiquement préfixée de $3(=$RUNSSCRIPTPATH)
 | |
| function setdone() {
 | |
|     local key="$1" value="$2"
 | |
|     [ -n "$key" ] || key="$RUNSSTATE_LASTKEY"
 | |
|     [ -n "$value" ] || value="$RUNSSTATE_LASTVALUE"
 | |
|     key="${3:-$RUNSSCRIPTPATH}${key:+-$key}"
 | |
|     [ -n "$value" ] || value=done
 | |
| 
 | |
|     local line="$key:$value"
 | |
|     mkdirof "$RUNSSTATE_FILE"
 | |
|     [ -f "$RUNSSTATE_FILE" ] || touch "$RUNSSTATE_FILE"
 | |
|     if ! quietgrep "^$line" "$RUNSSTATE_FILE"; then
 | |
|         echo "$line" >>"$RUNSSTATE_FILE"
 | |
|     fi
 | |
|     RUNSSTATE_LASTKEY=
 | |
|     RUNSSTATE_LASTVALUE=
 | |
| }
 | |
| # Supprimer toutes les valeurs de la clé $1 dans $RUNSSTATE_FILE
 | |
| # La clé est toujours automatiquement préfixée de $2(=$RUNSSCRIPTPATH)
 | |
| function resetdone() {
 | |
|     local key="${2:-$RUNSSCRIPTPATH}${1:+-$1}"
 | |
|     [ -n "$key" ] || return
 | |
|     [ -f "$RUNSSTATE_FILE" ] || return
 | |
|     sedi "/^${key//\//\\/}:/d" "$RUNSSTATE_FILE"
 | |
| }
 |