[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [test-API][PATCH] Add test case of set vcpus with flags



Use setVcpusFlags API to set domain vcpu with flags, domain could
be active or not. Flags could be '0', 'live', 'config', 'maximum'
and their combinations, use '|' between flags for combinations. A
sample conf file also added.

Signed-off-by: Wayne Sun <gsun redhat com>
---
 cases/set_vcpus_flags.conf      |   56 ++++++++
 repos/domain/set_vcpus_flags.py |  283 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 339 insertions(+), 0 deletions(-)
 create mode 100644 cases/set_vcpus_flags.conf
 create mode 100644 repos/domain/set_vcpus_flags.py

diff --git a/cases/set_vcpus_flags.conf b/cases/set_vcpus_flags.conf
new file mode 100644
index 0000000..7da13a2
--- /dev/null
+++ b/cases/set_vcpus_flags.conf
@@ -0,0 +1,56 @@
+domain:install_linux_cdrom
+    guestname
+        $defaultname
+    guestos
+        $defaultos
+    guestarch
+        $defaultarch
+    vcpu
+        $defaultvcpu
+    memory
+        $defaultmem
+    hddriver
+        $defaulthd
+    nicdriver
+        $defaultnic
+    imageformat
+        qcow2
+
+domain:set_vcpus_flags
+    guestname
+        $defaultname
+    vcpu
+        4
+    flags
+        0|config|live
+    username
+        $username
+    password
+        $password
+
+domain:destroy
+    guestname
+        $defaultname
+
+domain:set_vcpus_flags
+    guestname
+        $defaultname
+    vcpu
+        5
+    flags
+        0|config
+
+domain:set_vcpus_flags
+    guestname
+        $defaultname
+    vcpu
+        6
+    flags
+        maximum
+
+domain:undefine
+    guestname
+        $defaultname
+
+options cleanup=enable
+
diff --git a/repos/domain/set_vcpus_flags.py b/repos/domain/set_vcpus_flags.py
new file mode 100644
index 0000000..ca614cc
--- /dev/null
+++ b/repos/domain/set_vcpus_flags.py
@@ -0,0 +1,283 @@
+#!/usr/bin/env python
+# Test set domain vcpu with flags. Flags could be 0, live, config,
+# maximum and their combinations, use '|' for combinations. If
+# domain is active, username and password should be provided, else
+# not.
+
+import time
+import commands
+from xml.dom import minidom
+
+import libvirt
+from libvirt import libvirtError
+
+from src import sharedmod
+from utils import utils
+
+required_params = ('guestname', 'vcpu', 'flags', )
+optional_params = {
+                   'username': 'root',
+                   'password': '',
+                  }
+
+def check_domain_running(conn, guestname):
+    """ check if the domain exists, may or may not be active """
+    guest_names = []
+    ids = conn.listDomainsID()
+    for id in ids:
+        obj = conn.lookupByID(id)
+        guest_names.append(obj.name())
+
+    if guestname not in guest_names:
+        logger.info("%s is not running" % guestname)
+        return 1
+    else:
+        return 0
+
+def redefine_vcpu_number(domobj, guestname, vcpu):
+    """dump domain xml description to change the vcpu number,
+       then, define the domain again
+    """
+    guestxml = domobj.XMLDesc(0)
+    logger.debug('''original guest %s xml :\n%s''' %(guestname, guestxml))
+
+    doc = minidom.parseString(guestxml)
+
+    newvcpu = doc.createElement('vcpu')
+    newvcpuval = doc.createTextNode(str(vcpu))
+    newvcpu.appendChild(newvcpuval)
+    newvcpu.setAttribute('current', '1')
+
+    domain = doc.getElementsByTagName('domain')[0]
+    oldvcpu = doc.getElementsByTagName('vcpu')[0]
+
+    domain.replaceChild(newvcpu, oldvcpu)
+
+    return doc.toxml()
+
+def check_current_vcpu(domobj, state, flag, username, password):
+    """dump domain xml description to get current vcpu number and
+       check vcpu in domain if domain is active
+    """
+    if len(flag) == 1 and flag[0] == '0':
+        if state:
+            flag.append('config')
+        else:
+            flag.append('live')
+
+    if len(flag) == 1 and flag[0] == 'maximum':
+        if state:
+            flag.append('config')
+        else:
+            logger.error("'maximum' on live domain is not supported'")
+            return False
+
+    if 'live' in flag:
+        if 'maximum' in flag:
+            logger.error("'live' with 'maximum' is not supported'")
+            return False
+
+        guestxml = domobj.XMLDesc(1)
+        logger.debug("domain %s xml is :\n%s" %(domobj.name(), guestxml))
+
+        xml = minidom.parseString(guestxml)
+        vcpu = xml.getElementsByTagName('vcpu')[0]
+        if vcpu.hasAttribute('current'):
+            attr = vcpu.getAttributeNode('current')
+            current_vcpu = int(attr.nodeValue)
+        else:
+            logger.info("no 'current' attribute in vcpu element")
+            return False
+
+        if not state:
+            if password == '' and username == 'root':
+                logger.error("check will fail with empty root password")
+                return False
+
+            logger.info("check cpu number in domain")
+            ip = utils.mac_to_ip(mac, 180)
+
+            cmd = "cat /proc/cpuinfo | grep processor | wc -l"
+            ret, output = utils.remote_exec_pexpect(ip, username, password, cmd)
+            if not ret:
+                logger.info("cpu number in domain is %s" % output)
+                if int(output) == current_vcpu:
+                    logger.info("cpu in domain is equal to current vcpu value")
+                else:
+                    logger.error("current vcpu is not equal as check in domain")
+                    return False
+            else:
+                logger.error("check in domain fail")
+                return False
+
+    if 'config' in flag:
+        guestxml = domobj.XMLDesc(2)
+        logger.debug("domain %s xml is :\n%s" %(domobj.name(), guestxml))
+
+        xml = minidom.parseString(guestxml)
+        vcpu = xml.getElementsByTagName('vcpu')[0]
+        if 'maximum' in flag:
+            current_vcpu = int(vcpu.childNodes[0].data)
+        else:
+            if vcpu.hasAttribute('current'):
+                attr = vcpu.getAttributeNode('current')
+                conf_vcpu = int(attr.nodeValue)
+                if 'live' in flag:
+                    if not current_vcpu == conf_vcpu:
+                        return False
+                else:
+                    current_vcpu = conf_vcpu
+            else:
+                logger.info("no 'current' attribute in vcpu element")
+                return False
+
+    return current_vcpu
+
+def set_vcpus_offline(domobj, guestname, vcpu):
+    """offline set the domain vcpu as given and current value as 1,
+       then boot up the domain
+    """
+    timeout = 60
+    logger.info('destroy domain')
+
+    try:
+        domobj.destroy()
+    except libvirtError, e:
+        logger.error("libvirt call failed: " + str(e))
+        logger.error("fail to destroy domain")
+        return 1
+
+    newguestxml = redefine_vcpu_number(domobj, guestname, vcpu)
+    logger.debug('''new guest %s xml :\n%s''' %(guestname, newguestxml))
+
+    logger.info("undefine the original guest")
+    try:
+        domobj.undefine()
+    except libvirtError, e:
+        logger.error("libvirt call failed: " + str(e))
+        logger.error("fail to undefine guest %" % guestname)
+        return 1
+
+    logger.info("define guest with new xml")
+    try:
+        conn = domobj._conn
+        conn.defineXML(newguestxml)
+    except libvirtError, e:
+        logger.error("libvirt call failed: " + str(e))
+        logger.error("fail to define guest %s" % guestname)
+        return 1
+
+    try:
+        logger.info('boot guest up ...')
+        domobj.create()
+    except libvirtError, e:
+        logger.error("libvirt call failed: " + str(e))
+        logger.error("fail to start domain %s" % guestname)
+        return 1
+
+    timeout = 600
+
+    while timeout:
+        time.sleep(10)
+        timeout -= 10
+
+        logger.debug("get ip by mac address")
+        ip = utils.mac_to_ip(mac, 180)
+        logger.debug("the ip address of vm %s is %s" % (guestname, ip))
+
+        if not ip:
+            logger.info(str(timeout) + "s left")
+        else:
+            logger.info("vm %s power on successfully" % guestname)
+            logger.info("the ip address of vm %s is %s" % (guestname, ip))
+            break
+
+    if timeout <= 0:
+        logger.info("fail to power on vm %s" % guestname)
+        return 1
+
+    return 0
+
+def set_vcpus_flags(params):
+    """set domain vcpu with flags and check
+    """
+    global logger
+    logger = params['logger']
+    params.pop('logger')
+    guestname = params['guestname']
+    vcpu = int(params['vcpu'])
+    flags = params['flags']
+    username = params.get('username', 'root')
+    password = params.get('password', '')
+
+    logger.info("the name of virtual machine is %s" % guestname)
+    logger.info("the vcpu given is %s" % vcpu)
+
+    logger.info("the flags is %s" % flags)
+    flags_string = flags.split("|")
+
+    flags = 0
+    for flag in flags_string:
+        if flag == '0':
+            flags |= 0
+        elif flag == 'live':
+            flags |= libvirt.VIR_DOMAIN_AFFECT_LIVE
+        elif flag == 'config':
+            flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG
+        elif flag == 'maximum':
+            flags |= libvirt.VIR_DOMAIN_VCPU_MAXIMUM
+        else:
+            logger.error("unknown flag")
+            return 1
+
+    conn = sharedmod.libvirtobj['conn']
+
+    domobj = conn.lookupByName(guestname)
+    logger.debug("get the mac address of vm %s" % guestname)
+    global mac
+    mac = utils.get_dom_mac_addr(guestname)
+    logger.debug("the mac address of vm %s is %s" % (guestname, mac))
+
+    num = vcpu + 1
+    try:
+        max_vcpus = int(conn.getMaxVcpus('kvm'))
+        logger.debug("hypervisor supported max vcpu is %s" % max_vcpus)
+    except libvirtError, e:
+        logger.error("libvirt call failed: " + str(e))
+        return 1
+
+    if num > max_vcpus:
+        logger.error("vcpu must smaller than max number: %s" % max_vcpus)
+        return 1
+
+    state = check_domain_running(conn, guestname)
+
+    if state:
+        try:
+            logger.info("set domain maximum vcpu as: %s" % num)
+            domobj.setVcpusFlags(num, libvirt.VIR_DOMAIN_VCPU_MAXIMUM)
+        except libvirtError, e:
+            logger.error("libvirt call failed: " + str(e))
+            return 1
+    else:
+        logger.info("set domain vcpu to %s and restart with current cpu as 1" %
+                    num)
+        ret = set_vcpus_offline(domobj, guestname, num)
+        if ret != 0:
+            return 1
+
+    try:
+        logger.info("set vcpus to %s with flag: %s" % (vcpu, flags))
+        domobj.setVcpusFlags(vcpu, flags)
+        logger.info("set vcpu with flag succeed")
+    except libvirtError, e:
+        logger.error("libvirt call failed: " + str(e))
+        return 1
+
+    ret = check_current_vcpu(domobj, state, flags_string, username, password)
+    if ret == 'False':
+        logger.error("check set vcpu failed")
+        return 1
+    elif ret == vcpu:
+        logger.info("check set vcpu succeed")
+        return 0
-- 
1.7.1


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]