From b76174718ea3fa02271217a51de5a9b0c23893de Mon Sep 17 00:00:00 2001 From: Alois <11095760+AloisKlingler@users.noreply.github.com> Date: Tue, 16 Nov 2021 23:13:03 +0100 Subject: [PATCH] kvm_io now in python3 (#1254) * works on debian bullseye with this modification. * removed all codestyle issues, checked with "pycodestyle" on debian bullseye, besides two "line too long" * "config" param must not have newlines to avoid a warning in munin-update.log --- plugins/libvirt/kvm_io | 118 +++++++++++++++++++++++++---------------- 1 file changed, 73 insertions(+), 45 deletions(-) diff --git a/plugins/libvirt/kvm_io b/plugins/libvirt/kvm_io index fc82352d..50b0de7a 100755 --- a/plugins/libvirt/kvm_io +++ b/plugins/libvirt/kvm_io @@ -1,22 +1,47 @@ -#!/usr/bin/env 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 +#!/usr/bin/env python3 +""" +=encoding utf8 -import re, os, sys +=head1 NAME + +kvm_io - show IO usage of VM + + +=head1 CONFIGURATION + +Parsed environment variables: + + vmsuffix: part of VM name to be removed + + +=head1 LICENSE + +GPLv3 + +SPDX-License-Identifier: GPL-3.0-only + + +=head1 AUTHORS + +Maxence Dunnewind + +Rodolphe QuiƩdeville + + +=head1 MAGIC MARKERS + + #%# capabilities=autoconf + #%# family=contrib + +=cut +""" + +import re +import os +import sys from subprocess import Popen, PIPE + def config(vm_names): ''' Print the plugin's config @param vm_names : a list of "cleaned" vms' name @@ -25,21 +50,21 @@ def config(vm_names): graph_vlabel Bytes read(-)/written(+) per second graph_category virtualization graph_info This graph shows the block device I/O used of virtual machines -graph_args --base 1024 - """ - print base_config +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.info I/O used by virtual machine %s" % (vm, vm) - print "%s_read.graph no" % vm - print "%s_write.label %s" % (vm, vm) - print "%s_write.type COUNTER" % vm - print "%s_write.min 0" % vm - print "%s_write.negative %s_read" % (vm, vm) - print "%s_write.info I/O used by virtual machine %s" % (vm, vm) + print("%s_read.label %s" % (vm, vm)) + print("%s_read.type COUNTER" % vm) + print("%s_read.min 0" % vm) + print("%s_read.info I/O used by virtual machine %s" % (vm, vm)) + print("%s_read.graph no" % vm) + print("%s_write.label %s" % (vm, vm)) + print("%s_write.type COUNTER" % vm) + print("%s_write.min 0" % 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 @@ -49,7 +74,7 @@ def clean_vm_name(vm_name): # suffix part defined in conf suffix = os.getenv('vmsuffix') if suffix: - vm_name = re.sub(suffix,'',vm_name) + vm_name = re.sub(suffix, '', vm_name) # proxmox uses kvm with -name parameter parts = vm_name.split('\x00') if (parts[0].endswith('kvm')): @@ -59,22 +84,22 @@ def clean_vm_name(vm_name): pass return re.sub(r"[^a-zA-Z0-9_]", "_", vm_name) + def fetch(vms): ''' Fetch values for a list of pids @param dictionary {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() + with open("/proc/%s/io" % pid.decode(), "r") as f: + 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 + def detect_kvm(): ''' Check if kvm is installed @@ -83,16 +108,18 @@ def detect_kvm(): kvm.communicate() return not bool(kvm.returncode) + def find_vm_names(pids): '''Find and clean vm names from pids @return a dictionary 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"^.*guest=([a-zA-Z0-9.-_-]*).*$",r"\1", cmdline.readline())) + with open("/proc/%s/cmdline" % pid.decode(), "r") as cmdline: + result[pid] = clean_vm_name(re.sub(r"^.*guest=([a-zA-Z0-9.-_-]*).*$", r"\1", cmdline.readline())) return result + def list_pids(): ''' Find the pid of kvm processes @return a list of pids from running kvm @@ -100,13 +127,14 @@ def list_pids(): pid = Popen("pidof qemu-kvm qemu-system-x86_64 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" + print("yes") else: - print "no" + print("no (detect_kvm failed - is kvm installed?)") elif sys.argv[1] == "config": config(find_vm_names(list_pids()).values()) else: