From 8116591d1fe59c2c7e9191cec0723d24bc916893 Mon Sep 17 00:00:00 2001 From: Nicolas Dandrimont Date: Tue, 17 Mar 2009 07:29:41 +0100 Subject: [PATCH] [munin/scripts/link_plugins] Import initial MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ignore-this: 716026ebc32c1b292a4c7dc7ea2daa62 Pour l'instant, le script crée les liens dans un répertoire temporaire qu'il imprime sur sa sortie standard. darcs-hash:20090317062941-ffbb2-d3ac5ecf0d97559ad7ea1e66f4701e8661bab46d.gz --- munin/scripts/link_plugins.py | 157 ++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100755 munin/scripts/link_plugins.py diff --git a/munin/scripts/link_plugins.py b/munin/scripts/link_plugins.py new file mode 100755 index 00000000..6e500040 --- /dev/null +++ b/munin/scripts/link_plugins.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python +# -!- encoding: 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 +# +# Licence: MIT +# + +import os +import socket +import subprocess +import sys +import tempfile + +from hosts_plugins import hosts_plugins + +# Plugins munin classiques à ignorer +IGNORE_PLUGINS = ('port_', 'vlan_', 'apt_all', 'if_', 'if_err_') + +# 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 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:] + 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 plugin, dest_file in custom_plugins.iteritems(): + result[plugin] = os.path.join('/usr/scripts/munin', dest_file) + + return result + +def link_all_plugins(directory, plugins): + """Lie tous les plugins du dictionnaire plugins dans le répertoire + directory""" + + for name, path in plugins.iteritems(): + os.symlink(path, os.path.join(directory, 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 + + +QUIRKS.append(add_plugin("uptime")) # Coucou MoSaN +QUIRKS.append(add_plugin("netstat")) + +# Hacks sales +def add_wicked_ifaces_if_no_ifaces(plugins): + """Ajoute les interfaces moisies (p.ex. `crans') aux plugins si + munin n'a pas trouvé d'interface""" + + 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.strip() + # Recherche d'une ligne type "iface eth0 inet static" + if line.startswith('iface'): + if line.endswith("static"): + interface_name = line.split()[1] + # on dégage les interfaces sur vlan spéciaux et aliasées + 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_') + +QUIRKS.append(add_wicked_ifaces_if_no_ifaces) + +if __name__ == "__main__": + tmpdir = tempfile.mkdtemp() + print tmpdir + link_all_plugins(tmpdir, get_all_plugins())