From mboxrd@z Thu Jan 1 00:00:00 1970 From: Amos Kong Subject: Re: [Autotest] [PATCH 05/11] virt: Introducing libvirt VM class Date: Wed, 12 Oct 2011 14:51:38 +0800 Message-ID: <4E9538FA.6030405@redhat.com> References: <1318367237-26081-1-git-send-email-lmr@redhat.com> <1318367237-26081-6-git-send-email-lmr@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: autotest@test.kernel.org, kvm@vger.kernel.org To: Lucas Meneghel Rodrigues Return-path: Received: from mx1.redhat.com ([209.132.183.28]:1027 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751317Ab1JLGtG (ORCPT ); Wed, 12 Oct 2011 02:49:06 -0400 In-Reply-To: <1318367237-26081-6-git-send-email-lmr@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: On 10/12/2011 05:07 AM, Lucas Meneghel Rodrigues wrote: > This is a first attempt at providing a libvirt VM class, > in order to implement the needed methods for virt testing. > With this class, we will be able to implement a libvirt > test, that behaves similarly to the KVM test. > > As of implementation details, libvirt_vm uses virsh > (a userspace program written on top of libvirt) to > do domain start, stop, verification of status and > other common operations. The reason why virsh was > used is to get more coverage of the userspace stack > that libvirt offers, and also to catch issues that > virsh users would catch. > > Signed-off-by: Lucas Meneghel Rodrigues > --- > client/virt/libvirt_vm.py | 1232 +++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 1232 insertions(+), 0 deletions(-) > create mode 100644 client/virt/libvirt_vm.py > > diff --git a/client/virt/libvirt_vm.py b/client/virt/libvirt_vm.py > new file mode 100644 > index 0000000..bed512f > --- /dev/null > +++ b/client/virt/libvirt_vm.py > @@ -0,0 +1,1232 @@ > +""" > +Utility classes and functions to handle Virtual Machine creation using qemu. > + > +@copyright: 2008-2009 Red Hat Inc. > +""" > + > +import time, os, logging, fcntl, re, commands > +from autotest_lib.client.common_lib import error > +from autotest_lib.client.bin import utils, os_dep > +from xml.dom import minidom > +import virt_utils, virt_vm, aexpect > + > +DEBUG = False > +try: > + VIRSH_EXEC = os_dep.command("virsh") > +except ValueError: > + VIRSH_EXEC = None > + > + > +def libvirtd_restart(): > + """ > + Restart libvirt daemon. > + """ > + try: > + utils.run("service libvirtd restart") > + logging.debug("Restarted libvirtd successfuly") > + return True > + except error.CmdError, detail: > + logging.error("Failed to restart libvirtd: %s" % detail) > + return False > + > + > +def virsh_cmd(cmd): > + if VIRSH_EXEC is None: > + raise ValueError('Missing command: virsh') > + cmd_result = utils.run("%s %s" % (VIRSH_EXEC, cmd), ignore_status=True, > + verbose=DEBUG) > + if DEBUG: > + if cmd_result.stdout.strip(): > + logging.debug("stdout: %s", cmd_result.stdout.strip()) > + if cmd_result.stderr.strip(): > + logging.debug("stderr: %s", cmd_result.stderr.strip()) > + return cmd_result.stdout.strip() > + > + > +def virsh_uri(): > + """ > + Return the hypervisor canonical URI. > + """ > + return virsh_cmd("uri") > + > + > +def virsh_hostname(): > + """ > + Return the hypervisor hostname. > + """ > + return virsh_cmd("hostname") > + > + > +def virsh_domstate(name): > + """ > + Return the state about a running domain. > + > + @param name: VM name > + """ > + return virsh_cmd("domstate %s" % name) > + > + > +def virsh_uuid(name): > + """ > + Return the Converted domain name or id to the domain UUID. > + > + @param name: VM name > + """ > + return virsh_cmd("domuuid %s" % name) > + > + > +def virsh_screenshot(name, filename): > + virsh_cmd("screenshot %s %s" % (name, filename)) > + return filename > + > + > +def virsh_dumpxml(name): > + """ > + Return the domain information as an XML dump. > + > + @param name: VM name > + """ > + return virsh_cmd("dumpxml %s" % name) > + > + > +def virsh_is_alive(name): > + """ > + Return True if the domain is started/alive. > + > + @param name: VM name > + """ > + return not virsh_is_dead(name) > + > + > +def virsh_is_dead(name): > + """ > + Return True if the domain is not started/dead. > + > + @param name: VM name > + """ > + if (virsh_domstate(name) == 'running' or > + virsh_domstate(name) == 'idle'): > + return False > + else: > + return True > + > + > +def virsh_suspend(name): > + """ > + Return True on successful domain suspention of VM. > + > + Suspend a domain. It is kept in memory but will not be scheduled. > + > + @param name: VM name > + """ > + try: > + utils.run("virsh suspend %s" % (name)) > + if virsh_domstate(name) == 'paused': > + logging.debug("Suspended VM %s", name) > + return True > + else: > + return False > + except error.CmdError: > + logging.error("Suspending VM %s failed", name) > + return False > + > + > +def virsh_resume(name): > + """ > + Return True on successful domain resumption of VM. > + > + Move a domain out of the suspended state. > + > + @param name: VM name > + """ > + try: > + utils.run("virsh resume %s" % (name)) > + if virsh_is_alive(name): > + logging.debug("Resumed VM %s", name) > + return True > + else: > + return False > + except error.CmdError: > + logging.error("Resume VM %s failed", name) > + return False > + > + > +def virsh_start(name, vm): def virsh_start(name): one or two augments here? this function is called with one augment in VM.start() > + """ > + Return True on successful domain start. > + > + Start a (previously defined) inactive domain. > + > + @param name: VM name > + """ > + if virsh_is_alive(name): > + return > + try: > + utils.run("virsh start %s" % (name)) > + return True > + except error.CmdError: > + logging.error("Start VM %s failed", name) If the virsh cmd fails, we would got two error message. They are repeated, how about remove this one? or add a prefix(we would know it's an error of virsh cmd) logging.error("Start VM %s failed", name) logging.error("VM %s failed to start", self.name) > + return False > + > + .... > + > +class VM(virt_vm.BaseVM): > + """ > + This class handles all basic VM operations for libvirt. > + """ > + def __init__(self, name, params, root_dir, address_cache, state=None): > + """ > + Initialize the object and set a few attributes. > + > + @param name: The name of the object > + @param params: A dict containing VM params > + (see method make_qemu_command for a full description) .... > + > + def start(self): > + """ > + Starts this VM. > + """ > + if virsh_start(self.name): ^^^^^^^^ > + if self.wait_for_start(): > + logging.debug("Started VM %s", self.name) > + return True > + else: > + logging.error("VM %s failed to start", self.name) > + return False > + else: > + logging.error("VM %s failed to start", self.name) ^^^^^^^^ > + return False > + > + > + def wait_for_shutdown(self, count=60): > + """ > + Return True on successful domain shutdown. > + > + Wait for a domain to shutdown, libvirt does not block on domain > + shutdown so we need to watch for successful completion. > + > + @param name: VM name > + @param name: Optional timeout value > + """ > + timeout = count > + while count> 0: > + # check every 5 seconds > + if count % 5 == 0: > + if virsh_is_dead(self.name): > + logging.debug("Shutdown took %d seconds", timeout - count) > + return True > + count -= 1 > + time.sleep(1) > + logging.debug("Waiting for guest to shutdown %d", count) > + return False > +