[libvirt] [libvirt-test-API][PATCH 2/2] Add connection_getAllDomainStats test case

hujianwei jiahu at redhat.com
Thu Mar 12 07:14:09 UTC 2015


On 11/03/15 17:14, hongming wrote:
> Hi jiahu
>
> Please add the following api calling to your case, we can test them 
> using the same checking methods .
>
> def domainListGetStats(self, doms, stats=0, flags=0):
> """ Query statistics for given domains.
>
> Thanks
> Hongming
>
OK, the V2 patch series has been sent out, please review them.

BR,
Jianwei
> On 03/05/2015 04:02 PM, jiahu wrote:
>> The case will validate the getAllDomainStats API in class virConnect
>> ---
>>   repos/virconn/connection_getAllDomainStats.py | 528 
>> ++++++++++++++++++++++++++
>>   1 file changed, 528 insertions(+)
>>   create mode 100644 repos/virconn/connection_getAllDomainStats.py
>>
>> diff --git a/repos/virconn/connection_getAllDomainStats.py 
>> b/repos/virconn/connection_getAllDomainStats.py
>> new file mode 100644
>> index 0000000..023564a
>> --- /dev/null
>> +++ b/repos/virconn/connection_getAllDomainStats.py
>> @@ -0,0 +1,528 @@
>> +#!/usr/bin/env python
>> +# test getAllDomainStats() API for libvirt
>> +
>> +import libvirt
>> +
>> +from xml.dom import minidom
>> +from libvirt import libvirtError
>> +from src import sharedmod
>> +from utils import utils
>> +
>> +required_params = ()
>> +optional_params = {'stats': '','flags': ''}
>> +
>> +ds = {"state": libvirt.VIR_DOMAIN_STATS_STATE,
>> +      "cpu": libvirt.VIR_DOMAIN_STATS_CPU_TOTAL,
>> +      "balloon": libvirt.VIR_DOMAIN_STATS_BALLOON,
>> +      "vcpu": libvirt.VIR_DOMAIN_STATS_VCPU,
>> +      "interface": libvirt.VIR_DOMAIN_STATS_INTERFACE,
>> +      "block": libvirt.VIR_DOMAIN_STATS_BLOCK}
>> +
>> +fg = {"active": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE,
>> +      "inactive": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE,
>> +      "persistent": 
>> libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT,
>> +      "transient": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT,
>> +      "running": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_RUNNING,
>> +      "paused": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PAUSED,
>> +      "shutoff": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_SHUTOFF,
>> +      "other": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_OTHER,
>> +      "backing": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING,
>> +      "enforce": 
>> libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS}
>> +
>> +def filer_domains(logger, flags):
>> +    """
>> +       return a filtered domains set
>> +    """
>> +    a = set(active_domains(logger))
>> +    d = set(defined_domains(logger))
>> +    if flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT 
>> and \
>> +       flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT:
>> +        domains = a | d
>> +    elif flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT:
>> +        domains = d
>> +    elif flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT:
>> +        domains = a - d
>> +    else:
>> +        domains = a | d
>> +    if flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE and \
>> +       flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE:
>> +        domains &= (a | d)
>> +    elif flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE:
>> +        domains &= a
>> +    elif flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE:
>> +        domains &= (d - a)
>> +    else:
>> +        domains &= a | d
>> +    return domains
>> +
>> +def active_domains(logger):
>> +    """
>> +       return active domains on current uri
>> +    """
>> +    NUM = "ls /run/libvirt/qemu|grep \".xml\""
>> +    status, output = utils.exec_cmd(NUM, shell=True)
>> +    output = [item.replace(".xml","") for item in output]
>> +    if status == 0:
>> +        logger.debug("Got active domains: %s" % output)
>> +        return output
>> +    else:
>> +        logger.debug("Got active domains: %s" % output)
>> +        return output
>> +
>> +def defined_domains(logger):
>> +    """
>> +       return defined domains on current uri
>> +    """
>> +    NUM = "ls /etc/libvirt/qemu|grep \".xml\""
>> +    status, output = utils.exec_cmd(NUM, shell=True)
>> +    output = [item.replace(".xml","") for item in output]
>> +    if status == 0:
>> +        logger.debug("Got defined domains: %s" % output)
>> +        return output
>> +    else:
>> +        logger.debug("Got defined domains: %s" % output)
>> +        return output
>> +
>> +def compare_value(logger,op1,op2):
>> +    """
>> +       compare 2 variables value
>> +    """
>> +    if op1 != op2:
>> +        logger.debug("Check %s: Fail" % op2)
>> +        return False
>> +    else:
>> +        logger.debug("Check %s: Pass" % op2)
>> +        return True
>> +
>> +def check_vcpu(logger,dom_name,dom_active,dom_eles):
>> +    """
>> +       check vcpu info of given domain
>> +    """
>> +    iDOM_XML = "/etc/libvirt/qemu/" + dom_name +".xml"
>> +    aDOM_XML = "/run/libvirt/qemu/" + dom_name +".xml"
>> +    if dom_active:
>> +        xml = minidom.parse(aDOM_XML)
>> +        dom = xml.getElementsByTagName('domain')[0]
>> +        vcpu = dom.getElementsByTagName('vcpu')[0]
>> +        vcpu_max = int(vcpu.childNodes[0].data)
>> +        if not vcpu.getAttribute('current'):
>> +            vcpu_cur = vcpu_max
>> +        else:
>> +            vcpu_cur = int(vcpu.getAttribute('current'))
>> +
>> +        logger.debug("Checking vcpu.current: %d" \
>> +                % dom_eles.get("vcpu.current"))
>> +        if not compare_value(logger,vcpu_cur, \
>> +                dom_eles.get("vcpu.current")):
>> +            return False
>> +        logger.debug("Checking vcpu.maximum: %d" \
>> +                % dom_eles.get("vcpu.maximum"))
>> +        if not compare_value(logger,vcpu_max, \
>> +                dom_eles.get("vcpu.maximum")):
>> +            return False
>> +    else:
>> +        xml = minidom.parse(iDOM_XML)
>> +        vcpu = xml.getElementsByTagName('vcpu')[0]
>> +        vcpu_max = int(vcpu.childNodes[0].data)
>> +        logger.debug("Checking vcpu.maximum: %d" \
>> +                % dom_eles.get("vcpu.maximum"))
>> +        if not compare_value(logger,vcpu_max, \
>> +                dom_eles.get("vcpu.maximum")):
>> +            return False
>> +    #for each vcpu.state field
>> +    check_each_vcpu(logger,dom_name,dom_active,dom_eles)
>> +    return True
>> +
>> +def check_each_vcpu(logger,dom_name,dom_active,dom_eles):
>> +    """
>> +       check each vcpu info, but ignore vcpu.*.time
>> +    """
>> +    iDOM_XML = "/etc/libvirt/qemu/" + dom_name +".xml"
>> +    aDOM_XML = "/run/libvirt/qemu/" + dom_name +".xml"
>> +    vcpu_index = 0
>> +    if dom_active:
>> +        vcpu_stat = 1
>> +        xml = minidom.parse(aDOM_XML)
>> +        dom = xml.getElementsByTagName('vcpus')[0]
>> +        dom_pid = str(xml.getElementsByTagName("domstatus")[0].\
>> +                getAttributeNode('pid').nodeValue)
>> +        vcpu = dom.getElementsByTagName('vcpu')
>> +        for vcpu_sub in vcpu:
>> +            proc_path = "/proc/"
>> +            vcpu_pre = "vcpu."+ str(vcpu_index) + "."
>> +            attr1 = dom_eles.get(vcpu_pre +"state")
>> +            logger.debug("Checking %sstate: %d" %(vcpu_pre, attr1))
>> +            if not compare_value(logger,vcpu_stat, attr1):
>> +                return False
>> +            vcpu_index +=1
>> +    else:
>> +        vcpu_stat = 0
>> +        xml = minidom.parse(iDOM_XML)
>> +        vcpu = xml.getElementsByTagName('vcpu')[0]
>> +        vcpu_max = int(vcpu.childNodes[0].data)
>> +        vcpu_cur = vcpu.getAttributeNode('current')
>> +        if not vcpu_cur:
>> +            for i in range(0,vcpu_max):
>> +                vcpu_pre = "vcpu."+ str(i) + "."
>> +                logger.debug("Checking %sstate: %d" \
>> +                        %(vcpu_pre, dom_eles.get(vcpu_pre + "state")))
>> +                if not compare_value(logger,vcpu_stat, \
>> +                        dom_eles.get(vcpu_pre + "state")):
>> +                    return False
>> +        elif int(vcpu_cur.nodeValue) <= vcpu_max:
>> +            for i in range(0,int(vcpu_cur.nodeValue)):
>> +                vcpu_pre = "vcpu."+ str(i) + "."
>> +                logger.debug("Checking %sstate: %d" \
>> +                        %(vcpu_pre, dom_eles.get(vcpu_pre + "state")))
>> +                if not compare_value(logger,vcpu_stat, \
>> +                        dom_eles.get(vcpu_pre + "state")):
>> +                    return False
>> +    return True
>> +
>> +def check_balloon(logger,dom_name,dom_active,dom_eles):
>> +    """
>> +       check balloon of given domain
>> +    """
>> +    iDOM_XML = "/etc/libvirt/qemu/" + dom_name +".xml"
>> +    aDOM_XML = "/run/libvirt/qemu/" + dom_name +".xml"
>> +    if dom_active:
>> +        xml = minidom.parse(aDOM_XML)
>> +        dom = xml.getElementsByTagName('domain')[0]
>> +        mem_max = int(dom.getElementsByTagName('memory')[0]\
>> +                .childNodes[0].data)
>> +        mem_cur = int(dom.getElementsByTagName('currentMemory')[0]\
>> +                .childNodes[0].data)
>> +        logger.debug("Checking balloon.maximum: %d" \
>> +                % dom_eles.get("balloon.maximum"))
>> +        if not compare_value(logger,mem_max, \
>> +                dom_eles.get("balloon.maximum")):
>> +            return False
>> +        logger.debug("Checking balloon.current: %d" \
>> +                % dom_eles.get("balloon.current"))
>> +        if not compare_value(logger,mem_cur, \
>> +                dom_eles.get("balloon.current")):
>> +            return False
>> +    else:
>> +        xml = minidom.parse(iDOM_XML)
>> +        mem_max = int(xml.getElementsByTagName('memory')[0].\
>> +                childNodes[0].data)
>> +        logger.debug("Checking balloon.maximum: %d" \
>> +                % dom_eles.get("balloon.maximum"))
>> +        if not compare_value(logger,mem_max, \
>> +                dom_eles.get("balloon.maximum")):
>> +            return False
>> +    return True
>> +
>> +def check_interface(logger,dom_name,dom_active, dom_eles):
>> +    """
>> +       check interface info, only check the count and name attributes
>> +       other sub-attributes of net.* will be ignored
>> +    """
>> +    iDOM_XML = "/etc/libvirt/qemu/" + dom_name +".xml"
>> +    aDOM_XML = "/run/libvirt/qemu/" + dom_name +".xml"
>> +    netfile = "/proc/net/dev"
>> +    if dom_active:
>> +        xml = minidom.parse(aDOM_XML)
>> +        dom = xml.getElementsByTagName('domain')[0]
>> +        dev = dom.getElementsByTagName('devices')[0]
>> +        nic = dev.getElementsByTagName('interface')
>> +        logger.debug("Checking net.count: %d" % 
>> dom_eles.get("net.count"))
>> +        if not 
>> compare_value(logger,len(nic),dom_eles.get("net.count")):
>> +            return False
>> +        for iface in nic:
>> +            if_name = iface.getElementsByTagName("target")[0].\
>> +                    getAttribute('dev')
>> +            if_name += ":"
>> +            logger.debug("Checking %s" % if_name)
>> +            content = open(netfile, 'r')
>> +            if if_name in str(content.readlines()):
>> +                logger.debug("Check %s: Pass" % if_name)
>> +            else:
>> +                logger.debug("Check %s: Fail" % if_name)
>> +                return False
>> +            content.close()
>> +    else:
>> +        pass
>> +    return True
>> +
>> +def count_disk_chain(logger,filepath,dom_active):
>> +    """
>> +       count deep of disk chain
>> +    """
>> +    CMD = "file %s"
>> +    num = 0
>> +    while True:
>> +        status, output = utils.exec_cmd(CMD % filepath, shell=True)
>> +        if status != 0:
>> +            logger.debug("Can not see the back file")
>> +        if "has backing file" in output[0]:
>> +            num +=1
>> +            filepath = 
>> output[0].split("(path")[1].split(")")[0].strip()
>> +        else:
>> +            break
>> +        if not dom_active:
>> +            break
>> +    return num
>> +
>> +def check_block(logger,dom_name,dom_active,dom_eles,backing_f):
>> +    """
>> +       check the block info, only check count, name and path 
>> attributes,
>> +       other sub-attributes of block.* will be ignored
>> +    """
>> +    iDOM_XML = "/etc/libvirt/qemu/" + dom_name +".xml"
>> +    aDOM_XML = "/run/libvirt/qemu/" + dom_name +".xml"
>> +    disk_index = 0
>> +    if dom_active:
>> +        xml = minidom.parse(aDOM_XML)
>> +        dom = xml.getElementsByTagName('domain')[0]
>> +        dev = dom.getElementsByTagName('devices')[0]
>> +        disk = dev.getElementsByTagName('disk')
>> +        disk_count = len(disk)
>> +        for dk in disk:
>> +            disk_name = dk.getElementsByTagName('target')[0]\
>> +                    .getAttributeNode('dev').nodeValue
>> +            disk_sour = dk.getElementsByTagName('source')[0]\
>> +                    .getAttributeNode('file').nodeValue
>> +            if backing_f:
>> +                disk_count += 
>> count_disk_chain(logger,disk_sour,dom_active)
>> +        logger.debug("Checking disk.count: %d" % 
>> dom_eles.get("block.count"))
>> +        if not 
>> compare_value(logger,disk_count,dom_eles.get("block.count")):
>> +            return False
>> +        if not check_each_block(logger,dom_name,dom_eles,backing_f):
>> +            return False
>> +    else:
>> +        xml = minidom.parse(iDOM_XML)
>> +        dev = xml.getElementsByTagName('devices')[0]
>> +        disk = dev.getElementsByTagName('disk')
>> +        disk_count = len(disk)
>> +        logger.debug("Checking disk.count: %d" % 
>> dom_eles.get("block.count"))
>> +        if not 
>> compare_value(logger,disk_count,dom_eles.get("block.count")):
>> +            return False
>> +        for dk in disk:
>> +            disk_pre = "block."+ str(disk_index) + "."
>> +            disk_name = dk.getElementsByTagName('target')[0]\
>> +                    .getAttributeNode('dev').nodeValue
>> +            logger.debug("Checking %sname: %s" \
>> +                    % (disk_pre, dom_eles.get(disk_pre + "name")))
>> +            if not compare_value(logger,disk_name,\
>> +                    dom_eles.get(disk_pre + "name")):
>> +                return False
>> +            disk_sour = dk.getElementsByTagName('source')[0]\
>> +                    .getAttributeNode('file').nodeValue
>> +            logger.debug("Checking %spath: %s" \
>> +                    % (disk_pre, dom_eles.get(disk_pre + "path")))
>> +            if not compare_value(logger,disk_sour,\
>> +                    dom_eles.get(disk_pre + "path")):
>> +                return False
>> +            disk_index += 1
>> +    return True
>> +
>> +def check_each_block(logger,dom_name,dom_eles,backing_f):
>> +    """
>> +       for a active domain, this function will list all backing
>> +       block info
>> +    """
>> +    aDOM_XML = "/run/libvirt/qemu/" + dom_name +".xml"
>> +    disk_index = 0
>> +    xml = minidom.parse(aDOM_XML)
>> +    dom = xml.getElementsByTagName('domain')[0]
>> +    dev = dom.getElementsByTagName('devices')[0]
>> +    disk = dev.getElementsByTagName('disk')
>> +    for dk in disk:
>> +        disk_pre = "block."+ str(disk_index) + "."
>> +        disk_name = dk.getElementsByTagName('target')[0]\
>> +                .getAttributeNode('dev').nodeValue
>> +        disk_sour = dk.getElementsByTagName('source')[0]\
>> +                .getAttributeNode('file').nodeValue
>> +        logger.debug("Checking %s %s" % (disk_name,disk_sour))
>> +        if not compare_value(logger,disk_name, \
>> +                dom_eles.get(disk_pre + "name")):
>> +            return False
>> +        if not compare_value(logger,disk_sour, \
>> +                dom_eles.get(disk_pre + "path")):
>> +            return False
>> +        if not backing_f:
>> +            disk_index += 1
>> +            continue
>> +        while True:
>> +            temp = dk.getElementsByTagName('backingStore')[0]
>> +            if temp.hasChildNodes():
>> +                temp_name = disk_name
>> +                temp_backingIndex = 
>> int(temp.getAttributeNode('index').\
>> +                        nodeValue)
>> +                temp_path = temp.getElementsByTagName('source')[0].\
>> +                        getAttributeNode('file').nodeValue
>> +                logger.debug("Checking %s %s %s" \
>> +                        % (temp_name, temp_backingIndex, temp_path))
>> +                disk_index += 1
>> +                disk_pre = "block."+ str(disk_index) + "."
>> +                if not compare_value(logger,temp_name, \
>> +                        dom_eles.get(disk_pre + "name")):
>> +                    return False
>> +                if not compare_value(logger,temp_backingIndex, \
>> +                        dom_eles.get(disk_pre + "backingIndex")):
>> +                    return False
>> +                if not compare_value(logger,temp_path, \
>> +                        dom_eles.get(disk_pre + "path")):
>> +                    return False
>> +            else:
>> +                break
>> +            dk = temp
>> +        disk_index += 1
>> +    return True
>> +
>> +def connection_getAllDomainStats(params):
>> +    """
>> +       test API for getAllDomainStats in class virConnect, the 
>> script need
>> +       static values to compare with those returned by API,but they are
>> +       hard to calculate, so ignore below attributes temporarily:
>> +           cpu.time
>> +           cpu.user
>> +           cpu.system
>> +           *.*.time
>> +           net.*.rx.*
>> +           net.*.tx.*
>> +           block.*.rd
>> +           block.*.wr
>> +           block.*.fl
>> +           ...
>> +      for below two attributes, no good method to obtain values when
>> +      out of libvirt, pass them temporarily too.
>> +           state.state
>> +           state.reason
>> +    """
>> +    balloon_f = False
>> +    vcpu_f = False
>> +    interface_f = False
>> +    block_f = False
>> +    backing_f = False
>> +    filter_f = True
>> +
>> +    logger = params['logger']
>> +    domstats = params.get('stats', "all")
>> +    domstats_string = domstats.split("|")
>> +    logger.info("The stats are %s" % domstats)
>> +    domstats = 0
>> +    for domstat in domstats_string:
>> +        if domstat == 'state':
>> +            domstats |= ds.get('state')
>> +        elif domstat == 'cpu':
>> +            domstats |= ds.get('cpu')
>> +        elif domstat == 'balloon':
>> +            domstats |= ds.get('balloon')
>> +            balloon_f = True
>> +        elif domstat == 'vcpu':
>> +            domstats |= ds.get('vcpu')
>> +            vcpu_f = True
>> +        elif domstat == 'interface':
>> +            domstats |= ds.get('interface')
>> +            interface_f = True
>> +        elif domstat == 'block':
>> +            domstats |= ds.get('block')
>> +            block_f = True
>> +        elif domstat == "all":
>> +            domstats = 0
>> +            balloon_f = True
>> +            vcpu_f = True
>> +            interface_f = True
>> +            block_f = True
>> +        else:
>> +            logger.error("Unknown flags")
>> +            return 1
>> +    logger.info("The given stats is %d" % domstats)
>> +
>> +    flags = params.get('flags',"all")
>> +    logger.info("The flags are %s" % flags)
>> +    flags_string = flags.split("|")
>> +    flags = 0
>> +    for flag in flags_string:
>> +        if flag == 'active':
>> +            flags |= fg.get('active')
>> +        elif flag == 'inactive':
>> +            flags |= fg.get('inactive')
>> +        elif flag == 'persistent':
>> +            flags |= fg.get('persistent')
>> +        elif flag == 'transient':
>> +            flags |= fg.get('transient')
>> +        elif flag == 'running':
>> +            flags |= fg.get('running')
>> +            filter_f = False
>> +        elif flag == 'paused':
>> +            flags |= fg.get('paused')
>> +            filter_f = False
>> +        elif flag == 'shutoff':
>> +            flags |= fg.get('shutoff')
>> +            filter_f = False
>> +        elif flag == 'other':
>> +            flags |= fg.get('other')
>> +            filter_f = False
>> +        elif flag == 'backing':
>> +            flags |= fg.get('backing')
>> +            backing_f = True
>> +        elif flag == 'enforce':
>> +            flags |= fg.get('enforce')
>> +        elif flag == 'all':
>> +            flags = 0
>> +            filter_f = False
>> +        else:
>> +            logger.error("Unknown flags")
>> +            return 1
>> +    logger.info("The given flags is %d" % flags)
>> +
>> +    try:
>> +        conn = sharedmod.libvirtobj['conn']
>> +
>> +        domstats_from_api = conn.getAllDomainStats(domstats,flags)
>> +        logger.info("Got the number of domain from API: %s" \
>> +                % len(domstats_from_api))
>> +        #filter expected domains
>> +        domains = filer_domains(logger,flags)
>> +        if not filter_f:
>> +            logger.info("Check the number of domain: Skip")
>> +        elif len(domains) == len(domstats_from_api):
>> +            logger.info("Available domains: %s" % list(domains))
>> +            logger.info("Check the number of domain %s: Pass" \
>> +                    % len(domstats_from_api))
>> +        else:
>> +            logger.info("Available domains: %s" % list(domains))
>> +            logger.info("Check the number of domain %s: Fail" \
>> +                    % len(domstats_from_api))
>> +            return 1
>> +
>> +        for dom in domstats_from_api:
>> +            dom_name = dom[0].name()
>> +            dom_active = dom[0].isActive()
>> +            dom_eles = dom[1]
>> +            logger.debug("Domain elements are %s" %(dom_eles))
>> +            logger.info("Checking %s:" %(dom_name))
>> +            if vcpu_f:
>> +                if not check_vcpu(logger,dom_name,dom_active,dom_eles):
>> +                    logger.info("Failed to check vcpu states")
>> +                    return 1
>> +                else:
>> +                    logger.info("Success to check vcpu state")
>> +            if balloon_f:
>> +                if not 
>> check_balloon(logger,dom_name,dom_active,dom_eles):
>> +                    logger.info("Failed to check balloon state")
>> +                    return 1
>> +                else:
>> +                    logger.info("Success to check balloon state")
>> +            if interface_f:
>> +                if not 
>> check_interface(logger,dom_name,dom_active,dom_eles):
>> +                    logger.info("Failed to check interface state")
>> +                    return 1
>> +                else:
>> +                    logger.info("Success to check interface state")
>> +            if block_f:
>> +                if not check_block(logger,dom_name,dom_active,\
>> +                        dom_eles,backing_f):
>> +                    logger.info("Failed to check block state")
>> +                    return 1
>> +                else:
>> +                    logger.info("Success to check block state")
>> +
>> +    except libvirtError, e:
>> +        logger.error("API error message: %s" % e.message)
>> +        return 1
>> +
>> +    return 0
>




More information about the libvir-list mailing list