From e9b574d83dba6941d52db7160dd6606dcaae81f2 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Thu, 9 Mar 2017 07:15:09 +0400 Subject: [PATCH] =?UTF-8?q?rwoinst:=20int=C3=A9grer=20des=20fonctionnalit?= =?UTF-8?q?=C3=A9s=20de=20ruinst;=20support=20pr=C3=A9liminaire=20de=20dep?= =?UTF-8?q?loy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruinst | 5 +-- rwoinst | 133 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 116 insertions(+), 22 deletions(-) diff --git a/ruinst b/ruinst index a9d1fb3..c456272 100755 --- a/ruinst +++ b/ruinst @@ -56,9 +56,8 @@ OPTIONS Par défaut, si aucun hôte n'est spécifié, la configuration locale de déploiement est interrogée pour avoir cette information. -c, --deploy-config CONFNAME - Cette option permet de - spécifier le nom de la configuration à utiliser pour effectuer la - requête." + Cette option permet de spécifier le nom de la configuration à utiliser + pour effectuer la requête. Par défaut, utiliser le nom 'ruinst'" } set_defaults pubkeys diff --git a/rwoinst b/rwoinst index f1fdbc7..776b46c 100755 --- a/rwoinst +++ b/rwoinst @@ -10,7 +10,9 @@ USAGE $scriptname [-H host] [-T tmproot] ... [-- options de woinst] OPTIONS - -C Ne pas faire le déploiement. Configurer uniquement la connexion par clé + -C, --configure-user + --configure USER [--uses-su] + Ne pas faire le déploiement. Configurer uniquement la connexion par clé sur les hôtes distants spécifiés pour le user spécifié. Il faut pouvoir se connecter par mot de passe pour configurer la connexion par clé. Si l'on veut configurer la connexion par clé pour le user root, mais que @@ -19,53 +21,135 @@ OPTIONS il est possible de faire la configuration avec '--configure root'. La commande serait alors $scriptname -H user@host --configure root - -T tmproot + Si l'hôte distant n'a pas sudo ou si sudo n'est pas configuré, il faut + rajouter l'option --uses-su, e.g: + $scriptname -h user@host --configure root --uses-su + -T, --tmproot TMPROOT Spécifier le répertoire temporaire sur l'hôte distant, comme par exemple /var/tmp. Cette option est utile pour les vservers, qui ont par défaut un /tmp minuscule de 16 Mo. - -S ssh + -S, --ssh SSH Spécifier le programme à utiliser pour la connection par ssh. + -h, --host hosts + -h, --host @hostsfile -H host - Spécifier un hôte distant sur lequel faire le déploiement. Plusieurs - options -H peuvent être spécifiées, ou alors on peut séparer plusieurs - hôtes par ':', e.g. -H host1:host2 + Spécifier un ou plusieurs hôtes sur lequels faire le déploiement. Pour + spécifier plusieurs hôtes, il est possible d'utiliser plusieurs fois + l'option -h, ou spécifier en une seule fois plusieurs hôtes en les + séparant par un espace ou le caractère ':', e.g. 'host1 host2' ou + 'host1:host2'. Si la spécification contient les caractères { et }, + l'expansion est effectuée, e.g + -h 'root@{host1,host2}.univ.run' Par défaut, la connexion sur l'hôte distant se fait avec l'utilisateur root. Il est possible de spécifier un autre utilisateur avec la syntaxe - user@host, e.g -H user@host" + user@host, e.g -h user@host + La forme @hostsfile permet de lire la liste des hôtes depuis le fichier + hostsfile, à raison d'un hôte par ligne. + --deploy + --no-deploy + Autoriser (respectivement interdire) l'utilisation de la configuration + locale de déploiement pour identifier la destination si aucun hôte n'est + spécifié. + Par défaut, si aucun hôte n'est spécifié, la configuration locale de + déploiement est interrogée pour avoir cette information. + -c, --deploy-config CONFNAME + Cette option permet de spécifier le nom de la configuration à utiliser + pour effectuer la requête. Par défaut, utiliser le nom 'rwoinst'" } set_defaults pubkeys action=deploy confuser= +uses_su= tmproot= -hosts=() SSH= +hosts=() +deploy_enable=1 +deploy_confname=rwoinst parse_opts "${PRETTYOPTS[@]}" \ --help '$exit_with display_help' \ - -C action=configure \ + -C,--configure-user action=configure \ --configure: '$set@ confuser;action=configure' \ + --uses-su uses_su=1 \ -T:,--tmproot: tmproot= \ - -S: SSH= \ + -S:,--ssh: SSH= \ -h:,-H:,--host: hosts \ + --deploy deploy_enable=1 \ + --no-deploy deploy_enable= \ + -c:,--deploy-config deploy_confname= \ @ args -- "$@" && set -- "${args[@]}" || die "$args" -function _dot_is_localhost() { - [ "$1" == "." ] && echo "localhost" || echo "$1" +SSH="${SSH:-ssh}" + +__PARSED_HOSTS=() +__PARSED_FILES=() +function parse_hostsfile() { + # Lire chacun des fichiers $* et initialiser __PARSED_HOSTS avec la liste + # des hôtes mentionnés dans les fichiers. + local inputfile basedir inputs input + for inputfile in "$@"; do + inputfile="$(abspath "$inputfile")" + array_contains __PARSED_FILES "$inputfile" && { + ewarn "$(ppath "$inputfile"): inclusion récursive" + continue + } + array_add __PARSED_FILES "$inputfile" + basedir="$(dirname "$inputfile")" + + array_from_lines inputs "$(<"$inputfile" filter_conf)" || { + ewarn "$inputfile: fichier ingnoré" + continue + } + for input in "${inputs[@]}"; do + if [ "${input#@}" != "$input" ]; then + # fichier inclus + parse_hostsfile "$(abspath "${input#@}" "$basedir")" + else + array_addu __PARSED_HOSTS "$input" + fi + done + done } +function __expand_braces() { + if [[ "$1" == *{* ]] && [[ "$1" == *}* ]]; then + eval "echo $1" + else + echo "$1" + fi +} +function __dot_is_localhost() { [ "$1" == "." ] && echo "localhost" || echo "$1"; } function fix_hosts() { - # Si hosts contient des éléments multiple, comme a:b, séparés ces + # Si hosts contient des éléments multiple, comme a:b, séparer ces # éléments. i.e (a b:c) --> (a b c) - # remplacer aussi les '.' par 'localhost' - array_fix_paths hosts - array_map hosts _dot_is_localhost + # Supporter la syntaxe @hostsfile qui permet de charger la liste des hôtes + # depuis un fichier. + # Remplacer aussi les '.' par 'localhost' + array_map hosts __expand_braces + array_fix_paths hosts ":" + array_fix_paths hosts " " + + local -a _hosts _tmphosts host + for host in "${hosts[@]}"; do + host="${host%/}" + if [ "${host#@}" != "$host" ]; then + __PARSED_HOSTS=() + parse_hostsfile "${host#@}" + array_fix_paths __PARSED_HOSTS + array_extendu _hosts __PARSED_HOSTS + else + array_addu _hosts "$host" + fi + done + array_copy hosts _hosts + array_map hosts __dot_is_localhost } ################################################################################ # Configuration de l'accès par clé aux hôtes if [ "$action" == "configure" ]; then - args=(${confuser:+--configure "$confuser"}) + args=(${confuser:+--configure "$confuser"} ${uses_su:+--uses-su} -S "$SSH") for host in "${hosts[@]}"; do args=("${args[@]}" -H "$host") done @@ -75,8 +159,6 @@ fi ################################################################################ # Déploiement -SSH="${SSH:-ssh}" - ## Bundle à déployer if [ -z "$1" ] || [[ "$1" == -* ]] || [[ "$1" == *=* ]]; then # pas d'argument, ou c'est une option (qui fait donc partie des arguments de @@ -85,6 +167,19 @@ if [ -z "$1" ] || [[ "$1" == -* ]] || [[ "$1" == *=* ]]; then fi ## Hôtes sur lesquels faire le déploiement +if array_isempty hosts && [ -n "$deploy_enable" ]; then + urequire deploy + deploy_setconf "$deploy_confname" + if deploy_loadconf; then + setxx wobundle=abspath "$1" // basename -- + if eval "$(deploy_query -v host DEST wobundle rwoinst_bundle "" shell "$wobundle")"; then + check_interaction -c && einfo "Ce bundle sera déployé vers les hôtes suivants: +$(array_to_lines host "" " ")" + ask_any "Voulez-vous continuer?" Oq || die + array_copy hosts host + fi + fi +fi array_isempty hosts && read_value "Entrez une liste d'hôtes séparés par ':'" hosts "localhost" fix_hosts