Lancer puppet depuis cron
February 24, 2011 by nonoCatégories geekeries - Mots-clés cron puppet
Puppet, c'est bien. Ça a juste un tout petit inconvénient : c'est écrit en ruby, avec la consommation mémoire que ça implique. Vous me direz, 200 Mo, sur une machine moderne, c'est rien. Sauf que si vous commencez à jouer avec des isolateurs, vous allez vite vous rendre compte que 30 fois 200 Mo, ça finit par faire beaucoup. Surtout pour un outil qui passe 98% de son temps à dormir (non, il ne libère pas la mémoire pour autant).
J'ai donc pondu un petit bout de script shell pour lancer puppetd uniquement quand on a besoin de lui. J'en ai profité pour améliorer un peu la gestion de la périodicité. En gros,
- par défaut, puppetd tourne une fois par heure,
- si le fichier /var/run/puppet/run-often existe, il tourne toutes les 5 minutes pendant une heure au plus (il supprime le fichier après ce délai),
- si le fichier /var/run/puppet/never-auto-run existe, il refuse de tourner (pratique pour les maintenances où on ne veut pas se battre contre puppet).
Tout ça, c'est géré par cron de cette façon :
*/5 * * * * /usr/local/sbin/run-puppet -often 42 * * * * /usr/local/sbin/run-puppet
Notez que ces deux invocations ne lancent pas puppetd immédiatement ; elles attendent «un certain temps» (calculé en fonction de l'adresse IPv4 de la machine, je voulais des intervalles fixes entre deux passages de Puppet).
Le script accepte aussi une option -now qui lui indique de lancer puppet immédiatement ; cette option est conçue pour invoquer le script directement en ligne de commande.
Finalement, le script lui-même :
#!/bin/bash # # Arnaud Gomes 2010 # # Trigger a puppet run. # # Usage: # # run-puppet # Run sometime in the next hour. # # run-puppet -often # Run sometime in the next 5 minutes if $runoftenfile exists. # # run-puppet -now # Run now. # # This script will exit immediately if $dontrunfile exists. # # Needs /usr/bin/lockfile (from procmail). flagdir="/var/run/puppet" runoftenfile=${flagdir}"/run-often" dontrunfile=${flagdir}"/never-auto-run" lockfile=${flagdir}"/lock" puppetd="/usr/sbin/puppetd" flags="--no-daemonize --onetime --no-splay" usage () { echo "Usage: $0 [ -often | -now ]" exit 1 } dontrun () { echo "$dontrunfile present, skipping this run." exit 0 } run () { lockfile $lockfile $puppetd $flags rm -f $lockfile } [ $# -le 1 ] || usage [ -f $dontrunfile ] && dontrun # $seed is used for computing splay time. We do not make it random # as we want each machine to run puppet every hour (or whatever), not # "more or less randomely averaging to once every hour". # # This horrible perl thing just means "last two bytes from IPv4 address, # reversed". We reverse them as the last byte probably is more evenly # distributed. seed=$(($(facter ipaddress | perl -pe 's/^([0-9]+\.){2}([0-9]+)\.([0-9]+)$/$3 * 256 + $2/'))) splay=$(($seed % 3600)) # Exit if called with -often and no $runoftenfile. # If $runoftenfile is here, we run within 5 minutes instead of within # an hour. if [ "$1" = "-often" ] then [ -f $runoftenfile ] || exit 0 splay=$(($seed % 300)) fi # Of course option -now removes any splay time. if [ "$1" = "-now" ] then splay=0 flags="$flags --verbose" fi sleep $splay run # Remove $runoftenfile after an hour. We don't want to run every 5 minutes # for ever, only when needed. [ -f $runoftenfile ] && find $runoftenfile -cmin +60 -exec rm -f {} \;