Handle libvirt errors and logging

This commit is contained in:
Théophile Bastian 2020-03-19 19:07:12 +01:00
parent 71b5d661c0
commit b9f9e7d1b0
2 changed files with 110 additions and 1 deletions

105
lxc_net/libvirt_error.py Normal file
View file

@ -0,0 +1,105 @@
from collections import namedtuple
import libvirt
import logging
logger = logging.getLogger(__name__)
class LibvirtErrorCode:
reverse_errors = {
getattr(libvirt, err_name): err_name
for err_name in filter(lambda x: x.startswith("VIR_ERR_"), libvirt.__dir__())
}
def __init__(self, code):
self.code = code
self.err = self.reverse_errors.get(code, None)
def __repr__(self):
return "{}".format(self.code)
def __str__(self):
return "{} [{}]".format(self.err, self.code)
def __eq__(self, val):
return self.code == val
class LibvirtErrorDomain:
reverse_domains = {
getattr(libvirt, err_name): err_name
for err_name in filter(lambda x: x.startswith("VIR_DOMAIN_"), libvirt.__dir__())
}
def __init__(self, code):
self.code = code
self.domain = self.reverse_domains.get(code, None)
def __repr__(self):
return "{}".format(self.code)
def __str__(self):
return "{} [{}]".format(self.domain, self.code)
def __eq__(self, val):
return self.code == val
class LibvirtError:
params = (
"code",
"domain",
"message",
"level",
"str1",
"str2",
"str3",
"int1",
"int2",
)
def __init__(self, code, domain, message, level, str1, str2, str3, int1, int2):
self.code = LibvirtErrorCode(code)
self.domain = LibvirtErrorDomain(domain)
self.message = message
self.level = level
self.str1 = str1
self.str2 = str2
self.str3 = str3
self.int1 = int1
self.int2 = int2
def __repr__(self):
out = "{}(".format(self.__class__.__name__)
for param in self.__class__.params:
out += "{}={}, ".format(param, getattr(self, param))
out += ")"
return out
def __str__(self):
return "Libvirt error {}, domain {}. {}".format(
self.code, self.domain, self.message
)
@property
def loglevel(self):
levelmap = {
0: logging.INFO,
1: logging.WARNING,
2: logging.ERROR,
}
return levelmap.get(self.level, logging.CRITICAL)
def libvirt_error_handler(_, raw_error):
""" Called upon libvirt error """
error = LibvirtError(*raw_error)
loglevel = error.loglevel
if error.code == libvirt.VIR_ERR_NO_DOMAIN:
loglevel = logging.DEBUG
logger.log(loglevel, str(error))

View file

@ -1,9 +1,10 @@
#!/usr/bin/env python3
from lxc_net import parse_network
from lxc_net import parse_network, libvirt_error
import signal
import libvirt
import argparse
import logging
def parse_args():
@ -28,6 +29,9 @@ def main():
signal.signal(signal.SIGINT, handle_sigint)
logging.basicConfig(level=logging.WARNING)
libvirt.registerErrorHandler(libvirt_error.libvirt_error_handler, None)
conn = libvirt.open("lxc:///")
topology = parse_network.YamlTopology(args.topology, conn)