virsh command "domxml-from-native" is used to convert qemu commandline
generated into corresponding libvirt xml file. :domxml-from-native" is not
able to parse the network parameters in qemu commandline correctly, so a
base xml file with default network parameters is created at first and later
modified based on qemu network parameters passed. The function virsh_login
in virt_utils.py provides access to hypervisor's virsh shell

Signed-off-by: Yogananth Subramanian <[email protected]>
---
 client/virt/kvm_vm.py     |  145 +++++++++++++++++++++++++++++++++++++++++----
 client/virt/virt_utils.py |   26 ++++++++
 2 files changed, 160 insertions(+), 11 deletions(-)

diff --git a/client/virt/kvm_vm.py b/client/virt/kvm_vm.py
index a2f22b4..e9db86a 100644
--- a/client/virt/kvm_vm.py
+++ b/client/virt/kvm_vm.py
@@ -4,7 +4,8 @@ Utility classes and functions to handle Virtual Machine 
creation using qemu.
 @copyright: 2008-2009 Red Hat Inc.
 """
 
-import time, os, logging, fcntl, re, commands, glob
+import time, os, logging, fcntl, re, commands, glob, tempfile
+from xml.dom.minidom import parse
 from autotest_lib.client.common_lib import error
 from autotest_lib.client.bin import utils
 import virt_utils, virt_vm, virt_test_setup, kvm_monitor, aexpect
@@ -43,6 +44,7 @@ class VM(virt_vm.BaseVM):
             self.device_id = []
             self.tapfds = []
             self.uuid = None
+            self.virsh = False
 
 
         self.spice_port = 8000
@@ -80,7 +82,20 @@ class VM(virt_vm.BaseVM):
         """
         Return True if the qemu process is dead.
         """
-        return not self.process or not self.process.is_alive()
+        if self.virsh:
+            virt=virt_utils.virsh_login(self.virsh_password, self.virsh_prompt,
+                     self.virsh_hostname,self.virsh_driver,self.virsh_username)
+            if re.findall("Domain not found|shut off",virt.get_command_output(
+                                                   'domstate %s'%self.name)):
+                virt.sendline("undefine %s;quit"%self.name)
+                return True
+            else:
+                virt.sendline('quit')
+                return False
+        elif not self.process or not self.process.is_alive():
+            return True
+        else:
+            return False
 
 
     def verify_status(self, status):
@@ -779,9 +794,105 @@ class VM(virt_vm.BaseVM):
                 qemu_command += (' -incoming "exec:nc -l %s"' %
                                  self.migration_port)
 
-            logging.info("Running qemu command:\n%s", qemu_command)
-            self.process = aexpect.run_bg(qemu_command, None,
-                                                 logging.info, "(qemu) ")
+            if params.get("virsh") == "yes":
+                self.virsh = True
+            else:
+                self.virsh = False
+
+            if self.virsh:
+                self.qemu_command = qemu_command
+                qemu_format = re.sub("'", '', qemu_command)
+                net_info = re.findall('-(device|netdev) ([^\s]+)', qemu_format)
+                qemu_format = re.sub('-(device|netdev|monitor|serial) ([^\s]+)'
+                                                             , '', qemu_format)
+                qemu_format = qemu_format+" -net nic -net tap"
+                args_tmp = tempfile.mkdtemp(prefix='qemu_', dir='/tmp')
+                qemu_args = os.path.join(args_tmp, self.name+".args")
+                f = open(qemu_args, 'w')
+                f.write(qemu_format)
+                f.close()
+                self.virsh_driver = params.get("virsh_driver")
+                self.virsh_hostname = params.get("virsh_hostname")
+                self.virsh_username = params.get("virsh_username")
+                self.virsh_password = params.get("virsh_password")
+                self.virsh_prompt = params.get("virsh_prompt")
+                self.virsh_cmd = "virsh --connect  %s+ssh://%s@%s/system" % (
+                                   self.virsh_driver, self.virsh_username,
+                                     self.virsh_hostname)
+                virt = virt_utils.virsh_login(self.virsh_password,
+                                      self.virsh_prompt, self.virsh_hostname,
+                                      self.virsh_driver, self.virsh_username)
+                virt_tmp = tempfile.mkdtemp(prefix='virt_', dir='/tmp')
+                virt_xml = os.path.join(virt_tmp, self.name+".xml")
+                xml_create = "virsh domxml-from-native qemu-argv  %s > %s"%(
+                                                          qemu_args, virt_xml)
+                data = os.popen(xml_create).readlines()
+                xml_handle = open(virt_xml)
+                xml_pars = parse(xml_handle)
+                xml_pars.normalize()
+
+                xml_nod = xml_pars.getElementsByTagName('os')[0]
+                chld_elem = xml_nod.getElementsByTagName("type")[0]
+                chld_elem.setAttribute('arch','x86_64')
+                xml_nod = xml_pars.getElementsByTagName('interface')[0]
+                xml_nod.setAttribute('type', 'network')
+                xml_sib = xml_pars.getElementsByTagName('interface')[0].\
+                                                                 nextSibling
+
+                xml_clnod = xml_nod.cloneNode(True)
+                net_dic = dict(re.findall("(netdev|mac|id)=([^,\s]+)", dict(
+                                                        net_info)['device']))
+                net_model = re.findall("(^\S+?),", dict(net_info)['device'])[0]
+                chld_elem = xml_clnod.getElementsByTagName("mac")[0]
+                chld_elem.setAttribute('address', net_dic['mac'])
+                new_nod = chld_elem.cloneNode(True)
+                new_nod.setAttribute('type', net_model)
+                new_nod.removeAttribute('address')
+                new_nod.tagName = "model"
+                xml_clnod.appendChild(new_nod)
+
+                new_nod = chld_elem.cloneNode(True)
+                new_nod.setAttribute('network','default')
+                new_nod.removeAttribute('address')
+                new_nod.tagName = "source"
+                xml_clnod.appendChild(new_nod)
+
+                new_nod = chld_elem.cloneNode(True)
+                new_nod.setAttribute('dev', net_dic['id'])
+                new_nod.removeAttribute('address')
+                new_nod.tagName = "target"
+                xml_clnod.appendChild(new_nod)
+
+                xml_nod.parentNode.insertBefore(xml_clnod, xml_sib)
+                xml_nod.parentNode.removeChild(xml_nod)
+
+
+
+                tmp_xml = xml_pars.toxml()
+                virt_xml = os.path.join(virt_tmp, "virt_"+self.name+".xml")
+                f = open(virt_xml,'w')
+                f.write(tmp_xml)
+                f.close()
+
+                self.process = virt_utils.virsh_login(self.virsh_password,
+                                self.virsh_prompt, self.virsh_hostname,
+                                self.virsh_driver, self.virsh_username)
+                virt.sendline("define %s \n" % virt_xml)
+                logging.debug("Defining virsh with xml:\n%s" % virt_xml)
+                virt.sendline("start %s \n" % self.name)
+                start_output=virt.get_command_output("\n")
+                if "error:" in start_output:
+                    e = virt_vm.VMCreateError("virsh start", "defined",
+                                               start_output)
+                    virt.sendline("undefine %s" % self.name)
+                    self.destroy()
+                    raise e
+
+                virt.sendline('quit')
+            else:
+                logging.debug("Running qemu command:\n%s"% qemu_command)
+                self.process = aexpect.run_bg(qemu_command, None,
+                                                     logging.debug, "(qemu) ")
             for tapfd in self.tapfds:
                 try:
                     os.close(tapfd)
@@ -810,11 +921,16 @@ class VM(virt_vm.BaseVM):
                             monitor = kvm_monitor.QMPMonitor(
                                 monitor_name,
                                 self.get_monitor_filename(monitor_name))
-                        else:
+                        if monitor_params.get("monitor_type") == "human":
                             # Add a "human" monitor
                             monitor = kvm_monitor.HumanMonitor(
                                 monitor_name,
                                 self.get_monitor_filename(monitor_name))
+                        else:
+                           monitor = kvm_monitor.VirshMonitor(
+                                monitor_name, self.name,self.virsh_password,
+                                 self.virsh_prompt, self.virsh_hostname,
+                                   self.virsh_driver, self.virsh_username)
                         monitor.verify_responsive()
                         break
                     except kvm_monitor.MonitorError, e:
@@ -844,11 +960,18 @@ class VM(virt_vm.BaseVM):
 
             # Establish a session with the serial console -- requires a version
             # of netcat that supports -U
-            self.serial_console = aexpect.ShellSession(
-                "nc -U %s" % self.get_serial_console_filename(),
-                auto_close=False,
-                output_func=virt_utils.log_line,
-                output_params=("serial-%s.log" % name,))
+            if self.virsh:
+                self.serial_console = aexpect.ShellSession(
+                    "virsh console %s" %self.name,
+                    auto_close=False,
+                    output_func=virt_utils.log_line,
+                    output_params=("serial-%s.log" % name,))
+            else:
+                self.serial_console = aexpect.ShellSession(
+                    "nc -U %s" % self.get_serial_console_filename(),
+                    auto_close=False,
+                    output_func=virt_utils.log_line,
+                    output_params=("serial-%s.log" % name,))
 
         finally:
             fcntl.lockf(lockfile, fcntl.LOCK_UN)
diff --git a/client/virt/virt_utils.py b/client/virt/virt_utils.py
index d443a84..750b87e 100644
--- a/client/virt/virt_utils.py
+++ b/client/virt/virt_utils.py
@@ -669,6 +669,32 @@ def _remote_login(session, username, password, prompt, 
timeout=10):
         except aexpect.ExpectProcessTerminatedError, e:
             raise LoginProcessTerminatedError(e.status, e.output)
 
+def virsh_login( password, prompt, host='localhost', driver='qemu',
+                 username='root', linesep="\n", timeout=10):
+    """
+    Log into a remote host (hypervisor) using required URIs .
+
+    @param password: Password
+    @param prompt: Shell prompt (regular expression)
+    @param host: Hostname or IP address
+    @param driver: Hypervisor driver
+    @param username: Username
+    @param linesep: The line separator to use when sending lines
+            (e.g. '\\n' or '\\r\\n')
+    @timeout: Time in seconds that we will wait before giving up on logging
+            into the host.
+    @return: A ShellSession object.
+    """
+    if driver == "qemu":
+        command = "virsh --connect  %s+ssh://%s@%s/system" % (driver, username,
+                                                                          host)
+    session = aexpect.ShellSession(command, linesep=linesep, prompt=prompt)
+    try:
+        _remote_login(session, username, password, prompt, timeout)
+    except:
+        session.close()
+    return session
+
 
 def remote_login(client, host, port, username, password, prompt, linesep="\n",
                  log_filename=None, timeout=10):
-- 
1.7.0.4

_______________________________________________
Autotest mailing list
[email protected]
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest

Reply via email to