2017-09-13 08:13:11 +04:00
|
|
|
##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
|
|
|
## Gestion de fichiers de configuration et de répertoires de configuration
|
|
|
|
##@cooked nocomments
|
2017-09-14 08:28:40 +04:00
|
|
|
uprovide multiconf
|
2017-09-14 23:11:26 +04:00
|
|
|
urequire install
|
2017-09-13 08:13:11 +04:00
|
|
|
|
|
|
|
function conf_local() {
|
|
|
|
# afficher les commandes pour définir comme locales les variables utilisées
|
|
|
|
# par les fonctions conf_*
|
2017-09-14 21:51:23 +04:00
|
|
|
# cela permet d'utiliser ces fonctions à l'intérieur d'autres fonctions sans
|
|
|
|
# polluer l'espace de nom
|
2017-09-18 11:47:20 +04:00
|
|
|
echo "local -a __CONF_ARRAY_VARS __CONF_PATH_VARS"
|
2017-09-13 08:13:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
function conf_auto() {
|
|
|
|
# charger la configuration pour l'outil $1 avec les variables $2..@
|
|
|
|
# conf_init n'est appelé que si des variables sont spécifiées, ce qui permet
|
|
|
|
# d'appeler conf_init au préalable si une configuration spécifique doit être
|
|
|
|
# faite.
|
|
|
|
# Ainsi:
|
|
|
|
# conf_auto NAME VARS...
|
|
|
|
# est équivalent à:
|
|
|
|
# conf_init VARS...
|
|
|
|
# conf_auto NAME
|
|
|
|
# est équivalent à:
|
|
|
|
# conf_init VARS...
|
2017-09-14 22:21:34 +04:00
|
|
|
# conf_find_files __CONF_FILES ~/etc/default/NAME.conf ~/etc/NAME.d/*.conf
|
|
|
|
# conf_load_files "${__CONF_FILES[@]}"
|
2017-09-14 08:28:40 +04:00
|
|
|
# Pour supporter les scénarii où les fichiers de configuration sont ailleurs
|
|
|
|
# que dans ~/etc/default, l'argument NAME peut être un chemin:
|
|
|
|
# conf_auto PATH/TO/NAME VARS...
|
|
|
|
# est équivalent à:
|
|
|
|
# conf_init VARS...
|
2017-09-14 22:21:34 +04:00
|
|
|
# conf_find_files __CONF_FILES PATH/TO/NAME.conf PATH/TO/NAME.d/*.conf
|
|
|
|
# conf_load_files "${__CONF_FILES[@]}"
|
2017-09-13 08:13:11 +04:00
|
|
|
local __name="$1"; shift
|
|
|
|
[ -n "$__name" ] || return 1
|
|
|
|
[ $# -gt 0 ] && conf_init "$@"
|
|
|
|
local -a __CONF_FILES
|
2017-09-14 21:51:23 +04:00
|
|
|
if [[ "$__name" == */* ]]; then
|
2017-09-14 22:21:34 +04:00
|
|
|
conf_load "$__name.conf" "$__name.d/*.conf"
|
2017-09-14 21:51:23 +04:00
|
|
|
else
|
2017-09-14 22:21:34 +04:00
|
|
|
conf_load "$HOME/etc/default/$__name.conf" "$HOME/etc/$__name.d/*.conf"
|
2017-09-14 21:51:23 +04:00
|
|
|
fi
|
2017-09-13 08:13:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
function conf_init() {
|
2017-09-14 21:51:23 +04:00
|
|
|
# définir les variables attendues lors du chargement des fichiers de
|
2017-09-14 22:21:34 +04:00
|
|
|
# configuration par conf_load_files
|
2017-09-13 08:13:11 +04:00
|
|
|
# par défaut, les variables sont en mode scalaire: la définition d'une
|
|
|
|
# variable écrase la valeur précédente. Avec l'option -a les variables sont
|
|
|
|
# en mode tableau: les nouvelles valeurs sont rajoutées à la fin du tableau.
|
2017-09-18 11:47:20 +04:00
|
|
|
# Avec l'option -p les variables sont en mode chemin: les nouvelles valeurs
|
|
|
|
# sont ajoutées si elles n'existe pas déjà avec le séparateur ':'
|
2017-09-13 08:13:11 +04:00
|
|
|
# dans l'exemple suivant:
|
2017-09-18 11:47:20 +04:00
|
|
|
# conf_init NAME VALUE -a SRCDIRS DESTDIRS -p LIBPATH
|
|
|
|
# NAME et VALUE sont scalaires, SRCDIRS et DESTDIRS sont des tableaux et
|
|
|
|
# LIBPATH est de type chemin
|
|
|
|
# Les variables scalaires et chemin sont initialisées à la valeur vide ou à
|
|
|
|
# la valeur spécifiée e.g.:
|
|
|
|
# conf_init VAR=value MYPATH=a:b:c
|
2017-09-14 21:51:23 +04:00
|
|
|
# Les variables tableaux sont toujours initialisées à la valeur vide
|
2017-09-13 08:13:11 +04:00
|
|
|
# L'option -s permet de revenir au mode scalaire
|
|
|
|
__CONF_ARRAY_VARS=()
|
2017-09-18 11:47:20 +04:00
|
|
|
__CONF_PATH_VARS=()
|
|
|
|
local __var __type=scalar
|
2017-09-13 08:13:11 +04:00
|
|
|
while [ $# -gt 0 ]; do
|
|
|
|
case "$1" in
|
2017-09-18 11:47:20 +04:00
|
|
|
-a|--array) __type=array;;
|
|
|
|
-p|--path) __type=path;;
|
|
|
|
-s|--scalar) __type=scalar;;
|
2017-09-13 08:13:11 +04:00
|
|
|
*)
|
2017-09-18 11:47:20 +04:00
|
|
|
case "$__type" in
|
|
|
|
array)
|
2017-09-14 21:51:23 +04:00
|
|
|
eval "${1%%=*}=()"
|
|
|
|
array_addu __CONF_ARRAY_VARS "${1%%=*}"
|
2017-09-18 11:47:20 +04:00
|
|
|
array_del __CONF_PATH_VARS "${1%%=*}"
|
|
|
|
;;
|
|
|
|
path)
|
2017-09-14 21:51:23 +04:00
|
|
|
setv "$1"
|
2017-09-18 11:47:20 +04:00
|
|
|
array_addu __CONF_PATH_VARS "${1%%=*}"
|
|
|
|
array_del __CONF_ARRAY_VARS "${1%%=*}"
|
|
|
|
;;
|
|
|
|
scalar)
|
|
|
|
setv "$1"
|
|
|
|
;;
|
|
|
|
esac
|
2017-09-13 08:13:11 +04:00
|
|
|
;;
|
|
|
|
esac
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2017-09-14 22:21:34 +04:00
|
|
|
function conf_load() {
|
|
|
|
# charger les fichiers de configuration spécifiés
|
|
|
|
# conf_load SPECS...
|
|
|
|
# est équivalent à:
|
|
|
|
# conf_find_files __CONF_FILES SPECS...
|
|
|
|
# conf_load_files "${__CONF_FILES[@]}"
|
|
|
|
local -a __CONF_FILES
|
|
|
|
conf_find_files __CONFS_FILES "$@"
|
|
|
|
conf_load_files "${__CONFS_FILES[@]}"
|
|
|
|
}
|
|
|
|
|
|
|
|
function conf_find_files() {
|
2017-09-13 08:13:11 +04:00
|
|
|
# initialiser le tableau $1 avec les fichiers de configuration correspondant
|
|
|
|
# aux arguments $2..@
|
|
|
|
# - si on spécifie un fichier, il est pris tel quel s'il existe
|
|
|
|
# - si on spécifie un répertoire, tous les fichiers *.conf de ce répertoire
|
|
|
|
# sont pris
|
|
|
|
# - si on spécifie un pattern e.g path/to/*.conf alors tous les fichiers
|
|
|
|
# correspondant au pattern sont pris
|
|
|
|
# - sinon l'argument est ignoré
|
2017-09-14 21:51:23 +04:00
|
|
|
local __conf_dest="$1"; shift
|
|
|
|
local -a __conf_files
|
|
|
|
local __conf_spec __conf_dir __conf_wc
|
|
|
|
array_new "$__conf_dest"
|
|
|
|
for __conf_spec in "$@"; do
|
|
|
|
if [ -f "$__conf_spec" ]; then
|
|
|
|
array_add "$__conf_dest" "$__conf_spec"
|
|
|
|
continue
|
|
|
|
elif [ -d "$__conf_spec" ]; then
|
|
|
|
__conf_spec="$__conf_spec/*.conf"
|
|
|
|
fi
|
|
|
|
splitwcs "$__conf_spec" __conf_dir __conf_wc
|
|
|
|
array_lsfiles __conf_files "${__conf_dir:-.}" "$__conf_wc"
|
|
|
|
array_extend "$__conf_dest" __conf_files
|
|
|
|
done
|
2017-09-13 08:13:11 +04:00
|
|
|
}
|
|
|
|
|
2017-09-14 22:21:34 +04:00
|
|
|
function conf_load_files() {
|
2017-09-13 08:13:11 +04:00
|
|
|
# sourcer les fichiers spécifiés en faisant ce qui est nécessaire pour que
|
|
|
|
# les variables de __CONF_ARRAY_VARS soient correctement traitées.
|
2017-09-14 21:51:23 +04:00
|
|
|
local -a __conf_backups __conf_values
|
2017-09-18 11:47:20 +04:00
|
|
|
local __conf_file __conf_name __conf_i __conf_backup __conf_bn __conf_bv
|
2017-09-14 21:51:23 +04:00
|
|
|
for __conf_file in "$@"; do
|
|
|
|
# faire une copie de sauvegarde puis supprimer les variables tableaux
|
|
|
|
__conf_backups=()
|
2017-09-18 11:47:20 +04:00
|
|
|
for __conf_name in "${__CONF_ARRAY_VARS[@]}" "${__CONF_PATH_VARS[@]}"; do
|
|
|
|
__conf_backup="$(declare -p "$__conf_name" 2>/dev/null)"
|
|
|
|
if [ -z "$__conf_backup" ]; then
|
|
|
|
__conf_backup="$__conf_name="
|
|
|
|
else
|
|
|
|
# faire une correction de l'expression parce que la commande
|
|
|
|
# affichée par declare -p est différente entre bash 4.3 et bash
|
2017-09-19 08:19:12 +04:00
|
|
|
# 4.4 pour les tableaux. soit le tableau array=(a b)
|
2017-09-18 11:47:20 +04:00
|
|
|
# - bash 4.3 affiche declare -a array='([0]="a" [1]="b")'
|
|
|
|
# - bash 4.4 affiche declare -a array=([0]="a" [1]="b")
|
|
|
|
__conf_backup="${__conf_backup#declare }"
|
|
|
|
__conf_bn="${__conf_backup%% *}"
|
|
|
|
__conf_bv="${__conf_backup#* }"
|
|
|
|
if [[ "$__conf_bn" == -*a* ]]; then
|
|
|
|
__conf_bn="${__conf_bv%%=*}"
|
|
|
|
__conf_bv="${__conf_bv#*=}"
|
|
|
|
if [ "${__conf_bv:0:2}" == "'(" -a "${__conf_bv: -2:2}" == ")'" ]; then
|
2017-09-19 08:19:12 +04:00
|
|
|
__conf_backup="$__conf_bn=$(eval "echo $__conf_bv")"
|
2017-09-18 11:47:20 +04:00
|
|
|
else
|
|
|
|
__conf_backup="$__conf_bn=$__conf_bv"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
__conf_backup="$__conf_bv"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
__conf_backups=("${__conf_backups[@]}" "$__conf_backup")
|
2017-09-14 21:51:23 +04:00
|
|
|
unset "$__conf_name"
|
|
|
|
done
|
|
|
|
# charger le fichier
|
|
|
|
source "$__conf_file"
|
|
|
|
# puis restaurer les variables ou les fusionner avec une éventuelle nouvelle valeur
|
|
|
|
__conf_i=0
|
2017-09-18 11:47:20 +04:00
|
|
|
for __conf_name in "${__CONF_ARRAY_VARS[@]}" "${__CONF_PATH_VARS[@]}"; do
|
2017-09-14 21:51:23 +04:00
|
|
|
__conf_backup="${__conf_backups[$__conf_i]}"
|
|
|
|
if [ -n "$(declare -p "$__conf_name" 2>/dev/null)" ]; then
|
|
|
|
# la variable a été redéfinie, la fusionner avec la précédente valeur
|
2017-09-18 11:47:20 +04:00
|
|
|
if array_contains __CONF_ARRAY_VARS "$__conf_name"; then
|
|
|
|
array_copy __conf_values "$__conf_name"
|
|
|
|
eval "$__conf_backup"
|
|
|
|
array_extend "$__conf_name" __conf_values
|
|
|
|
elif array_contains __CONF_PATH_VARS "$__conf_name"; then
|
|
|
|
__conf_values="${!__conf_name}"
|
|
|
|
eval "$__conf_backup"
|
|
|
|
uaddpath "$__conf_values" "$__conf_name"
|
|
|
|
fi
|
2017-09-14 21:51:23 +04:00
|
|
|
else
|
|
|
|
# la variable n'a pas été redéfinie, restaurer la précédente valeur
|
|
|
|
eval "$__conf_backup"
|
|
|
|
fi
|
|
|
|
__conf_i=$(($__conf_i + 1))
|
|
|
|
done
|
|
|
|
done
|
2017-09-13 08:13:11 +04:00
|
|
|
}
|
2017-09-14 23:11:26 +04:00
|
|
|
|
|
|
|
function conf_install() {
|
|
|
|
# USAGE: conf_install DEST SRCS...
|
|
|
|
# installer les fichiers de SRCS dans le répertoire standardisé DEST
|
|
|
|
# ## destination
|
|
|
|
# - si DEST est un nom sans chemin, e.g NAME, alors la destination est
|
|
|
|
# ~/etc/NAME.d
|
|
|
|
# - si DEST est un nom avec chemin, alors la valeur est prise telle quelle
|
|
|
|
# comme destination, et le répertoire est créé le cas échéant.
|
|
|
|
# Si un fichier existe déjà dans la destination, afficher une demande de
|
|
|
|
# confirmation avant de l'écraser
|
|
|
|
# ## source
|
|
|
|
# - si SRC est un fichier, le prendre tel quel
|
|
|
|
# - si SRC est un répertoire, prendre tous les fichiers SRC/*.conf
|
|
|
|
# - si SRC est un pattern, prendre tous les fichiers correspondant
|
|
|
|
local -a srcs
|
|
|
|
local src dir wc
|
|
|
|
local dest="$1"; shift
|
|
|
|
[[ "$dest" == */* ]] || dest="$HOME/etc/$dest.d"
|
|
|
|
mkdir -p "$dest" || return 1
|
|
|
|
for src in "$@"; do
|
|
|
|
if [ -f "$src" ]; then
|
|
|
|
srcs=("$src")
|
|
|
|
elif [ -d "$src" ]; then
|
|
|
|
array_lsfiles srcs "$src" "*.conf"
|
|
|
|
else
|
|
|
|
splitwcs "$src" dir wc
|
|
|
|
array_lsfiles srcs "$dir" "$wc"
|
|
|
|
fi
|
|
|
|
for src in "${srcs[@]}"; do
|
|
|
|
copy_update_ask -y "$src" "$dest"
|
|
|
|
done
|
|
|
|
done
|
|
|
|
}
|