On Wed, Oct 12, 2011 at 4:48 AM, Amos Kong <[email protected]> wrote:
> On 10/12/2011 05:07 AM, Lucas Meneghel Rodrigues wrote:
>> This is an initial implementation for a libvirt monitor.
>> With it, we plan on making the libvirt test use all the
>> monitor features, making most of the tests available for
>> kvm available for libvirt.
>>
>> As of implementation details, it uses aexpect to get a
>> virsh shell, and then the monitor methods are implemented
>> by executing commands on that virsh shell.
>>
>> As of now, the libvirt vm class is still not using the
>> monitor code, but we plan on making the move soon enough.
>>
>> Signed-off-by: Lucas Meneghel Rodrigues<[email protected]>
>> ---
>> client/virt/libvirt_monitor.py | 322
>> ++++++++++++++++++++++++++++++++++++++++
>> 1 files changed, 322 insertions(+), 0 deletions(-)
>> create mode 100644 client/virt/libvirt_monitor.py
>>
>> diff --git a/client/virt/libvirt_monitor.py b/client/virt/libvirt_monitor.py
>> new file mode 100644
>> index 0000000..05b838c
>> --- /dev/null
>> +++ b/client/virt/libvirt_monitor.py
>> @@ -0,0 +1,322 @@
>> +import re, tempfile, xml.dom.minidom, logging
>> +import virt_utils, aexpect
>> +from autotest_lib.client.bin import utils
>> +
>> +
>> +class VirshMonitor:
>> + """
>> + Wraps "Virsh monitor" commands.
>> + """
>> +
>> + def __init__(self, virsh_exec='virsh', name, vmname, password=None,
>> + prompt=None, hostname='localhost', driver=None,
>> username=None,
>> + linesep="\\n"):
>> + """
>> + Connect to the hypervisor and get virsh prompt.
>> +
>> + @param virsh_exec: Virsh executable
>> + @param name: Monitor identifier (a string)
>> + @param vmname: VM name
>> + @param password: Hypervisor user password
>> + @param prompt: Virsh prompt
>> + @param hostname: Hypervisor IP
>> + @param driver: Hypervisor driver type
>> + @param username: Hypervisor username
>> + @param linesep: The line separator to use when sending lines
>> + (e.g. '\\n' or '\\r\\n')
>> + """
>> + self.virsh_exec = virsh_exec
>> + self.name = name
>> + self.vmname = vmname
>> + self.password = password
>> + self.prompt = prompt
>> + self.hostname = hostname
>> + self.driver = driver
>> + self.username = username
>> + self.session = self.login()
>> + self.virsh_cmd = {"help":"help", "quit":"destroy " + self.vmname,
>> + "stop":"suspend", "cont":"resume"}
>> + self.drive_map = {}
>> + self.network_info = []
>> + self.disk_info = []
>> + self._parse_domxml()
>> +
>> +
>> + def __del__(self):
>> + self.session.sendline("quit")
>> +
>
> ....
>> + if "balloon" in command:
>> + new_mem = re.findall("balloon\s+(\d+)", command)[0]
>> + new_mem = str(int(new_mem) * 1024)
>> + output = self.session.cmd_output("setmem %s %s" %
>> + (self.vmname,
>> new_mem))
>> + return
>> +
>> + if "system_reset" in command:
>> + self.session.cmd_output("destroy %s" % self.vmname)
>> + self.session.cmd_output("start %s" % self.vmname)
>> + return
>
> This would make qemu process exit, this is not same as qemu monitor
> cmd(system_reset). We may migrate guest which is repeatedly rebooting,
> then migration will be failed.
Ok, noted, but since there's no such an API written for it yet, and
since we are still not supporting migration tests, I believe it's OK
to leave it like that for now.
> # grep system_reset virt/tests/*
> virt/tests/boot.py: 2) Send a reboot command or a system_reset
> monitor command (optional)
> virt/tests/boot.py: if params["reboot_method"] == "system_reset":
> Binary file virt/tests/boot.pyc matches
> virt/tests/iofuzz.py: session =
> vm.reboot(method="system_reset")
>
>
> 'system_reset' of qemu monitor is only called for fakereboot in Libvirt.
> but Libvirt developer told me they may add new API for it.
>
>
>> + data = self.session.cmd_output(" %s \n" % self.virsh_cmd.get(
>> + command,
>> command))
>> + return data
>> +
>> +
>> + def is_responsive(self):
>> + """
>> + Return True if the monitor is responsive.
>> + """
>> + return True
>> +
>> +
>> + def quit(self):
>> + """
>> + Send "quit" without waiting for output.
>> + """
>> + self.cmd("quit")
>> +
>> +
>> + def screendump(self, filename, debug=True):
>> + """
>> + Request a screendump.
>> +
>> + @param filename: Location for the screendump
>> + @return: The command's output
> ^^^^^^^^^^^^
>
>> + """
>> + if debug:
>> + logging.debug("Requesting screendump %s" % filename)
>> + self.cmd("screenshot %s" % filename)
>
> cmd output is not returned.
Ok, that was easy enough to fix, thanks! I've updated my branch with
all the fixes pointed out so far.
>
>> + def info(self, what):
>> + """
>> + Request info about something and return the output.
>> + """
>> + if "network" in what:
>> + return self.network_info
>> +
>> + if "pci" in what:
>> + domxml = self.session.cmd_output("dumpxml %s \n" %
>> + self.vmname)
>> + self._parse_dev(domxml)
>> + return str(self.network_info) + str(self.drive_map)
>> +
>> + if "balloon" in what:
>> + self.session.cmd_output("\n")
>> + netpool_lst = self.session.cmd_output("dominfo %s" %
>> + self.vmname)
>> + return str(int(re.findall("Used memory:\s+(\d+)", netpool_lst)
>> + [0]) / 1024)
>> +
>> + return self.cmd("info %s" % what)
>
> _______________________________________________
> Autotest mailing list
> [email protected]
> http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
>
--
Lucas
_______________________________________________
Autotest mailing list
[email protected]
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest