summaryrefslogtreecommitdiff
path: root/files
diff options
context:
space:
mode:
Diffstat (limited to 'files')
-rw-r--r--files/config/host/munin.conf.header.CentOS88
-rw-r--r--[l---------]files/config/host/munin.conf.header.Debian.sid76
-rw-r--r--[l---------]files/config/host/munin.conf.header.Debian.wheezy76
-rw-r--r--files/plugins/kvm_cpu101
-rw-r--r--files/plugins/kvm_io109
-rw-r--r--files/plugins/kvm_mem106
-rw-r--r--files/plugins/kvm_net148
7 files changed, 676 insertions, 28 deletions
diff --git a/files/config/host/munin.conf.header.CentOS b/files/config/host/munin.conf.header.CentOS
index 413cd84..f212ce0 100644
--- a/files/config/host/munin.conf.header.CentOS
+++ b/files/config/host/munin.conf.header.CentOS
@@ -5,26 +5,40 @@
# must be writable by the user running munin-cron. They are all
# defaulted to the values you see here.
#
-# dbdir /var/lib/munin
-# htmldir /var/www/html/munin
-# logdir /var/log/munin
-# rundir /var/run/munin
+#dbdir /var/lib/munin
+#htmldir /var/www/html/munin
+htmldir /var/www/html/munin
+#logdir /var/log/munin
+#rundir /var/run/munin
+
+# Where to look for the HTML templates
#
-# tmpldir /etc/munin/templates
+#tmpldir /etc/munin/templates
-# (Exactly one) directory to include all files from.
+# Where to look for the static www files
+#
+#staticdir /etc/munin/static
+
+# temporary cgi files are here. note that it has to be writable by
+# the cgi user (usually nobody or httpd).
#
-# includedir /etc/munin/munin-conf.d
+# cgitmpdir /var/lib/munin/cgi-tmp
-# Make graphs show values per minute instead of per second
-#graph_period minute
+# (Exactly one) directory to include all files from.
+includedir /etc/munin/conf.d
+
+# You can choose the time reference for "DERIVE" like graphs, and show
+# "per minute", "per hour" values instead of the default "per second"
+#
+#graph_period second
-# Graphics files are normaly generated by munin-graph, no matter if
-# the graphs are used or not. You can change this to
-# on-demand-graphing by following the instructions in
-# http://munin.projects.linpro.no/wiki/CgiHowto
+# Graphics files are generated either via cron or by a CGI process.
+# See http://munin-monitoring.org/wiki/CgiHowto2 for more
+# documentation.
+# Since 2.0, munin-graph has been rewritten to use the cgi code.
+# It is single threaded *by design* now.
#
-graph_strategy cgi
+#graph_strategy cgi
# munin-cgi-graph is invoked by the web server up to very many times at the
# same time. This is not optimal since it results in high CPU and memory
@@ -36,15 +50,41 @@ graph_strategy cgi
# If the automatic CGI url is wrong for your system override it here:
#
-#cgiurl_graph /cgi-bin/munin-cgi-graph
+#cgiurl_graph /munin-cgi/munin-cgi-graph
+
+# max_size_x and max_size_y are the max size of images in pixel.
+# Default is 4000. Do not make it too large otherwise RRD might use all
+# RAM to generate the images.
+#
+#max_size_x 4000
+#max_size_y 4000
-# munin-graph runs in parallel, the number of concurrent processes is
-# 6. If you want munin-graph to not be parallel set to 0. If set too
-# high it will slow down munin-graph. Some experiments are needed to
-# determine how many are optimal on your system. On a multi-core
-# system with good SCSI disks the number can probably be quite high.
+# HTML files are normally generated by munin-html, no matter if the
+# files are used or not. You can change this to on-demand generation
+# by following the instructions in http://munin-monitoring.org/wiki/CgiHowto2
+#
+# Notes:
+# - moving to CGI for HTML means you cannot have graph generated by cron.
+# - cgi html has some bugs, mostly you still have to launch munin-html by hand
+#
+html_strategy cron
+
+# munin-update runs in parallel.
+#
+# The default max number of processes is 16, and is probably ok for you.
+#
+# If set too high, it might hit some process/ram/filedesc limits.
+# If set too low, munin-update might take more than 5 min.
+#
+# If you want munin-update to not be parallel set it to 0.
#
-#max_graph_jobs 6
+#max_processes 16
+
+# RRD updates are per default, performed directly on the rrd files.
+# To reduce IO and enable the use of the rrdcached, uncomment it and set it to
+# the location of the socket that rrdcached uses.
+#
+#rrdcached_socket /var/run/rrdcached.sock
# Drop somejuser@fnord.comm and anotheruser@blibb.comm an email everytime
# something changes (OK -> WARNING, CRITICAL -> OK, etc)
@@ -53,11 +93,7 @@ graph_strategy cgi
#
# For those with Nagios, the following might come in handy. In addition,
# the services must be defined in the Nagios server as well.
-#contact.nagios.command /usr/sbin/send_nsca -H nagios.host.com -c /etc/send_nsca.cfg
-
-contacts me
-contact.me.command mail -s "Munin notification ${var:group} :: ${var:host} :: ${var:graph_title}" root
-contact.me.always_send warning critical
+#contact.nagios.command /usr/bin/send_nsca nagios.host.comm -c /etc/nsca.conf
# a simple host tree
#[localhost]
diff --git a/files/config/host/munin.conf.header.Debian.sid b/files/config/host/munin.conf.header.Debian.sid
index 5fa2037..771d50d 120000..100644
--- a/files/config/host/munin.conf.header.Debian.sid
+++ b/files/config/host/munin.conf.header.Debian.sid
@@ -1 +1,75 @@
-munin.conf.header.Debian.squeeze \ No newline at end of file
+# Example configuration file for Munin, generated by 'make build'
+
+# The next three variables specifies where the location of the RRD
+# databases, the HTML output, and the logs, severally. They all
+# must be writable by the user running munin-cron.
+dbdir /var/lib/munin
+htmldir /var/cache/munin/www
+logdir /var/log/munin
+rundir /var/run/munin
+
+# Where to look for the HTML templates
+tmpldir /etc/munin/templates
+
+# Make graphs show values per minute instead of per second
+#graph_period minute
+
+# Drop somejuser@fnord.comm and anotheruser@blibb.comm an email everytime
+# something changes (OK -> WARNING, CRITICAL -> OK, etc)
+#contact.someuser.command mail -s "Munin notification" somejuser@fnord.comm
+#contact.anotheruser.command mail -s "Munin notification" anotheruser@blibb.comm
+#
+# For those with Nagios, the following might come in handy. In addition,
+# the services must be defined in the Nagios server as well.
+#contact.nagios.command /usr/sbin/send_nsca -H nagios.host.com -c /etc/send_nsca.cfg
+
+#contacts me
+#contact.me.command mail -s "Munin notification ${var:group} :: ${var:host} :: ${var:graph_title}" root
+#contact.me.always_send warning critical
+
+# a simple host tree
+#[localhost]
+# address 127.0.0.1
+# use_node_name yes
+
+#
+# A more complex example of a host tree
+#
+## First our "normal" host.
+# [fii.foo.com]
+# address foo
+#
+## Then our other host...
+# [fay.foo.com]
+# address fay
+#
+## Then we want totals...
+# [foo.com;Totals] #Force it into the "foo.com"-domain...
+# update no # Turn off data-fetching for this "host".
+#
+# # The graph "load1". We want to see the loads of both machines...
+# # "fii=fii.foo.com:load.load" means "label=machine:graph.field"
+# load1.graph_title Loads side by side
+# load1.graph_order fii=fii.foo.com:load.load fay=fay.foo.com:load.load
+#
+# # The graph "load2". Now we want them stacked on top of each other.
+# load2.graph_title Loads on top of each other
+# load2.dummy_field.stack fii=fii.foo.com:load.load fay=fay.foo.com:load.load
+# load2.dummy_field.draw AREA # We want area instead the default LINE2.
+# load2.dummy_field.label dummy # This is needed. Silly, really.
+#
+# # The graph "load3". Now we want them summarised into one field
+# load3.graph_title Loads summarised
+# load3.combined_loads.sum fii.foo.com:load.load fay.foo.com:load.load
+# load3.combined_loads.label Combined loads # Must be set, as this is
+# # not a dummy field!
+#
+## ...and on a side note, I want them listen in another order (default is
+## alphabetically)
+#
+# # Since [foo.com] would be interpreted as a host in the domain "com", we
+# # specify that this is a domain by adding a semicolon.
+# [foo.com;]
+# node_order Totals fii.foo.com fay.foo.com
+#
+
diff --git a/files/config/host/munin.conf.header.Debian.wheezy b/files/config/host/munin.conf.header.Debian.wheezy
index 5fa2037..771d50d 120000..100644
--- a/files/config/host/munin.conf.header.Debian.wheezy
+++ b/files/config/host/munin.conf.header.Debian.wheezy
@@ -1 +1,75 @@
-munin.conf.header.Debian.squeeze \ No newline at end of file
+# Example configuration file for Munin, generated by 'make build'
+
+# The next three variables specifies where the location of the RRD
+# databases, the HTML output, and the logs, severally. They all
+# must be writable by the user running munin-cron.
+dbdir /var/lib/munin
+htmldir /var/cache/munin/www
+logdir /var/log/munin
+rundir /var/run/munin
+
+# Where to look for the HTML templates
+tmpldir /etc/munin/templates
+
+# Make graphs show values per minute instead of per second
+#graph_period minute
+
+# Drop somejuser@fnord.comm and anotheruser@blibb.comm an email everytime
+# something changes (OK -> WARNING, CRITICAL -> OK, etc)
+#contact.someuser.command mail -s "Munin notification" somejuser@fnord.comm
+#contact.anotheruser.command mail -s "Munin notification" anotheruser@blibb.comm
+#
+# For those with Nagios, the following might come in handy. In addition,
+# the services must be defined in the Nagios server as well.
+#contact.nagios.command /usr/sbin/send_nsca -H nagios.host.com -c /etc/send_nsca.cfg
+
+#contacts me
+#contact.me.command mail -s "Munin notification ${var:group} :: ${var:host} :: ${var:graph_title}" root
+#contact.me.always_send warning critical
+
+# a simple host tree
+#[localhost]
+# address 127.0.0.1
+# use_node_name yes
+
+#
+# A more complex example of a host tree
+#
+## First our "normal" host.
+# [fii.foo.com]
+# address foo
+#
+## Then our other host...
+# [fay.foo.com]
+# address fay
+#
+## Then we want totals...
+# [foo.com;Totals] #Force it into the "foo.com"-domain...
+# update no # Turn off data-fetching for this "host".
+#
+# # The graph "load1". We want to see the loads of both machines...
+# # "fii=fii.foo.com:load.load" means "label=machine:graph.field"
+# load1.graph_title Loads side by side
+# load1.graph_order fii=fii.foo.com:load.load fay=fay.foo.com:load.load
+#
+# # The graph "load2". Now we want them stacked on top of each other.
+# load2.graph_title Loads on top of each other
+# load2.dummy_field.stack fii=fii.foo.com:load.load fay=fay.foo.com:load.load
+# load2.dummy_field.draw AREA # We want area instead the default LINE2.
+# load2.dummy_field.label dummy # This is needed. Silly, really.
+#
+# # The graph "load3". Now we want them summarised into one field
+# load3.graph_title Loads summarised
+# load3.combined_loads.sum fii.foo.com:load.load fay.foo.com:load.load
+# load3.combined_loads.label Combined loads # Must be set, as this is
+# # not a dummy field!
+#
+## ...and on a side note, I want them listen in another order (default is
+## alphabetically)
+#
+# # Since [foo.com] would be interpreted as a host in the domain "com", we
+# # specify that this is a domain by adding a semicolon.
+# [foo.com;]
+# node_order Totals fii.foo.com fay.foo.com
+#
+
diff --git a/files/plugins/kvm_cpu b/files/plugins/kvm_cpu
new file mode 100644
index 0000000..f48d9f0
--- /dev/null
+++ b/files/plugins/kvm_cpu
@@ -0,0 +1,101 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# vim: set fileencoding=utf-8
+#
+# Munin plugin to show CPU used by vm
+#
+# Copyright Maxence Dunnewind, Rodolphe Quiédeville
+#
+# License : GPLv3
+#
+# parsed environment variables:
+# vmsuffix: part of vm name to be removed
+#
+#%# capabilities=autoconf
+#%# family=contrib
+
+import re, os, sys
+from subprocess import Popen, PIPE
+
+def config(vm_names):
+ ''' Print the plugin's config
+ @param vm_names : a list of "cleaned" vms' name
+ '''
+ percent = len(filter(lambda x: x[0:3] == 'cpu' and x[3] != ' ', open('/proc/stat', 'r').readlines())) * 100
+
+ base_config = """graph_title KVM Virtual Machine CPU usage
+graph_vlabel %%
+graph_category KVM
+graph_scale no
+graph_period second
+graph_info This graph shows the current CPU used by virtual machines
+graph_args --base 1000 -r --lower-limit 0 --upper-limit %d""" % percent
+ print base_config
+ draw = "AREA"
+ for vm in vm_names:
+ print "%s_cpu.label %s" % (vm, vm)
+ print "%s_cpu.min 0" % vm
+ print "%s_cpu.type DERIVE" % vm
+ print "%s_cpu.draw %s" % (vm, draw)
+ print "%s_cpu.info percent of cpu time used by virtual machine" % vm
+ draw = "STACK"
+
+
+def clean_vm_name(vm_name):
+ ''' Replace all special chars
+ @param vm_name : a vm's name
+ @return cleaned vm's name
+ '''
+
+ # suffix part defined in conf
+ suffix = os.getenv('vmsuffix')
+ if suffix:
+ vm_name = re.sub(suffix,'',vm_name)
+
+ return re.sub(r"[^a-zA-Z0-9_]", "_", vm_name)
+
+def detect_kvm():
+ ''' Check if kvm is installed
+ '''
+ kvm = Popen("which kvm", shell=True, stdout=PIPE)
+ kvm.communicate()
+ return not bool(kvm.returncode)
+
+def find_vm_names(pids):
+ '''Find and clean vm names from pids
+ @return a dictionnary of {pids : cleaned vm name}
+ '''
+ result = {}
+ for pid in pids:
+ cmdline = open("/proc/%s/cmdline" % pid, "r")
+ result[pid] = clean_vm_name(re.sub(r"^.*-name\x00([a-zA-Z0-9.-]*)\x00\-.*$",r"\1", cmdline.readline()))
+ return result
+
+def list_pids():
+ ''' Find the pid of kvm processes
+ @return a list of pids from running kvm
+ '''
+ pid = Popen("pidof qemu-kvm kvm", shell=True, stdout=PIPE)
+ return pid.communicate()[0].split()
+
+def fetch(vms):
+ ''' Fetch values for a list of pids
+ @param dictionnary {kvm_pid: cleaned vm name}
+ '''
+ for ( pid, name ) in vms.iteritems():
+ ( user, system ) = open("/proc/%s/stat" % pid, 'r').readline().split(' ')[13:15]
+ print '%s_cpu.value %d' % ( name, int(user) + int(system) )
+
+if __name__ == "__main__":
+ if len(sys.argv) > 1:
+ if sys.argv[1] in ['autoconf', 'detect']:
+ if detect_kvm():
+ print "yes"
+ else:
+ print "no"
+ elif sys.argv[1] == "config":
+ config(find_vm_names(list_pids()).values())
+ else:
+ fetch(find_vm_names(list_pids()))
+ else:
+ fetch(find_vm_names(list_pids()))
diff --git a/files/plugins/kvm_io b/files/plugins/kvm_io
new file mode 100644
index 0000000..43941f5
--- /dev/null
+++ b/files/plugins/kvm_io
@@ -0,0 +1,109 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# vim: set fileencoding=utf-8
+#
+# Munin plugin to show io by vm
+#
+# Copyright Maxence Dunnewind, Rodolphe Quiédeville
+#
+# License : GPLv3
+#
+# parsed environment variables:
+# vmsuffix: part of vm name to be removed
+#
+#%# capabilities=autoconf
+#%# family=contrib
+
+import re, os, sys
+from subprocess import Popen, PIPE
+
+def config(vm_names):
+ ''' Print the plugin's config
+ @param vm_names : a list of "cleaned" vms' name
+ '''
+ base_config = """graph_title KVM Virtual Machine IO usage
+graph_vlabel Bytes read(-)/written(+) per second
+graph_category KVM
+graph_info This graph shows the block device I/O used of virtual machines
+graph_args --base 1024"""
+ print base_config
+
+ for vm in vm_names:
+ print "%s_read.label %s" % (vm, vm)
+ print "%s_read.type COUNTER" % vm
+ print "%s_read.min 0" % vm
+ print "%s_read.draw LINE1" % vm
+ print "%s_read.info I/O used by virtual machine %s" % (vm, vm)
+ print "%s_write.label %s" % (vm, vm)
+ print "%s_write.type COUNTER" % vm
+ print "%s_write.min 0" % vm
+ print "%s_write.draw LINE1" % vm
+ print "%s_write.negative %s_read" % (vm, vm)
+ print "%s_write.info I/O used by virtual machine %s" % (vm, vm)
+
+def clean_vm_name(vm_name):
+ ''' Replace all special chars
+ @param vm_name : a vm's name
+ @return cleaned vm's name
+ '''
+ # suffix part defined in conf
+ suffix = os.getenv('vmsuffix')
+ if suffix:
+ vm_name = re.sub(suffix,'',vm_name)
+
+ return re.sub(r"[^a-zA-Z0-9_]", "_", vm_name)
+
+def fetch(vms):
+ ''' Fetch values for a list of pids
+ @param dictionnary {kvm_pid: cleaned vm name}
+ '''
+ res = {}
+ for pid in vms:
+ f = open("/proc/%s/io" % pid, "r")
+ for line in f.readlines():
+ if "read_bytes" in line:
+ read = line.split()[1]
+ print "%s_read.value %s" % (vms[pid], read)
+ if "write_bytes" in line:
+ write = line.split()[1]
+ print "%s_write.value %s" % (vms[pid], write)
+ break
+ f.close()
+
+def detect_kvm():
+ ''' Check if kvm is installed
+ '''
+ kvm = Popen("which kvm", shell=True, stdout=PIPE)
+ kvm.communicate()
+ return not bool(kvm.returncode)
+
+def find_vm_names(pids):
+ '''Find and clean vm names from pids
+ @return a dictionnary of {pids : cleaned vm name}
+ '''
+ result = {}
+ for pid in pids:
+ cmdline = open("/proc/%s/cmdline" % pid, "r")
+ result[pid] = clean_vm_name(re.sub(r"^.*-name\x00([a-zA-Z0-9.-]*)\x00\-.*$",r"\1", cmdline.readline()))
+ return result
+
+def list_pids():
+ ''' Find the pid of kvm processes
+ @return a list of pids from running kvm
+ '''
+ pid = Popen("pidof qemu-kvm kvm", shell=True, stdout=PIPE)
+ return pid.communicate()[0].split()
+
+if __name__ == "__main__":
+ if len(sys.argv) > 1:
+ if sys.argv[1] in ['autoconf', 'detect']:
+ if detect_kvm():
+ print "yes"
+ else:
+ print "no"
+ elif sys.argv[1] == "config":
+ config(find_vm_names(list_pids()).values())
+ else:
+ fetch(find_vm_names(list_pids()))
+ else:
+ fetch(find_vm_names(list_pids()))
diff --git a/files/plugins/kvm_mem b/files/plugins/kvm_mem
new file mode 100644
index 0000000..14fb793
--- /dev/null
+++ b/files/plugins/kvm_mem
@@ -0,0 +1,106 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# vim: set fileencoding=utf-8
+#
+# Munin plugin to show amount of memory used by vm
+#
+# Copyright Maxence Dunnewind, Rodolphe Quiédeville, Adrien Pujol
+#
+# License : GPLv3
+#
+# parsed environment variables:
+# vmsuffix: part of vm name to be removed
+#
+#%# capabilities=autoconf
+#%# family=contrib
+
+import re, os, sys
+from subprocess import Popen, PIPE
+
+def config(vm_names):
+ ''' Print the plugin's config
+ @param vm_names : a list of "cleaned" vms' name
+ '''
+ base_config = """graph_title KVM Virtual Machine Memory usage
+graph_vlabel Bytes
+graph_category KVM
+graph_info This graph shows the current amount of memory used by virtual machines
+graph_args --base 1024"""
+ print base_config
+ draw = "AREA"
+ for vm in vm_names:
+ print "%s_mem.label %s" % (vm, vm)
+ print "%s_mem.type GAUGE" % vm
+ if draw == 'AREA':
+ print "%s_mem.min 0" % vm
+ print "%s_mem.draw %s" % (vm, draw)
+ print "%s_mem.info memory used by virtual machine %s" % (vm, vm)
+ draw = "STACK"
+
+
+def clean_vm_name(vm_name):
+ ''' Replace all special chars
+ @param vm_name : a vm's name
+ @return cleaned vm's name
+ '''
+ # suffix part defined in conf
+ suffix = os.getenv('vmsuffix')
+ if suffix:
+ vm_name = re.sub(suffix,'',vm_name)
+
+ return re.sub(r"[^a-zA-Z0-9_]", "_", vm_name)
+
+def fetch(vms):
+ ''' Fetch values for a list of pids
+ @param dictionnary {kvm_pid: cleaned vm name}
+ '''
+ res = {}
+ for pid in vms:
+ try:
+ cmdline = open("/proc/%s/cmdline" % pid, "r")
+ amount = re.sub(r"^.*-m\x00(.*)\x00-smp.*$",r"\1", cmdline.readline())
+ ammount = int(amount) * 1024 * 1024
+ print "%s_mem.value %s" % (vms[pid], ammount)
+ except:
+ cmdline = open("/proc/%s/cmdline" % pid, "r")
+ amount = re.sub(r"^.*-m\x00(\d+).*$",r"\1", cmdline.readline())
+ ammount = int(amount) * 1024 * 1024
+ print "%s_mem.value %s" % (vms[pid], ammount)
+
+def detect_kvm():
+ ''' Check if kvm is installed
+ '''
+ kvm = Popen("which kvm", shell=True, stdout=PIPE)
+ kvm.communicate()
+ return not bool(kvm.returncode)
+
+def find_vm_names(pids):
+ '''Find and clean vm names from pids
+ @return a dictionnary of {pids : cleaned vm name}
+ '''
+ result = {}
+ for pid in pids:
+ cmdline = open("/proc/%s/cmdline" % pid, "r")
+ result[pid] = clean_vm_name(re.sub(r"^.*-name\x00([a-zA-Z0-9.-]*)\x00\-.*$",r"\1", cmdline.readline()))
+ return result
+
+def list_pids():
+ ''' Find the pid of kvm processes
+ @return a list of pids from running kvm
+ '''
+ pid = Popen("pidof qemu-kvm kvm", shell=True, stdout=PIPE)
+ return pid.communicate()[0].split()
+
+if __name__ == "__main__":
+ if len(sys.argv) > 1:
+ if sys.argv[1] in ['autoconf', 'detect']:
+ if detect_kvm():
+ print "yes"
+ else:
+ print "no"
+ elif sys.argv[1] == "config":
+ config(find_vm_names(list_pids()).values())
+ else:
+ fetch(find_vm_names(list_pids()))
+ else:
+ fetch(find_vm_names(list_pids()))
diff --git a/files/plugins/kvm_net b/files/plugins/kvm_net
new file mode 100644
index 0000000..c7b5aca
--- /dev/null
+++ b/files/plugins/kvm_net
@@ -0,0 +1,148 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# vim: set fileencoding=utf-8
+#
+# Munin plugin to show the network I/O per vm
+# On redhat based systems
+#
+# Copyright Igor Borodikhin
+# Copyright Peter Meier
+#
+# License : GPLv3
+#
+#
+# parsed environment variables:
+# vmsuffix: part of vm name to be removed
+#
+#%# capabilities=autoconf
+#%# family=contrib
+
+import re, os, sys
+from subprocess import Popen, PIPE
+
+def config(vms):
+ ''' Print the plugin's config
+ @param vm_names : a list of "cleaned" vms' name
+ '''
+ base_config = """graph_title KVM Network I/O
+graph_vlabel Bytes rx(-)/tx(+) per second
+graph_category KVM
+graph_info This graph shows the network I/O of the virtual machines
+graph_args --base 1024"""
+ print base_config
+ for pid in vms:
+ macs = get_vm_macs(pid)
+ i = 0
+ for mac in macs:
+ print "%s_eth%s_in.label %s_eth%s" % (vms[pid],i, vms[pid], i)
+ print "%s_eth%s_in.type COUNTER" % (vms[pid], i)
+ print "%s_eth%s_in.min 0" % (vms[pid],i)
+ print "%s_eth%s_in.draw LINE2" % (vms[pid],i)
+ print "%s_eth%s_out.negative %s_eth%s_in" % (vms[pid], i, vms[pid], i)
+ print "%s_eth%s_out.label %s_eth%s" % (vms[pid], i, vms[pid], i)
+ print "%s_eth%s_out.type COUNTER" % (vms[pid], i)
+ print "%s_eth%s_out.min 0" % (vms[pid], i)
+ print "%s_eth%s_out.draw LINE2" % (vms[pid], i)
+ i += 1
+
+def clean_vm_name(vm_name):
+ ''' Replace all special chars
+ @param vm_name : a vm's name
+ @return cleaned vm's name
+ '''
+ # suffix part defined in conf
+ suffix = os.getenv('vmsuffix')
+ if suffix:
+ vm_name = re.sub(suffix,'',vm_name)
+
+ return re.sub(r"[^a-zA-Z0-9_]", "_", vm_name)
+
+def fetch(vms):
+ ''' Fetch values for a list of pids
+ @param dictionnary {kvm_pid: cleaned vm name}
+ '''
+ res = {}
+ macs_to_inf = find_macs_to_inf()
+ interfaces = {}
+ for e in Popen('cat /proc/net/dev | awk \'{ print $1 ":" $9 }\'', shell=True, stdout=PIPE).communicate()[0].split('\n'):
+ s = e.split(':')
+ if len(s) == 3:
+ interfaces[s[0]] = (s[1],s[2])
+ for pid in vms:
+ macs = get_vm_macs(pid)
+ i = 0
+ for mac in macs:
+ inf = macs_to_inf[mac]
+ values = interfaces[inf]
+ if len(values) == 2:
+ print "%s_eth%s_in.value %s" % (vms[pid], i, values[0])
+ print "%s_eth%s_out.value %s" % (vms[pid], i, values[1])
+ i += 1
+
+def detect_kvm():
+ ''' Check if kvm is installed
+ '''
+ kvm = Popen("which kvm", shell=True, stdout=PIPE)
+ kvm.communicate()
+ return not bool(kvm.returncode)
+
+def find_vm_names(pids):
+ '''Find and clean vm names from pids
+ @return a dictionnary of {pids : cleaned vm name}
+ '''
+ result = {}
+ for pid in pids:
+ cmdline = open("/proc/%s/cmdline" % pid, "r")
+ result[pid] = clean_vm_name(re.sub(r"^.*-name\x00([a-zA-Z0-9.-]*)\x00\-.*$",r"\1", cmdline.readline()))
+ return result
+
+def get_vm_macs(pid):
+ '''Find macs for a pid
+ @return the mac addresses for a specified pid
+ '''
+ cmdline = open("/proc/%s/cmdline" % pid, "r")
+ line = cmdline.readline()
+ # macs are fe:... on the host
+ macs = [ re.sub(r"^\d{2}",'fe',p.split('=')[1]) for p in line.split(",") if re.match(r"^mac(addr)?=",p) ]
+ return macs
+
+def list_pids():
+ ''' Find the pid of kvm processes
+ @return a list of pids from running kvm
+ '''
+ pid = Popen("pidof qemu-kvm kvm", shell=True, stdout=PIPE)
+ return pid.communicate()[0].split()
+
+def find_macs_to_inf():
+ ''' Find interfaces for vms
+ @return a dictionary of macs to inf
+ '''
+ result = {}
+ inf = ""
+ kvm = Popen("ip a | grep -E -A 1 '(tap|vnet)' | awk '{print $2}' | grep -v '^$'", shell=True, stdout=PIPE)
+ res = kvm.communicate()[0].split('\n')
+ for line in res:
+ if len(line) > 0:
+ if re.match(r"^tap.*", line):
+ inf = re.sub(r"(tap[^:]+):", r"\1", line)
+ elif re.match(r"^vnet.*", line):
+ inf = re.sub(r"(vnet[^:]+):", r"\1", line)
+ else:
+ result[line] = inf
+
+ return result
+
+if __name__ == "__main__":
+ if len(sys.argv) > 1:
+ if sys.argv[1] in ['autoconf', 'detect']:
+ if detect_kvm():
+ print "yes"
+ else:
+ print "no"
+ elif sys.argv[1] == "config":
+ config(find_vm_names(list_pids()))
+ else:
+ fetch(find_vm_names(list_pids()))
+ else:
+ fetch(find_vm_names(list_pids()))
+