
On s'autorise à lister les plugins à activer sur la base des groupes bcfg2 d'un serveur, au lieu de spécifier en dur le nom du serveur.
247 lines
7.5 KiB
Python
Executable file
247 lines
7.5 KiB
Python
Executable file
#!/bin/bash /usr/scripts/python.sh
|
|
# -*- coding: utf-8 -*-
|
|
#
|
|
# Liste les liens à créer pour les plugins munin.
|
|
#
|
|
# Utilise la liste de plugins classiques renvoyée par
|
|
# munin-node-configure, filtrée, et les plugins customisés Cr@ns
|
|
# configurés dans hosts_plugins.py
|
|
#
|
|
# Copyright © 2009 Nicolas Dandrimont <Nicolas.Dandrimont@crans.org>
|
|
#
|
|
# Licence: MIT
|
|
#
|
|
|
|
import optparse
|
|
import os
|
|
import shutil
|
|
import socket
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
|
|
from hosts_plugins import hosts_plugins, general_plugins
|
|
|
|
from gestion.config.services import services
|
|
|
|
|
|
# Plugins munin classiques à ignorer
|
|
IGNORE_PLUGINS = (
|
|
'apt_all',
|
|
'if_',
|
|
'if_err_',
|
|
'multips',
|
|
'nfs4_client',
|
|
'nfsd',
|
|
'nfsd4',
|
|
'exim_mailstats',
|
|
'port_',
|
|
'sensors_',
|
|
'squid_icp',
|
|
'tomcat_',
|
|
'vlan_',
|
|
)
|
|
|
|
if socket.gethostname() in services.get('iscsi', []):
|
|
IGNORE_PLUGINS += (
|
|
'diskstat',
|
|
'diskstats',
|
|
'diskstat_',
|
|
)
|
|
|
|
# Chemin d'accès aux plugins munin
|
|
MUNIN_PATH = "/usr/share/munin/plugins"
|
|
|
|
# Hacks crades
|
|
QUIRKS = []
|
|
|
|
if sys.version_info < (2, 5):
|
|
def any(genexpr):
|
|
"""Retourne True si quelque chose est vrai dans genexpr"""
|
|
for truc in genexpr:
|
|
if truc:
|
|
return True
|
|
return False
|
|
|
|
def register_quirk(f):
|
|
QUIRKS.append(f)
|
|
|
|
def get_munin_plugins():
|
|
"""Liste les plugins munin créés par le système
|
|
|
|
Retourne un dictionnaire dont la clé est le lien dans
|
|
/etc/munin/plugins, et la valeur le fichier à lier.
|
|
"""
|
|
|
|
# Dictionnaire de sortie
|
|
output = {}
|
|
|
|
# Crée un répertoire vide pour faire croire à Munin qu'on veut
|
|
# créer tous les liens...
|
|
tempdir = tempfile.mkdtemp()
|
|
|
|
# Demande à Munin quels plugins il lui semble bon nous faire
|
|
# utiliser. --families=auto,manual permet de récupérer plus de
|
|
# plugins (qu'il faut ensuite filtrer)
|
|
munin = subprocess.Popen(["/usr/sbin/munin-node-configure",
|
|
"--families=manual",
|
|
"--families=auto",
|
|
"--servicedir", tempdir,
|
|
"--shell"],
|
|
stdout = subprocess.PIPE,
|
|
stderr = subprocess.PIPE
|
|
)
|
|
munin_stdout, munin_stderr = munin.communicate()
|
|
|
|
# if munin.returncode != 0:
|
|
# raise RuntimeError, "munin-node-configure... Stderr:\n%s" % munin_stderr
|
|
|
|
munin_output_lines = munin_stdout.splitlines()
|
|
|
|
for line in munin_output_lines:
|
|
if line.startswith("ln -s"):
|
|
dst, src = line.split()[-2:]
|
|
if dst[0] == "'":
|
|
dst = dst[1:-1]
|
|
src = src[1:-1]
|
|
src = os.path.basename(src)
|
|
# filtrage
|
|
if not os.path.basename(dst) in IGNORE_PLUGINS:
|
|
output[src] = dst
|
|
|
|
os.rmdir(tempdir)
|
|
|
|
# Exécute les hacks sales sur la sortie
|
|
for quirk in QUIRKS:
|
|
quirk(output)
|
|
|
|
return output
|
|
|
|
def get_all_plugins():
|
|
"""Liste les liens de plugins munin à créer
|
|
|
|
Retourne un dictionnaire dont la clé est le lien dans
|
|
/etc/munin/plugins, et la valeur le fichier à lier.
|
|
"""
|
|
|
|
hostname = socket.gethostname()
|
|
result = get_munin_plugins()
|
|
|
|
custom_plugins = hosts_plugins.get(hostname, {})
|
|
for (group, hosts) in services.iteritems():
|
|
if hostname in hosts:
|
|
custom_plugins.update(hosts_plugins.get(group, {}))
|
|
custom_plugins.update(general_plugins)
|
|
|
|
for plugin, dest_file in custom_plugins.iteritems():
|
|
if dest_file.startswith('/'):
|
|
result[plugin] = dest_file
|
|
else:
|
|
result[plugin] = os.path.join('/usr/scripts/munin', dest_file)
|
|
|
|
return result
|
|
|
|
def list_plugins(plugins, directory):
|
|
"""Liste les plugins comme s'ils allaient être liés dans
|
|
directory"""
|
|
|
|
for name, path in sorted(plugins.items()):
|
|
print os.path.join(directory, name), '->', path
|
|
|
|
def link_plugins(plugins, directory):
|
|
"""Lie les plugins dans le répertoire directory"""
|
|
|
|
for name, path in plugins.iteritems():
|
|
try:
|
|
os.symlink(path, os.path.join(directory, name))
|
|
if options.verbose:
|
|
print "%s installé avec succès!" % name
|
|
except OSError:
|
|
print "Echec à l'installation de %s (déjà installé?)" % name
|
|
|
|
# Hack propre
|
|
def add_plugin(plugin):
|
|
"""Crée une fonction qui ajoute le plugin à la liste"""
|
|
# Les clôtures en Python, ça fait rêver...
|
|
def f(plugins, plugin=plugin):
|
|
plugins[plugin] = os.path.join(MUNIN_PATH, plugin)
|
|
return f
|
|
|
|
register_quirk(add_plugin("uptime")) # Coucou MoSaN
|
|
register_quirk(add_plugin("netstat"))
|
|
register_quirk(add_plugin("nfs_client"))
|
|
|
|
# Hacks sales
|
|
@register_quirk
|
|
def add_ifaces(plugins):
|
|
"""Ajoute les interfaces à la liste des plugins si munin n'a pas
|
|
trouvé d'interface (ou si elles ont été filtrées)"""
|
|
|
|
if not any(plugin.startswith('if_') for plugin in plugins):
|
|
# Liste les interfaces configurées sur le système
|
|
interfaces_file = None
|
|
interfaces = []
|
|
try:
|
|
interfaces_file = file('/etc/network/interfaces', 'r')
|
|
for line in interfaces_file:
|
|
line = line.split()
|
|
# Recherche d'une ligne type "iface eth0 inet static"
|
|
if line and line[0] == 'iface' and line[-1] == 'static':
|
|
interface_name = line[1]
|
|
# on dégage les interfaces sur vlan spéciaux et
|
|
# aliasées (leur nom contient ':' ou '.')
|
|
if not set('.:') & set(interface_name):
|
|
interfaces.append(interface_name)
|
|
finally:
|
|
if interfaces_file is not None:
|
|
interfaces_file.close()
|
|
|
|
for interface in interfaces:
|
|
plugins['if_%s' % interface] = os.path.join(MUNIN_PATH,'if_')
|
|
plugins['if_err_%s' % interface] = os.path.join(MUNIN_PATH, 'if_err_')
|
|
|
|
@register_quirk
|
|
def use_correct_postfix_mailstats(plugins):
|
|
"""Utilise un postfix_mailstats non buggué sur etch"""
|
|
if "postfix_mailstats" in plugins:
|
|
try:
|
|
debver_file = open('/etc/debian_version')
|
|
except IOError:
|
|
return
|
|
else:
|
|
debver = debver_file.read()
|
|
debver_file.close()
|
|
if debver.startswith('4'):
|
|
plugins["postfix_mailstats"] = "/usr/scripts/munin/postfix_mailstats"
|
|
|
|
if __name__ == "__main__":
|
|
parser = optparse.OptionParser()
|
|
parser.add_option('-d', '--directory',
|
|
help = 'Write plugin symlinks to DIR',
|
|
metavar = 'DIR',
|
|
default = '/etc/munin/plugins'
|
|
)
|
|
parser.add_option('-f', '--force',
|
|
action = 'store_true',
|
|
help = 'Remove destination directory'
|
|
)
|
|
parser.add_option('-p', '--pretend',
|
|
action = 'store_true',
|
|
help = 'Do not actually make links'
|
|
)
|
|
parser.add_option('-v', '--verbose',
|
|
action = 'store_true',
|
|
help = 'Increase verbosity'
|
|
)
|
|
(options, args) = parser.parse_args()
|
|
|
|
plugins = get_all_plugins()
|
|
|
|
if options.pretend:
|
|
list_plugins(plugins, options.directory)
|
|
else:
|
|
if options.force:
|
|
shutil.rmtree(options.directory)
|
|
os.mkdir(options.directory)
|
|
link_plugins(plugins, options.directory)
|
|
|