Projet

Général

Profil

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

root / plugins / libvirt / kvm_net @ 3267bbd0

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

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

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

    
20

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

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

    
44

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

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

    
57

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

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

    
77

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

    
84

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

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

    
96

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

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

    
107

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

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

    
116

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