diff mbox

[KVM-AUTOTEST] support for remote migration

Message ID 1241092606.9730.28.camel@yogi-laptop (mailing list archive)
State New, archived
Headers show

Commit Message

yogi April 30, 2009, 11:56 a.m. UTC
Hello everyone,

I like to submit patch to add support for "remote migration" in
kvm-autotest.

To use this patch 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:

Three files r being modified in this patch kvm_utils.py, kvm_tests.py
and kvm_vm.py.
kvm_utils.py - if the  ssh-keys have been exchanged between the test
machines,then remote login fails with message "Got unexpected login
prompt", to prevent this, have made it return a session rather then None

kvm_tests.py - the host address used in migration is made dynamic

kvm_vm.py -    have replaced unix sockets with tcp sockets for monitor,
in both remote and local VM. Added two new variables(remote,ssh_port) to
class VM,remote set to True if the VM is on a  remote machine,ssh_port
contains the redirection port, funtion get_address() returns the ip of
the host whr the VM is(local or remote).

Thx
Yogi

Comments

David Huff April 30, 2009, 1:55 p.m. UTC | #1
yogi wrote:
> Hello everyone,
> 
> I like to submit patch to add support for "remote migration" in
> kvm-autotest.
> 

Thanks for the patch, Uri is out on vacation for a while. I'll apply the 
patch to my test repo and do some validation testing, however may be a 
little while untill it makes it in.

-D
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

 kvm_tests.py |    2 -
 kvm_utils.py |    3 --
 kvm_vm.py    |   61 ++++++++++++++++++++++++++++++++++++++++++++---------------
 3 files changed, 48 insertions(+), 18 deletions(-)

Signed-off-by: Yogananth Subramanian <anantyog@in.ibm.com>
---
diff -aurp kvm-autotest.orgi//client/tests/kvm_runtest_2/kvm_tests.py kvm-autotest/client/tests/kvm_runtest_2/kvm_tests.py
--- kvm-autotest.orgi//client/tests/kvm_runtest_2/kvm_tests.py	2009-04-29 18:33:10.000000000 +0000
+++ kvm-autotest/client/tests/kvm_runtest_2/kvm_tests.py	2009-04-30 05:59:24.000000000 +0000
@@ -81,7 +81,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)
     kvm_log.debug("Migration command: %s" % cmd)
 
     # Migrate
diff -aurp kvm-autotest.orgi//client/tests/kvm_runtest_2/kvm_utils.py kvm-autotest/client/tests/kvm_runtest_2/kvm_utils.py
--- kvm-autotest.orgi//client/tests/kvm_runtest_2/kvm_utils.py	2009-04-29 18:33:10.000000000 +0000
+++ kvm-autotest/client/tests/kvm_runtest_2/kvm_utils.py	2009-04-30 06:13:47.000000000 +0000
@@ -431,8 +431,7 @@  def remote_login(command, password, prom
                 return None
         elif match == 2:  # "login:"
             kvm_log.debug("Got unexpected login prompt")
-            sub.close()
-            return None
+            return sub
         elif match == 3:  # "Connection closed"
             kvm_log.debug("Got 'Connection closed'")
             sub.close()
diff -aurp kvm-autotest.orgi//client/tests/kvm_runtest_2/kvm_vm.py kvm-autotest/client/tests/kvm_runtest_2/kvm_vm.py
--- kvm-autotest.orgi//client/tests/kvm_runtest_2/kvm_vm.py	2009-04-29 18:33:10.000000000 +0000
+++ kvm-autotest/client/tests/kvm_runtest_2/kvm_vm.py	2009-04-30 06:31:34.000000000 +0000
@@ -3,6 +3,7 @@ 
 import time
 import socket
 import os
+import re
 
 import kvm_utils
 import kvm_log
@@ -105,6 +106,7 @@  class VM:
         self.qemu_path = qemu_path
         self.image_dir = image_dir
         self.iso_dir = iso_dir
+        self.remote = False
 
     def verify_process_identity(self):
         """Make sure .pid really points to the original qemu process.
@@ -124,8 +126,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
 
     def make_qemu_command(self, name=None, params=None, qemu_path=None, image_dir=None, iso_dir=None):
@@ -173,7 +173,6 @@  class VM:
 
         qemu_cmd = qemu_path
         qemu_cmd += " -name '%s'" % name
-        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)
@@ -211,6 +210,7 @@  class VM:
             redir_params = kvm_utils.get_sub_dict(params, redir_name)
             guest_port = int(redir_params.get("guest_port"))
             host_port = self.get_port(guest_port)
+            self.ssh_port = host_port
             qemu_cmd += " -redir tcp:%s::%s" % (host_port, guest_port)
 
         if params.get("display") == "vnc":
@@ -254,6 +254,17 @@  class VM:
         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") == self.name:
+            self.remote = True
+            self.hostip = params.get("remoteip")
+        else:
+            self.remote = False
+            self.hostip = params.get("hostip","localhost")
+
+
+
         # Verify the md5sum of the ISO image
         iso = params.get("cdrom")
         if iso:
@@ -310,8 +321,28 @@  class VM:
             # Add -incoming option to the qemu command
             qemu_command += " -incoming tcp:0:%d" % self.migration_port
 
-        kvm_log.debug("Running qemu command:\n%s" % qemu_command)
-        (status, pid, output) = kvm_utils.run_bg(qemu_command, None, kvm_log.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:
             kvm_log.debug("qemu exited with status %d" % status)
@@ -363,9 +394,8 @@  class VM:
         # Connect to monitor
         kvm_log.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:
             kvm_log.debug("Could not connect to monitor socket")
             return (1, "")
@@ -442,8 +472,9 @@  class VM:
     def is_alive(self):
         """Return True iff 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:
@@ -468,7 +499,7 @@  class VM:
         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):
         """Return the port in host space corresponding to port in guest space.
@@ -486,7 +517,7 @@  class VM:
     def is_sshd_running(self, timeout=10):
         """Return True iff the guest's SSH port is responsive."""
         address = self.get_address()
-        port = self.get_port(int(self.params.get("ssh_port")))
+        port = self.ssh_port
         if not port:
             return False
         return kvm_utils.is_sshd_running(address, port, timeout=timeout)
@@ -503,7 +534,7 @@  class VM:
         prompt = self.params.get("ssh_prompt", "[\#\$]")
         use_telnet = self.params.get("use_telnet") == "yes"
         address = self.get_address()
-        port = self.get_port(int(self.params.get("ssh_port")))
+        port = self.ssh_port
         if not port:
             return None
 
@@ -520,7 +551,7 @@  class VM:
         username = self.params.get("username", "")
         password = self.params.get("password", "")
         address = self.get_address()
-        port = self.get_port(int(self.params.get("ssh_port")))
+        port = self.ssh_port
         if not port:
             return None
         return kvm_utils.scp_to_remote(address, port, username, password, local_path, remote_path, timeout)
@@ -530,7 +561,7 @@  class VM:
         username = self.params.get("username", "")
         password = self.params.get("password", "")
         address = self.get_address()
-        port = self.get_port(int(self.params.get("ssh_port")))
+        port = self.ssh_port
         if not port:
             return None
         return kvm_utils.scp_from_remote(address, port, username, password, remote_path, local_path, timeout)