---
repos/domain/update_devflag.py | 276 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 276 insertions(+), 0 deletions(-)
create mode 100644 repos/domain/update_devflag.py
diff --git a/repos/domain/update_devflag.py b/repos/domain/update_devflag.py
new file mode 100644
index 0000000..e1bf559
--- /dev/null
+++ b/repos/domain/update_devflag.py
@@ -0,0 +1,276 @@
+#!/usr/bin/env python
+"""Update virtual device to guest from an XML file
+ domain:update_devflag
+ guestname
+ xxx
+ devtype
+ cdrom|floppy
+"""
+
+__author__ = 'Nan Zhang: nzhang(a)redhat.com'
+__date__ = 'Fri Sep 2, 2011'
+__version__ = '0.1.0'
+__credits__ = 'Copyright (C) 2011 Red Hat, Inc.'
+__all__ = ['check_updated_device', 'update_devflag']
+
+import os
+import re
+import sys
+import time
+import guestfs
+from xml.dom import minidom
+
+
+def append_path(path):
+ """Append root path of package"""
+ if path in sys.path:
+ pass
+ else:
+ sys.path.append(path)
+
+pwd = os.getcwd()
+result = re.search('(.*)libvirt-test-API', pwd)
+append_path(result.group(0))
+
+from lib import connectAPI
+from lib import domainAPI
+from utils.Python import utils
+from utils.Python import xmlbuilder
+from exception import LibvirtAPI
+
+def check_params(params):
+ """Verify inputing parameter dictionary"""
+ logger = params['logger']
+ keys = ['guestname', 'devtype']
+ for key in keys:
+ if key not in params:
+ logger.error("%s is required" %key)
+ return 1
+ return 0
+
+def create_image(params, util, img_name, img_size):
+ """Create an image file"""
+ logger = params['logger']
+ cmd = "qemu-img create -f raw %s %s" % (img_name, img_size)
+ ret, output = util.exec_cmd(cmd, shell=True)
+ if ret:
+ logger.error("image creation fail: \n %s" % output)
+ return False
+ else:
+ logger.info("create an image %s with %s." % (img_name, img_size))
+
+ cmd = "mkfs.ext2 -F %s" % img_name
+ ret, output = util.exec_cmd(cmd, shell=True)
+ if ret:
+ logger.error("fail to format image: \n %s" % output)
+ return False
+ else:
+ logger.info("succeed to format image: %s" % img_name)
+
+ cmd = "guestmount -a %s -m /dev/vda --rw /mnt && \
+ touch /mnt/`uuidgen -t` && umount -l /mnt" % img_name
+ ret, output = util.exec_cmd(cmd, shell=True)
+ if ret:
+ logger.error("fail to write a file to image: \n %s" % output)
+ return False
+ else:
+ logger.info("succeed to write a file to image: %s" % img_name)
+
+ return True
+
+def check_device_in_guest(params, util, guestip):
+ """Check updated device in guest"""
+ logger = params['logger']
+
+ if params['devtype'] == 'cdrom':
+ cmd = "mount -o loop /dev/cdrom /media"
+ elif params['devtype'] == 'floppy':
+ cmd = "mount /dev/fd0 /media"
+ else:
+ logger.error("it's not a cdrom or floppy device.")
+ return False, None
+
+ ret, output = util.remote_exec_pexpect(guestip, "root", "redhat",
cmd)
+ logger.debug(output)
+ if ret:
+ logger.error("failed to mount %s device." % params['devtype'])
+ return False, output
+
+ time.sleep(5)
+
+ ret, output = util.remote_exec_pexpect(guestip, "root", "redhat",
\
+ "umount /media")
+ logger.debug(output)
+ if ret:
+ logger.error("failed to unmount %s device." %
params['devtype'])
+ return False, output
+
+ time.sleep(5)
+
+ ret, output = util.remote_exec_pexpect(guestip, "root", "redhat",
\
+ "ls /media")
+ logger.debug(output)
+ if ret:
+ logger.error("failed to list contents of %s device." \
+ % params['devtype'])
+ return False, output
+
+ return True, output
+
+def check_updated_device(params, output, util, guestip, domobj, srcfile):
+ """Check if the device is updated"""
+ logger = params['logger']
+ xmlobj = domobj.get_xml_desc(params['guestname'])
+ domxml = minidom.parseString(xmlobj)
+
+ for diskTag in domxml.getElementsByTagName("source"):
+ if diskTag.parentNode.getAttribute("device") == 'cdrom':
+ upfile = diskTag.getAttribute("file")
+ elif diskTag.parentNode.getAttribute('device') == 'floppy':
+ upfile = diskTag.getAttribute("file")
+
+ res = check_device_in_guest(params, util, guestip)
+ if res[0] and cmp(res[1], output):
+ if upfile == srcfile:
+ logger.debug("checking fail.")
+ return False, upfile
+ else:
+ logger.debug("checking successful.")
+ return True, upfile
+ else:
+ return False, None
+
+def update_devflag(params):
+ """Update virtual device to a domain from xml"""
+ util = utils.Utils()
+
+ # Initiate and check parameters
+ params_check_result = check_params(params)
+ if params_check_result:
+ return 1
+
+ logger = params['logger']
+ guestname = params['guestname']
+ devtype = params['devtype']
+
+ if devtype == 'cdrom':
+ xmlargs = {}
+ xmlargs['guestname'] = guestname
+ xmlargs['guesttype'] = 'kvm'
+ xmlargs['hdmodel'] = 'ide'
+ xmlargs['bootcd'] = '/var/lib/libvirt/boot/cdrom.img'
+ srcfile = xmlargs['bootcd']
+ if not create_image(params, util, srcfile, '100M'):
+ return 1
+ elif devtype == 'floppy':
+ xmlargs = {}
+ xmlargs['guestname'] = guestname
+ xmlargs['floppysource'] = '/var/lib/libvirt/boot/floppy.img'
+ srcfile = xmlargs['floppysource']
+ if not create_image(params, util, srcfile, '2M'):
+ return 1
+ else:
+ srcfile = None
+ logger.error("Wrong device type was specified.")
+ return 1
+
+ if not params.has_key('flag'):
+ flag = domainAPI.VIR_DOMAIN_AFFECT_CONFIG
+
+ # Connect to local hypervisor connection URI
+ uri = util.get_uri('127.0.0.1')
+ mac = util.get_dom_mac_addr(guestname)
+ guestip = util.mac_to_ip(mac, 180)
+ logger.debug("ip address: %s" % guestip)
+
+ conn = connectAPI.ConnectAPI()
+ virconn = conn.open(uri)
+ caps = conn.get_caps()
+ logger.debug(caps)
+ domobj = domainAPI.DomainAPI(virconn)
+ guestxml = domobj.get_xml_desc(guestname)
+ guestobj = minidom.parseString(guestxml)
+
+ # Generat device XML for original use
+ origxmlobj = xmlbuilder.XmlBuilder()
+
+ if devtype == 'cdrom':
+ origxmlobj.add_cdrom(xmlargs, guestobj)
+ guestxml = origxmlobj.build_domain(guestobj)
+ elif devtype == 'floppy':
+ origxmlobj.add_floppy(xmlargs, guestobj)
+ guestxml = origxmlobj.build_domain(guestobj)
+
+ if domobj.get_state(guestname) == 'running':
+ domobj.destroy(guestname)
+
+ try:
+ domobj.undefine(guestname)
+ domobj.define(guestxml)
+ domobj.start(guestname)
+ except LibvirtAPI, e:
+ logger.error("API error message: %s, error code is %s" %
+ (e.response()['message'], e.response()['code']))
+ return 1
+
+ time.sleep(60)
+ ret, output = check_device_in_guest(params, util, guestip)
+ logger.debug(output)
+ if not ret:
+ return 1
+
+ # Generate device XML for updating
+ newxmlobj = xmlbuilder.XmlBuilder()
+
+ if devtype == 'cdrom':
+ xmlargs['bootcd'] = '/var/lib/libvirt/boot/cdrom-new.img'
+ upfile = xmlargs['bootcd']
+ if not create_image(params, util, upfile, '100M'):
+ logger.info("fail to create new image.")
+ return 1
+ newdevxml = newxmlobj.build_cdrom(xmlargs)
+ elif devtype == 'floppy':
+ xmlargs['floppysource'] = '/var/lib/libvirt/boot/floppy-new.img'
+ upfile = xmlargs['floppysource']
+ if not create_image(params, util, upfile, '2M'):
+ logger.info("fail to create new image.")
+ return 1
+ newdevxml = newxmlobj.build_floppy(xmlargs)
+
+ logger.debug("block device xml desc for update:\n%s" % newdevxml)
+
+ logger.debug("domain xml before updating:\n%s" \
+ % domobj.get_xml_desc(guestname))
+
+ try:
+ domobj.update_device_flag(guestname, newdevxml, flag)
+ logger.debug("domain xml after updating:\n%s" \
+ % domobj.get_xml_desc(guestname))
+ except LibvirtAPI, e:
+ logger.error("API error message: %s, error code is %s" %
+ (e.response()['message'], e.response()['code']))
+ return 1
+
+ result = check_updated_device(params, output, util, \
+ guestip, domobj, srcfile)
+ if result[0]:
+ logger.error("fail to update '%s' device: %s\n" % (devtype,
result[1]))
+ conn.close()
+ return 1
+
+ logger.info("success to update '%s' device: %s\n" % (devtype,
result[1]))
+ conn.close()
+ return 0
+
+def update_devflag_clean(params):
+ """Clean testing environment"""
+ logger = params['logger']
+
+ if params['devtype'] == 'cdrom':
+ os.unlink('/var/lib/libvirt/boot/cdrom.img')
+ os.unlink('/var/lib/libvirt/boot/cdrom-new.img')
+ elif params['devtype'] == 'floppy':
+ os.unlink('/var/lib/libvirt/boot/floppy.img')
+ os.unlink('/var/lib/libvirt/boot/floppy-new.img')
+ else:
+ logger.debug("image file was not found.")
--
1.7.4.4