Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / libvirt / kvm_net @ 67cc769c

Historique | Voir | Annoter | Télécharger (3,35 ko)

1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
# vim: set fileencoding=utf-8
4
#
5
# Munin plugin to show the network I/O per vm
6
#
7
# Copyright Igor Borodikhin
8
#
9
# License : GPLv3
10
#
11
#
12
# parsed environment variables:
13
# vmsuffix: part of vm name to be removed
14
#
15
#%# capabilities=autoconf
16
#%# family=contrib
17

    
18
import re, os, sys
19
from subprocess import Popen, PIPE
20

    
21

    
22
def config(vm_names):
23
    """ Print the plugin's config
24

    
25
    @param vm_names : a list of "cleaned" vms' name
26
    """
27
    base_config = """graph_title KVM Network I/O
28
graph_vlabel Bytes rx(-)/tx(+) per second
29
graph_category Virtualization
30
graph_info This graph shows the network I/O of the virtual machines
31
graph_args --base 1024
32
    """
33
    print(base_config)
34
    for vm in vm_names:
35
        print("%s_in.label %s" % (vm, vm))
36
        print("%s_in.type COUNTER" % vm)
37
        print("%s_in.min 0" % vm)
38
        print("%s_in.draw LINE2" % vm)
39
        print("%s_out.negative %s_in" % (vm, vm))
40
        print("%s_out.label %s" % (vm, vm))
41
        print("%s_out.type COUNTER" % vm)
42
        print("%s_out.min 0" % vm)
43
        print("%s_out.draw LINE2" % vm)
44

    
45

    
46
def clean_vm_name(vm_name):
47
    """ Replace all special chars
48

    
49
    @param vm_name : a vm's name
50
    @return cleaned vm's name
51
    """
52
    # suffix part defined in conf
53
    suffix = os.getenv("vmsuffix")
54
    if suffix:
55
        vm_name = re.sub(suffix, "", vm_name)
56
    return re.sub(r"[^a-zA-Z0-9_]", "_", vm_name)
57

    
58

    
59
def fetch(vms):
60
    """ Fetch values for a list of pids
61

    
62
    @param dictionnary {kvm_pid: cleaned vm name}
63
    """
64
    res = {}
65
    for pid in vms:
66
        tap = get_vm_mac(pid)
67
        try:
68
            f = open("/proc/net/dev", "r")
69
            for line in f.readlines():
70
                if tap in line:
71
                    print("%s_in.value %s" % (vms[pid], line.split()[1]))
72
                    print("%s_out.value %s" % (vms[pid], line.split()[9]))
73
                    break
74
        except Exception as inst:
75
            print(inst)
76
            continue
77

    
78

    
79
def detect_kvm():
80
    """ Check if kvm is installed """
81
    kvm = Popen("which kvm", shell=True, stdout=PIPE)
82
    kvm.communicate()
83
    return not bool(kvm.returncode)
84

    
85

    
86
def find_vm_names(pids):
87
    """Find and clean vm names from pids
88

    
89
    @return a dictionnary of {pids : cleaned vm name}
90
    """
91
    result = {}
92
    for pid in pids:
93
        cmdline = open("/proc/%s/cmdline" % pid, "r")
94
        result[pid] = clean_vm_name(re.sub(r"^.*-name\x00([a-zA-Z0-9.-_-]*)\x00\-.*$",r"\1", cmdline.readline()))
95
    return result
96

    
97

    
98
def get_vm_mac(pid):
99
    """Find and clean vm names from pids
100

    
101
    @return the mac address for a specified pid
102
    """
103
    cmdline = open("/proc/%s/cmdline" % pid, "r")
104
    line = cmdline.readline()
105
    mac = re.sub(r"^.*ifname=(tap[^,]+),.*$",r"\1", line)
106
    return mac
107

    
108

    
109
def list_pids():
110
    """ Find the pid of kvm processes
111

    
112
    @return a list of pids from running kvm
113
    """
114
    pid = Popen("pidof qemu-kvm qemu-system-x86_64 kvm", shell=True, stdout=PIPE)
115
    return pid.communicate()[0].split()
116

    
117

    
118
if __name__ == "__main__":
119
    if len(sys.argv) > 1:
120
        if sys.argv[1] in ["autoconf", "detect"]:
121
            if detect_kvm():
122
                print("yes")
123
            else:
124
                print("no")
125
        elif sys.argv[1] == "config":
126
            config(find_vm_names(list_pids()).values())
127
        else:
128
            fetch(find_vm_names(list_pids()))
129
    else:
130
        fetch(find_vm_names(list_pids()))