diff mbox

[KVM-AUTOTEST] kvm test: Adding remote migration support

Message ID 1245199610-6338-1-git-send-email-lmr@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Lucas Meneghel Rodrigues June 17, 2009, 12:46 a.m. UTC
Make the current migration test handle remote migration. In order to
use remote migration, the following four parameters should be added
to the existing migration test:

       remote = dst
       hostip = <localhost ip or name>
       remoteip = <remote host ip or name>
       remuser = root
       rempassword = <password>

The field remote=dst indicates the VM "dst" should be created on remote
machine. For example:

   - migrate:      install setup
       type = migration
       vms += " dst"
       migration_test_command = help
       kill_vm_on_error = yes
       remote = dst
       hostip = 192.168.1.2
       remoteip = 192.168.1.3
       remuser = root
       rempassword = 123456
       variants:

Signed-off-by: Yogananth Subramanian <anantyog@in.ibm.com>
---
 client/tests/kvm/kvm_tests.cfg.sample |    6 +++
 client/tests/kvm/kvm_tests.py         |    2 +-
 client/tests/kvm/kvm_vm.py            |   61 +++++++++++++++++++++++++--------
 3 files changed, 53 insertions(+), 16 deletions(-)

Comments

Lucas Meneghel Rodrigues June 17, 2009, 12:53 a.m. UTC | #1
On Tue, 2009-06-16 at 21:46 -0300, Lucas Meneghel Rodrigues wrote:
> Make the current migration test handle remote migration. In order to
> use remote migration, the following four parameters should be added
> to the existing migration test:

I went trough the discussion about this patch and I also agree we should
be implementing this test as a server side test. However I thought it
would be good having this patch rebased to the new kvm test code just in
case we need it in the future. This is part of the patch queue work.

>        remote = dst
>        hostip = <localhost ip or name>
>        remoteip = <remote host ip or name>
>        remuser = root
>        rempassword = <password>
> 
> The field remote=dst indicates the VM "dst" should be created on remote
> machine. For example:
> 
>    - migrate:      install setup
>        type = migration
>        vms += " dst"
>        migration_test_command = help
>        kill_vm_on_error = yes
>        remote = dst
>        hostip = 192.168.1.2
>        remoteip = 192.168.1.3
>        remuser = root
>        rempassword = 123456
>        variants:
> 
> Signed-off-by: Yogananth Subramanian <anantyog@in.ibm.com>
> ---
>  client/tests/kvm/kvm_tests.cfg.sample |    6 +++
>  client/tests/kvm/kvm_tests.py         |    2 +-
>  client/tests/kvm/kvm_vm.py            |   61 +++++++++++++++++++++++++--------
>  3 files changed, 53 insertions(+), 16 deletions(-)
> 
> diff --git a/client/tests/kvm/kvm_tests.cfg.sample b/client/tests/kvm/kvm_tests.cfg.sample
> index 931f748..ca7f1d0 100644
> --- a/client/tests/kvm/kvm_tests.cfg.sample
> +++ b/client/tests/kvm/kvm_tests.cfg.sample
> @@ -54,6 +54,12 @@ variants:
>          vms += " dst"
>          migration_test_command = help
>          kill_vm_on_error = yes
> +        remote = dst
> +        hostip = 192.168.1.2
> +        remoteip = 192.168.1.3
> +        remuser = root
> +        rempassword = 123456
> +        kill_vm_on_error = yes
>          variants:
>              - 1:
>                  start_vm_for_migration_dst = yes
> diff --git a/client/tests/kvm/kvm_tests.py b/client/tests/kvm/kvm_tests.py
> index 4270cae..32b1ba4 100644
> --- a/client/tests/kvm/kvm_tests.py
> +++ b/client/tests/kvm/kvm_tests.py
> @@ -113,7 +113,7 @@ def run_migration(test, params, env):
>      session.close()
>  
>      # Define the migration command
> -    cmd = "migrate -d tcp:localhost:%d" % dest_vm.migration_port
> +    cmd = "migrate -d tcp:%s:%d" % (dest_vm.hostip, dest_vm.migration_port)
>      logging.debug("Migration command: %s" % cmd)
>  
>      # Migrate
> diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
> index 5028161..c15d0a1 100644
> --- a/client/tests/kvm/kvm_vm.py
> +++ b/client/tests/kvm/kvm_vm.py
> @@ -1,5 +1,5 @@
>  #!/usr/bin/python
> -import time, socket, os, logging, fcntl
> +import time, socket, os, logging, fcntl, re
>  import kvm_utils
>  
>  """
> @@ -113,6 +113,7 @@ class VM:
>          self.qemu_path = qemu_path
>          self.image_dir = image_dir
>          self.iso_dir = iso_dir
> +        self.remote = False
>  
> 
>          # Find available monitor filename
> @@ -170,8 +171,6 @@ class VM:
>          file.close()
>          if not self.qemu_path in cmdline:
>              return False
> -        if not self.monitor_file_name in cmdline:
> -            return False
>          return True
>  
> 
> @@ -234,8 +233,6 @@ class VM:
>          qemu_cmd += qemu_path
>          # Add the VM's name
>          qemu_cmd += " -name '%s'" % name
> -        # Add the monitor socket parameter
> -        qemu_cmd += " -monitor unix:%s,server,nowait" % self.monitor_file_name
>  
>          for image_name in kvm_utils.get_sub_dict_names(params, "images"):
>              image_params = kvm_utils.get_sub_dict(params, image_name)
> @@ -320,6 +317,18 @@ class VM:
>          qemu_path = self.qemu_path
>          image_dir = self.image_dir
>          iso_dir = self.iso_dir
> +        # If VM is remote, set hostip to ip of the remote machine
> +        # If VM is local set hostip to localhost or hostip param
> +        if params.get("remote") == "yes":
> +            self.remote = True
> +            self.hostip = params.get("remoteip")
> +            self.qemu_path = params.get("qemu_path",qemu_path)
> +            qemu_path = self.qemu_path
> +            self.image_dir = params.get("image_dir",image_dir)
> +            image_dir = self.image_dir
> +        else:
> +            self.remote = False
> +            self.hostip = params.get("hostip","localhost")
>  
>          # Verify the md5sum of the ISO image
>          iso = params.get("cdrom")
> @@ -377,9 +386,32 @@ class VM:
>                  # Add -incoming option to the qemu command
>                  qemu_command += " -incoming tcp:0:%d" % self.migration_port
>  
> -            logging.debug("Running qemu command:\n%s", qemu_command)
> -            (status, pid, output) = kvm_utils.run_bg(qemu_command, None,
> -                                                     logging.debug, "(qemu) ")
> +            self.monitor_port = kvm_utils.find_free_port(5400, 6000)
> +            qemu_command += (" -monitor tcp:0:%d,server,nowait" %
> +                             self.monitor_port)
> +
> +            # If the VM is remote, get the username and password of remote host
> +            # and lanch qemu command on the remote machine.
> +            if self.remote:
> +                remuser = params.get("remuser")
> +                rempassword = params.get("rempassword")
> +                sub = kvm_utils.ssh(self.hostip, 22, remuser, rempassword,
> +                                    self.params.get("ssh_prompt", "[\#\$]"))
> +                qemu_command +=" &"
> +                kvm_log.debug("Running qemu command:\n%s" % qemu_command)
> +                sub.sendline(qemu_command)
> +
> +                (status,output) = sub.read_up_to_prompt()
> +                if "Exit " in output:
> +                    status = int(re.findall("Exit\s(\d+)",output)[0])
> +                else:
> +                    pid = int(re.findall(".*] (\d+)",output)[0])
> +                    status = 0
> +            else:
> +                kvm_log.debug("Running qemu command:\n%s" % qemu_command)
> +                (status, pid, output) = kvm_utils.run_bg(qemu_command, None,
> +                                                         kvm_log.debug,
> +                                                         "(qemu) ")
>  
>              if status:
>                  logging.debug("qemu exited with status %d", status)
> @@ -450,9 +482,8 @@ class VM:
>          # Connect to monitor
>          logging.debug("Sending monitor command: %s" % command)
>          try:
> -            s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
> -            s.setblocking(False)
> -            s.connect(self.monitor_file_name)
> +            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
> +            s.connect((self.hostip, self.monitor_port))
>          except:
>              logging.debug("Could not connect to monitor socket")
>              return (1, "")
> @@ -542,8 +573,9 @@ class VM:
>          Return True if the VM's monitor is responsive.
>          """
>          # Check if the process exists
> -        if not kvm_utils.pid_exists(self.pid):
> -            return False
> +        if not self.remote:
> +            if not kvm_utils.pid_exists(self.pid):
> +                return False
>          # Try sending a monitor command
>          (status, output) = self.send_monitor_cmd("help")
>          if status:
> @@ -573,8 +605,7 @@ class VM:
>          If port redirection is used, return 'localhost' (the guest has no IP
>          address of its own).  Otherwise return the guest's IP address.
>          """
> -        # Currently redirection is always used, so return 'localhost'
> -        return "localhost"
> +        return self.hostip
>  
> 
>      def get_port(self, port):
diff mbox

Patch

diff --git a/client/tests/kvm/kvm_tests.cfg.sample b/client/tests/kvm/kvm_tests.cfg.sample
index 931f748..ca7f1d0 100644
--- a/client/tests/kvm/kvm_tests.cfg.sample
+++ b/client/tests/kvm/kvm_tests.cfg.sample
@@ -54,6 +54,12 @@  variants:
         vms += " dst"
         migration_test_command = help
         kill_vm_on_error = yes
+        remote = dst
+        hostip = 192.168.1.2
+        remoteip = 192.168.1.3
+        remuser = root
+        rempassword = 123456
+        kill_vm_on_error = yes
         variants:
             - 1:
                 start_vm_for_migration_dst = yes
diff --git a/client/tests/kvm/kvm_tests.py b/client/tests/kvm/kvm_tests.py
index 4270cae..32b1ba4 100644
--- a/client/tests/kvm/kvm_tests.py
+++ b/client/tests/kvm/kvm_tests.py
@@ -113,7 +113,7 @@  def run_migration(test, params, env):
     session.close()
 
     # Define the migration command
-    cmd = "migrate -d tcp:localhost:%d" % dest_vm.migration_port
+    cmd = "migrate -d tcp:%s:%d" % (dest_vm.hostip, dest_vm.migration_port)
     logging.debug("Migration command: %s" % cmd)
 
     # Migrate
diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 5028161..c15d0a1 100644
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -1,5 +1,5 @@ 
 #!/usr/bin/python
-import time, socket, os, logging, fcntl
+import time, socket, os, logging, fcntl, re
 import kvm_utils
 
 """
@@ -113,6 +113,7 @@  class VM:
         self.qemu_path = qemu_path
         self.image_dir = image_dir
         self.iso_dir = iso_dir
+        self.remote = False
 
 
         # Find available monitor filename
@@ -170,8 +171,6 @@  class VM:
         file.close()
         if not self.qemu_path in cmdline:
             return False
-        if not self.monitor_file_name in cmdline:
-            return False
         return True
 
 
@@ -234,8 +233,6 @@  class VM:
         qemu_cmd += qemu_path
         # Add the VM's name
         qemu_cmd += " -name '%s'" % name
-        # Add the monitor socket parameter
-        qemu_cmd += " -monitor unix:%s,server,nowait" % self.monitor_file_name
 
         for image_name in kvm_utils.get_sub_dict_names(params, "images"):
             image_params = kvm_utils.get_sub_dict(params, image_name)
@@ -320,6 +317,18 @@  class VM:
         qemu_path = self.qemu_path
         image_dir = self.image_dir
         iso_dir = self.iso_dir
+        # If VM is remote, set hostip to ip of the remote machine
+        # If VM is local set hostip to localhost or hostip param
+        if params.get("remote") == "yes":
+            self.remote = True
+            self.hostip = params.get("remoteip")
+            self.qemu_path = params.get("qemu_path",qemu_path)
+            qemu_path = self.qemu_path
+            self.image_dir = params.get("image_dir",image_dir)
+            image_dir = self.image_dir
+        else:
+            self.remote = False
+            self.hostip = params.get("hostip","localhost")
 
         # Verify the md5sum of the ISO image
         iso = params.get("cdrom")
@@ -377,9 +386,32 @@  class VM:
                 # Add -incoming option to the qemu command
                 qemu_command += " -incoming tcp:0:%d" % self.migration_port
 
-            logging.debug("Running qemu command:\n%s", qemu_command)
-            (status, pid, output) = kvm_utils.run_bg(qemu_command, None,
-                                                     logging.debug, "(qemu) ")
+            self.monitor_port = kvm_utils.find_free_port(5400, 6000)
+            qemu_command += (" -monitor tcp:0:%d,server,nowait" %
+                             self.monitor_port)
+
+            # If the VM is remote, get the username and password of remote host
+            # and lanch qemu command on the remote machine.
+            if self.remote:
+                remuser = params.get("remuser")
+                rempassword = params.get("rempassword")
+                sub = kvm_utils.ssh(self.hostip, 22, remuser, rempassword,
+                                    self.params.get("ssh_prompt", "[\#\$]"))
+                qemu_command +=" &"
+                kvm_log.debug("Running qemu command:\n%s" % qemu_command)
+                sub.sendline(qemu_command)
+
+                (status,output) = sub.read_up_to_prompt()
+                if "Exit " in output:
+                    status = int(re.findall("Exit\s(\d+)",output)[0])
+                else:
+                    pid = int(re.findall(".*] (\d+)",output)[0])
+                    status = 0
+            else:
+                kvm_log.debug("Running qemu command:\n%s" % qemu_command)
+                (status, pid, output) = kvm_utils.run_bg(qemu_command, None,
+                                                         kvm_log.debug,
+                                                         "(qemu) ")
 
             if status:
                 logging.debug("qemu exited with status %d", status)
@@ -450,9 +482,8 @@  class VM:
         # Connect to monitor
         logging.debug("Sending monitor command: %s" % command)
         try:
-            s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-            s.setblocking(False)
-            s.connect(self.monitor_file_name)
+            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            s.connect((self.hostip, self.monitor_port))
         except:
             logging.debug("Could not connect to monitor socket")
             return (1, "")
@@ -542,8 +573,9 @@  class VM:
         Return True if the VM's monitor is responsive.
         """
         # Check if the process exists
-        if not kvm_utils.pid_exists(self.pid):
-            return False
+        if not self.remote:
+            if not kvm_utils.pid_exists(self.pid):
+                return False
         # Try sending a monitor command
         (status, output) = self.send_monitor_cmd("help")
         if status:
@@ -573,8 +605,7 @@  class VM:
         If port redirection is used, return 'localhost' (the guest has no IP
         address of its own).  Otherwise return the guest's IP address.
         """
-        # Currently redirection is always used, so return 'localhost'
-        return "localhost"
+        return self.hostip
 
 
     def get_port(self, port):