Photos récentes


Pages

Liens

Mots-clés

Archives

Ce site…

Lancer puppet depuis cron

February 24th, 2011 at 1:35 pm by nono

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 {} \;

Tags: ,
Posted in geekeries


5 Comments

  • […] En résumé, ça efface les éventuels certificats et autres clés déjà présents sur la machine, ça les remplace par la version «qui fait autorité» et ça lance puppet pour amorcer la pompe. Pour le touch à la fin, c’est expliqué là : http://blogs.glou.org/arnaud/2011/02/24/lancer-puppet-depuis-cron/ […]

  • Gardouille says:

    Ola =)

    Merci pour ton script.
    J’y ai ajouté une petite modification:
    [ -f $runoftenfile ] || touch ${flagdir}”/.run-often”
    [ -f $dontrunfile ] || touch ${flagdir}”/.never-auto-run”

    Ainsi j’ai juste à déplacer/copier le fichier caché pour le rendre “visible” pour choisir de bloquer puppet ou de l’exécuter toutes les 5 minutes. C’est surtout pour m’éviter de me rappeler l’emplacement exact des fichiers ou de devoir retourner dans le script =)

    Aller, je retourne à mes configurations 😉

  • nono says:

    J’adopte. Enfin, pour la prochaine fois que j’y toucherai. Merci ! 🙂

  • Gardouille says:

    Je me suis planté sur les tests en fait, je vérifie si le fichier caché existe ou je le crée, pas si le fichier non caché existe.

    M’enfin l’idée est là quoi =)

  • Francis says:

    Merci pour ce script, c’est une très bonne idée.
    Pour ceux qui veulent le déployer avec puppet, voici mon fichier .pp :

    #PuppetAgent
    #
    #Configuration de puppet Agent
    #

    class puppetagent {
    package { “puppet”:
    ensure => installed;
    }

    service { “puppet”:
    ensure => stopped,
    enable => false,
    hasrestart => true,
    hasstatus => true,
    require => Package[“puppet”],
    }

    file { “/usr/local/sbin/run-puppet”:
    mode => 755,
    owner => root,
    group => root,
    content => template(“puppetagent/run-puppet.erb”);
    }

    case $puppet_mode {
    ‘client’ : {
    file { “/etc/puppet/puppet.conf”:
    mode => 644,
    owner => root,
    group => root,
    content => template(“puppetagent/puppet.conf.erb”);
    }
    }
    }

    cron { cron-run-puppet-often:
    command => “/usr/local/sbin/run-puppet -often”,
    require => File[“/usr/local/sbin/run-puppet”],
    user => root,
    minute => ‘*/5′
    }

    cron { cron-run-puppet:
    command => “/usr/local/sbin/run-puppet”,
    require => File[“/usr/local/sbin/run-puppet”],
    user => root,
    minute => ’42’
    }
    }

 




XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>