Files
init.sh/init.sh

233 lines
6.0 KiB
Bash
Executable File

#!/bin/bash
# Init : initialise une machine et la met en conformité
# Copyright (c) 2021 Geoffray Levasseur <geoffray.levasseur@obs-mip.fr>
# trace ERR through pipes
set -o pipefail
# trace ERR through 'time command' and other functions
set -o errtrace
# set -e : exit the script if any statement returns a non-true return value
set -o errexit
export VERSION="0.95.1"
# Stocke le chemin du script
export MYPATH=$(dirname $0)
# récupère le nom d'hote
export HOSTNAME=$(hostname)
# Charge les bibliothèques
for lib in $MYPATH/lib/*.sh; do
. $lib
done
# =============================
# ==== Basic sanity checks ====
# =============================
# Check if a function exists
function_exists() {
declare -f -F $1 > /dev/null
return $?
}
function_exists prnt || (
echo "*** ERREUR FATALE !"
echo "*** Il manque des fonctions vitales venant des bibliothèques."
exit 2
)
# ================================
# ==== Main program functions ====
# ================================
# Affiche l'aide
disp_help()
{
cat << EOF
Utilisation : init.sh [OPTIONS] [-m|--module <module1,...,moduleN>]
Initialise une machine pour l'intégrer à un réseau.
Options :
-m, --module <liste> Lance les modules indiqués même s'il ne sont pas
dans les fichiers de configuration.
-c, --check-only Lance les procédure de vérification préexecution
sans rien modifier.
-j, --jump Saute les procédures de vérification.
-k, --keep-going L'execution continura en cas d'erreur.
-r, --resume Reprend l'execution la ou elle c'est arrêté.
-h, --help Affiche ce texte d'aide.
-v, --version Show version of that script and version of all
available modules.
Attention : les options courtes ne sont pas concaténable.
Variable d'environnement :
LOGFILE Stocke le nom complet du fichier de log qui sera
utilisé.
Fichiers de configuration :
Le fichier de configuration principal fournira les détails nécessaire
au déploiement de la nouvelle machine. Il doit se situer dans le
répertoire conf/ à coté du script init.sh. Si un fichier appelé
"hostname.sh" (ou hostname est le nom d'hote) existe il sera le fichier
de configuration principal. Dans le cas contraire, le nom générique
"init.conf.sh" sera recherché. En l'absence de fichier de configuration
ce script ne pourra pas fonctionner.
Veuiller consulter les fichiers de configuration fournis en exemple
pour avoir un aperçu des paramêtres disponibles.
EOF
}
# Show version infos
show_version()
{
echo -e "${BWhite}init.sh${DEFAULTCOL} version ${BGreen}$VERSION${DEFAULTCOL}"
echo ""
echo "Available modules:"
for mod in $MYPATH/modules/*.sh; do
. $mod
local modname=$(get_mod_name $mod)
local version=VER_$modname
echo -e "\t$BWhite$modname${DEFAULTCOL}: $BGreen${!version}$DEFAULTCOL"
done
}
# Get module name from module file
get_mod_name()
{
echo $(basename $1 | cut -f 1 -d '.')
}
# ======================
# ==== Main Program ====
# ======================
# Initializing global variables
export CHECK_ONLY=false
export JUMP=false
export KEEPGOING=false
export RESUME=false
# Processing command line options
want_module=false
for opt in $@; do
if [[ $want_module == false ]]; then
case $opt in
"-h"|"--help")
disp_help
exit 0
;;
"-v"|"--version")
show_version
exit 0
;;
"-m"|"--module")
want_module=true
prnt W "Une liste de modules manuelle sera utilisé. $want_module"
;;
"-c"|"--check-only")
export CHECK_ONLY=true
;;
"-j"|"--jump")
export JUMP=true
;;
"-k"|"--keep-going")
export KEEPGOING=true
;;
"-r"|"--resume")
if [[ -s $MYPATH/stage ]]; then
export RESUME=true
else
prnt E "Le fichier d'état n'existe pas ou est vide !"
prnt E "Sans ce fichier, la reprise n'est pas possible."
die 1 --force
fi
;;
*)
prnt E "Paramètre \'$opt\' non géré."
disp_help
exit 1
;;
esac
else
if [[ ! $MANUAL_MODULE_LIST ]]; then
MANUAL_MODULE_LIST=$opt
want_module=false
else
prnt E "Une liste de module à déjà été fournie !"
prnt E "La ligne de commande ne tolère qu'un paramètre --module."
die 1 --force
fi
fi
done
# À ce stade on vérifie qu'on soit root
# (--help et --version sont autorisés en user normal)
if [[ $EUID -ne 0 ]]; then
prnt E "Ce script doit être démarré en tant que root. Arrêt."
die 1 --force
fi
# Variables globales importantes
export LOGFILE=${LOGFILE:-"$MYPATH/log/init-$(uname -n)-$(stdtime).log"}
prnt I "Création du répertoire d'accueil du fichier log..."
[[ ! -d $(dirname $LOGFILE) ]] && mkdir -pv $(dirname $LOGFILE)
# Log toutes les sortie dans le fichier de log
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec > >(tee -a $LOGFILE)
exec 2> >(tee -a $LOGFILE >&2)
# Récupère la configuration
prnt I "Chargement de la configuration..."
if [[ -e $MYPATH/conf/$HOSTNAME.conf ]]; then
prnt I "Une configuration spécifique sera utilisé."
. $MYPATH/conf/$HOSTNAME.conf
else
if [[ -e $MYPATH/conf/init.conf.sh ]]; then
prnt I "Une configuration générique sera utilisé."
. $MYPATH/conf/init.conf.sh
else
prnt E "Aucune configuration trouvée, impossible de continuer."
die 2 --force
fi
fi
if [[ $want_module == true ]]; then
prnt E "La liste des modules à exécuter est manquante !"
die 1 --force
fi
# Check unconsistant parameters
if [[ $CHECK_ONLY == true ]]; then
[[ $JUMP == true ]] && (
prnt E "Les options --check-only et --jump s'excluent mutuellement !"
die 1 --force
)
[[ $KEEPGOING == true ]] && (
prnt E "Les options --keep-going et --check-only sont incompatible !"
die 1 --force
)
fi
if [[ $RESUME == true ]]; then
[[ $CHECK_ONLY == true ]] && (
prnt E "La reprise n'a pas de sens avec --check-only."
die 1 --force
)
[[ $MANUAL_MODULE_LIST ]] && (
prnt E "Le mode reprise ne fonctionne pas avec une liste de modules passé manuellement."
die 1 --force
)
fi
prnt I "That's all folks !"
echo "Après vérification des logs, vous devriez redémarrer la machine..."