The patch V2 inclues fixing all spots commented by Gren The managedsave test cases and test suite cover test include verifying virsh commands managedsave(include all flags and their combination)/managedsave-remove and managedSaveRemove/ManagedSave/ hasManagedSaveImage python APIs. The following new files be created. new file: cases/managedsave.conf - Test all test cases new file: repos/managedsave/__init__.py new file: repos/managedsave/managedsave.py - Test mangaedsave command/API and all flags new file: repos/managedsave/managedsave_remove.py - Test managedsave-remove command/API new file: repos/managedsave/managedsave_start.py - Verfiy managedsave'flags and start from managedsave image --- cases/managedsave.conf | 63 ++++++++++++ repos/managedsave/managedsave.py | 159 +++++++++++++++++++++++++++++++ repos/managedsave/managedsave_remove.py | 60 ++++++++++++ repos/managedsave/managedsave_start.py | 150 +++++++++++++++++++++++++++++ 4 files changed, 432 insertions(+), 0 deletions(-) create mode 100644 cases/managedsave.conf create mode 100644 repos/managedsave/__init__.py create mode 100644 repos/managedsave/managedsave.py create mode 100644 repos/managedsave/managedsave_remove.py create mode 100644 repos/managedsave/managedsave_start.py diff --git a/cases/managedsave.conf b/cases/managedsave.conf new file mode 100644 index 0000000..8dcafe2 --- /dev/null +++ b/cases/managedsave.conf @@ -0,0 +1,63 @@ +domain:install_linux_cdrom + guestname + $defaultname + guestos + $defaultos + guestarch + $defaultarch + vcpu + $defaultvcpu + memory + $defaultmem + hddriver + $defaulthd + nicdriver + $defaultnic + imageformat + qcow2 + macaddr + 54:52:00:4a:16:30 + +#VIR_DOMAIN_SAVE_BYPASS_CACHE = 1 +#VIR_DOMAIN_SAVE_RUNNING = 2 +#VIR_DOMAIN_SAVE_PAUSED = 4 +#No_FLAGS = 0 +managedsave:managedsave + guestname + $defaultname + flags + 1|2 + +managedsave:managedsave_start + guestname + $defaultname + flags + noping + +managedsave:managedsave + guestname + $defaultname + flags + 1|4 + +managedsave:managedsave_start + guestname + $defaultname + flags + noping + +managedsave:managedsave + guestname + $defaultname + flags + 0 + +managedsave:managedsave_remove + guestname + $defaultname + +managedsave:managedsave_start + guestname + $defaultname + flags + noping diff --git a/repos/managedsave/__init__.py b/repos/managedsave/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/repos/managedsave/managedsave.py b/repos/managedsave/managedsave.py new file mode 100644 index 0000000..a126cd8 --- /dev/null +++ b/repos/managedsave/managedsave.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python + +import os +import math + +import libvirt +from libvirt import libvirtError + +from src import sharedmod +from utils import utils + +required_params = ('guestname', 'flags',) +optional_params = {} + +def check_guest_status(*args): + """Check guest current status""" + (domobj, logger) = args + state = domobj.info()[0] + logger.debug("current guest status: %s" % state) + + if state == libvirt.VIR_DOMAIN_SHUTOFF or \ + state == libvirt.VIR_DOMAIN_SHUTDOWN or \ + state == libvirt.VIR_DOMAIN_BLOCKED: + return False + else: + return True + +def check_savefile_create(*args): + """Check guest's managed save file be created""" + + (guestname) = args + cmds = "ls /var/lib/libvirt/qemu/save/%s" % guestname + ".save -lh" + logger.info("Execute cmd %s" % cmds) + (status, output) = utils.exec_cmd(cmds, shell=True) + if status != 0: + logger.error("No managed save file") + return False + else : + logger.info("managed save file exists") + return True + +def compare_cachedfile(cachebefore, cacheafter): + """Compare cached value before managed save and its value after + managed save """ + + diff = cacheafter - cachebefore + logger.info("diff is %s " % diff) + percent = math.fabs(diff)/cachebefore + logger.info("diff percent is %s " % percent) + if percent < 0.05: + return True + else: + return False + +def get_cachevalue(): + """Get the file system cached value """ + + cmds = "head -n4 /proc/meminfo|grep Cached|awk '{print $2}'" + (status, output) = utils.exec_cmd(cmds, shell=True) + if status != 0: + logger.error("Fail to run cmd line to get cache") + return 1 + else: + logger.debug(output[0]) + cachevalue= int(output[0]) + return cachevalue + +def managedsave(params): + """Managed save a running domain""" + + global logger + logger = params['logger'] + guestname = params['guestname'] + flags = params ['flags'] + #Save given flags to sharedmod.data + sharedmod.data['flagsave'] = flags + + logger.info("The given flags are %s " % flags) + if not '|' in flags: + flagn = int(flags) + else: + # bitwise-OR of flags of managedsave + flaglist = flags.split('|') + flagn = 0 + for flag in flaglist: + flagn |= int(flag) + + conn = sharedmod.libvirtobj['conn'] + domobj = conn.lookupByName(guestname) + + if not check_guest_status(domobj, logger): + logger.error("Current guest status is shutoff") + return 1 + + try: + + logger.info("bitwise OR value of flags is %s" % flagn) + + if flagn == 0: + logger.info("managedsave %s domain with no flag" % guestname) + elif flagn == 1: + logger.info("managedsave %s domain --bypass-cache" % guestname) + elif flagn == 2: + logger.info("managedsave %s domain --running" % guestname) + elif flagn == 3: + logger.info("managedsave %s domain --running --bypass-cache"\ + % guestname) + elif flagn == 4: + logger.info("managedsave %s domain --paused" % guestname) + elif flagn == 5: + logger.info("managedsave %s domain --paused --bypass-cache"\ + % guestname) + elif flagn == 6: + logger.error("--running and --paused are mutually exclusive") + return 1 + elif flagn == 7: + logger.error("--running and --paused are mutually exclusive") + return 1 + else: + logger.error("Wrong flags be given and fail to managedsave domain") + return 1 + + #If given flags include bypass-cache,check if bypass file system cache + if flagn % 2 == 1: + logger.info("Given flags include --bypass-cache") + os.system('echo 3 > /proc/sys/vm/drop_caches') + cache_before = get_cachevalue() + logger.info("Cached value before managedsave is %s" % cache_before) + + domobj.managedSave(flagn) + + cache_after = get_cachevalue() + logger.info("Cached value after managedsave is %s" % cache_after) + + if compare_cachedfile(cache_before, cache_after): + logger.info("Bypass file system cache successfully") + else: + logger.error("Bypass file system cache failed") + return 1 + else: + domobj.managedSave(flagn) + + #Check if domain has managedsave image + if domobj.hasManagedSaveImage(0) and \ + domobj.info()[0]==libvirt.VIR_DOMAIN_SHUTOFF and \ + check_savefile_create(guestname): + logger.info("Domain %s managedsave successfully " % guestname) + else: + logger.error("Fail to managedsave domain") + return 1 + + except libvirtError, e: + logger.error("API error message: %s, error code is %s" \ + % e.message) + logger.error("Fail to managedsave %s domain" % guestname) + return 1 + + return 0 + diff --git a/repos/managedsave/managedsave_remove.py b/repos/managedsave/managedsave_remove.py new file mode 100644 index 0000000..a0eec1f --- /dev/null +++ b/repos/managedsave/managedsave_remove.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# Save domain as a statefile + +import libvirt +from libvirt import libvirtError + +from src import sharedmod +from utils import utils + +required_params = ('guestname',) +optional_params = {} + +def check_savefile_remove(*args): + """Check if guest's managedsave file be removed """ + + (guestname) = args + cmds = "ls /var/lib/libvirt/qemu/save/%s" % guestname + ".save -lh" + logger.info("Execute cmd %s" % cmds) + (status, output) = utils.exec_cmd(cmds, shell=True) + if status != 0: + logger.info("No managed save file") + return True + else : + logger.error("managed save file exits") + return False + +def managedsave_remove(params): + """Remove an existing managed save state file from a domain""" + + global logger + logger = params['logger'] + guestname = params['guestname'] + + conn = sharedmod.libvirtobj['conn'] + domobj = conn.lookupByName(guestname) + + if not domobj.hasManagedSaveImage(0) and check_savefile_remove(guestname): + logger.error("Domain %s hasn't managedsave image" % guestname) + return 1 + else: + logger.info("Domain %s has managedsave image" % guestname) + + try: + domobj.managedSaveRemove(0) + #Check if domain has managedsave image + if not domobj.hasManagedSaveImage(0) and \ + check_savefile_remove(guestname): + logger.info("Domain %s's managedsave image has been removed"\ + % guestname) + else: + logger.error("Fail to remove managedsave domain") + return 1 + + except libvirtError, e: + logger.error("API error message: %s, error code is %s" % e.message) + logger.error("Fail to managedsave %s domain" % guestname) + return 1 + + return 0 + diff --git a/repos/managedsave/managedsave_start.py b/repos/managedsave/managedsave_start.py new file mode 100644 index 0000000..70539ae --- /dev/null +++ b/repos/managedsave/managedsave_start.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python + +import time + +import libvirt +from libvirt import libvirtError + +from src import sharedmod +from utils import utils + +required_params = ('guestname',) +optional_params = {'flags' : ''} + +NONE = 0 +START_PAUSED = 1 + +def check_savefile_remove(*args): + """Check guest managed save file""" + (guestname) = args + cmds = "ls /var/lib/libvirt/qemu/save/%s" % guestname + ".save -lh" + logger.info("Execute cmd %s" % cmds) + (status, output) = utils.exec_cmd(cmds, shell=True) + if status != 0: + logger.info("No managed save file") + return True + else : + logger.error("managed save file exists") + return False + +def managedsave_start(params): + """ Start domain with managedsave image and check if its status is right + according to given flags of running managedsave command.If it is + correctly paused , resume it. + + Argument is a dictionary with two keys: + {'logger': logger, 'guestname': guestname} + + logger -- an object of utils/log.py + mandatory arguments : guestname -- same as the domain name + optional arguments : flags -- domain create flags <none|start_paused + |noping>.It allows only one flag be given. + + Return 0 on SUCCESS or 1 on FAILURE + """ + domname = params['guestname'] + global logger + logger = params['logger'] + flags = params.get('flags', '') + # Get given flags of managedsave + if sharedmod.data.has_key('flagsave'): + flagsave = sharedmod.data.get('flagsave') + else: + logger.error("Failed to get flags from managedsave") + # Clean sharedmod.data + sharedmod.data = {} + + conn = sharedmod.libvirtobj['conn'] + domobj = conn.lookupByName(domname) + + timeout = 600 + logger.info('start domain') + # Check if guest has managedsave image before start + if domobj.hasManagedSaveImage(0) : + logger.info("Domain has managedsave image") + else: + logger.info("Domain hasn't managedsave image") + + try: + if "none" in flags: + domobj.createWithFlags(NONE) + elif "start_paused" in flags: + domobj.createWithFlags(START_PAUSED) + else: + # this covers flags = None as well as flags = 'noping' + domobj.create() + except libvirtError, e: + logger.error("API error message: %s, error code is %s" \ + % e.message) + logger.error("start failed") + return 1 + + while timeout: + state = domobj.info()[0] + expect_states = [libvirt.VIR_DOMAIN_RUNNING,libvirt.VIR_DOMAIN_PAUSED,\ + libvirt.VIR_DOMAIN_NOSTATE,libvirt.VIR_DOMAIN_BLOCKED] + + if state in expect_states: + break + + time.sleep(10) + timeout -= 10 + logger.info(str(timeout) + "s left") + + if timeout <= 0: + logger.error('The domain state is not as expected, state: ' + state) + return 1 + + logger.info("Guest started") + + """If domain's current state is paused. Check if start command has + --paused flag or managedsave has --paused flag (given flags in managedsave + include '4'). If yes, it means domain successfully paused , then resume it. + If not, throw error -guest state error.""" + + if state == libvirt.VIR_DOMAIN_PAUSED: + if "start_paused" in flags or "4" in flagsave: + logger.info("Guest paused successfully ") + + try: + domobj.resume() + + except libvirtError, e: + logger.error("API error message: %s, error code is %s" \ + % e.message) + logger.error("resume failed") + return 1 + stateresume = domobj.info()[0] + expect_states = [libvirt.VIR_DOMAIN_RUNNING, \ + libvirt.VIR_DOMAIN_NOSTATE, \ + libvirt.VIR_DOMAIN_BLOCKED] + if stateresume not in expect_states: + logger.error('The domain state is not equal to "paused"') + return 1 + else: + logger.info('Domain resume successfully') + return 0 + else: + logger.error("guest state error") + return 1 + + # Get domain ip and ping ip to check domain's status + if not "noping" in flags: + mac = utils.get_dom_mac_addr(domname) + logger.info("get ip by mac address") + ip = utils.mac_to_ip(mac, 180) + + logger.info('ping guest') + if not utils.do_ping(ip, 300): + logger.error('Failed on ping guest, IP: ' + str(ip)) + return 1 + + # Check if domain' managedsave image exists,if not, return 0. + if not domobj.hasManagedSaveImage(0) and check_savefile_remove(domname): + logger.info("Domain %s with managedsave image successfully start" \ + % domname) + return 0 + else: + logger.error("Fail to start domain s% with managedsave image" \ + % domname) + return 1 -- 1.7.7.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list