All of lore.kernel.org
 help / color / mirror / Atom feed
* [KVM-AUTOTEST PATCH 0/6] KVM test: configuration interface changes
@ 2009-08-09 16:33 Michael Goldish
  2009-08-09 16:33 ` [KVM-AUTOTEST PATCH 1/6] KVM test: rename SSH related parameters and functions and add new ones Michael Goldish
  2009-08-17 20:54 ` [Autotest] [KVM-AUTOTEST PATCH 0/6] KVM test: configuration interface changes Lucas Meneghel Rodrigues
  0 siblings, 2 replies; 8+ messages in thread
From: Michael Goldish @ 2009-08-09 16:33 UTC (permalink / raw)
  To: autotest, kvm


This patch set modifies the names and functionality of several config
parameters and adds new ones.
It also adds support for Netcat as a remote shell client.

It breaks compatibility with existing test configurations.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [KVM-AUTOTEST PATCH 1/6] KVM test: rename SSH related parameters and functions and add new ones
  2009-08-09 16:33 [KVM-AUTOTEST PATCH 0/6] KVM test: configuration interface changes Michael Goldish
@ 2009-08-09 16:33 ` Michael Goldish
  2009-08-09 16:33   ` [KVM-AUTOTEST PATCH 2/6] KVM test: support Netcat as a remote shell client Michael Goldish
  2009-08-17 20:54 ` [Autotest] [KVM-AUTOTEST PATCH 0/6] KVM test: configuration interface changes Lucas Meneghel Rodrigues
  1 sibling, 1 reply; 8+ messages in thread
From: Michael Goldish @ 2009-08-09 16:33 UTC (permalink / raw)
  To: autotest, kvm; +Cc: Michael Goldish

(This patch breaks compatibility with existing config files.)

We now support both SSH and Telnet for communicating with guests, and will soon
use Netcat as well.  It makes no sense to keep 'ssh' in the names of many
remote shell related functions and parameters.  Therefore the following
renaming was performed:

Functions:
ssh_login -> remote_login
scp_to_remote -> copy_files_to
scp_from_remote -> copy_files_from

Config parameters:
ssh_port -> shell_port
guest_port_ssh -> guest_port_remote_shell
ssh_prompt -> shell_prompt
ssh_status_test_command -> status_test_command
cmd_shutdown -> shutdown_command
cmd_reboot -> reboot_command

Also, new parameters were added:
shell_client (ssh, telnet or nc)
file_transfer_client (currently only scp)
file_transfer_port

The parameter use_telnet was removed, as well as the function VM.ssh().

Signed-off-by: Michael Goldish <mgoldish@redhat.com>
---
 client/tests/kvm/kvm_tests.cfg.sample |   47 ++++++++-----
 client/tests/kvm/kvm_tests.py         |   52 +++++++-------
 client/tests/kvm/kvm_utils.py         |   26 ++++---
 client/tests/kvm/kvm_vm.py            |  121 ++++++++++++++++-----------------
 4 files changed, 127 insertions(+), 119 deletions(-)

diff --git a/client/tests/kvm/kvm_tests.cfg.sample b/client/tests/kvm/kvm_tests.cfg.sample
index 3a4bf64..8238f3e 100644
--- a/client/tests/kvm/kvm_tests.cfg.sample
+++ b/client/tests/kvm/kvm_tests.cfg.sample
@@ -17,12 +17,12 @@ kill_vm_gracefully = yes
 # Some default VM params
 mem = 512
 image_size = 10G
-ssh_port = 22
+shell_port = 22
 display = vnc
 
 # Port redirections
-redirs = ssh
-guest_port_ssh = 22
+redirs = remote_shell
+guest_port_remote_shell = 22
 
 # NIC parameters
 nic_mode = tap
@@ -146,16 +146,20 @@ variants:
     # Linux section
     - @Linux:
         no timedrift
-        cmd_shutdown = shutdown -h now
-        cmd_reboot = shutdown -r now
-        ssh_status_test_command = echo $?
+        shutdown_command = shutdown -h now
+        reboot_command = shutdown -r now
+        status_test_command = echo $?
         username = root
         password = 123456
+        shell_client = ssh
+        shell_port = 22
+        file_transfer_client = scp
+        file_transfer_port = 22
 
         variants:
             - Fedora:
                 no setup
-                ssh_prompt = "\[root@.{0,50}][\#\$] "
+                shell_prompt = "\[root@.{0,50}][\#\$] "
 
                 variants:
                     - 8.32:
@@ -237,7 +241,7 @@ variants:
                     md5sum_1m = 768ca32503ef92c28f2d144f2a87e4d0
 
             - @Ubuntu:
-                ssh_prompt = "root@.{0,50}[\#\$] "
+                shell_prompt = "root@.{0,50}[\#\$] "
 
                 variants:
                     - Ubuntu-6.10-32:
@@ -269,7 +273,7 @@ variants:
 
             - RHEL:
                 no setup
-                ssh_prompt = "\[root@.{0,50}][\#\$] "
+                shell_prompt = "\[root@.{0,50}][\#\$] "
 
                 variants:
                     - 5.3.i386:
@@ -329,12 +333,17 @@ variants:
     # Windows section
     - @Windows:
         no autotest
-        cmd_shutdown = shutdown /s /t 0
-        cmd_reboot = shutdown /r /t 0
-        ssh_prompt = "C:\\.{0,50}>"
-        ssh_status_test_command = echo %errorlevel%
+        shutdown_command = shutdown /s /t 0
+        reboot_command = shutdown /r /t 0
+        status_test_command = echo %errorlevel%
+        shell_prompt = "C:\\.{0,50}>"
         username = Administrator
         password = 123456
+        shell_client = ssh
+        shell_port = 22
+        file_transfer_client = scp
+        file_transfer_port = 22
+
         migrate:
             migration_test_command = ver && vol
         stress_boot:
@@ -394,8 +403,8 @@ variants:
 
             - Win2003:
                 image_size = 20G
-                cmd_shutdown = shutdown /s /f /t 0
-                cmd_reboot = shutdown /r /f /t 0
+                shutdown_command = shutdown /s /f /t 0
+                reboot_command = shutdown /r /f /t 0
 
                 variants:
                     - 32:
@@ -443,10 +452,10 @@ variants:
             - Win2008:
                 image_name = win2008
                 image_size = 20G
-                cmd_shutdown = shutdown /s /f /t 0
-                cmd_reboot = shutdown /r /f /t 0
-                ssh_port = 23
-                guest_port_ssh = 23
+                shutdown_command = shutdown /s /f /t 0
+                reboot_command = shutdown /r /f /t 0
+                shell_port = 23
+                guest_port_remote_shell = 23
                 use_telnet = yes
                 username = Administrator
                 password = 1q2w3eP
diff --git a/client/tests/kvm/kvm_tests.py b/client/tests/kvm/kvm_tests.py
index d146929..3fa0837 100644
--- a/client/tests/kvm/kvm_tests.py
+++ b/client/tests/kvm/kvm_tests.py
@@ -29,7 +29,7 @@ def run_boot(test, params, env):
 
     logging.info("Waiting for guest to be up...")
 
-    session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
+    session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2)
     if not session:
         raise error.TestFail("Could not log into guest")
 
@@ -37,7 +37,7 @@ def run_boot(test, params, env):
 
     if params.get("reboot") == "yes":
         # Send the VM's reboot command
-        session.sendline(vm.get_params().get("cmd_reboot"))
+        session.sendline(vm.get_params().get("reboot_command"))
         logging.info("Reboot command sent; waiting for guest to go down...")
 
         if not kvm_utils.wait_for(lambda: not session.is_responsive(),
@@ -48,7 +48,7 @@ def run_boot(test, params, env):
 
         logging.info("Guest is down; waiting for it to go up again...")
 
-        session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
+        session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2)
         if not session:
             raise error.TestFail("Could not log into guest after reboot")
 
@@ -76,14 +76,14 @@ def run_shutdown(test, params, env):
 
     logging.info("Waiting for guest to be up...")
 
-    session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
+    session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2)
     if not session:
         raise error.TestFail("Could not log into guest")
 
     logging.info("Logged in")
 
     # Send the VM's shutdown command
-    session.sendline(vm.get_params().get("cmd_shutdown"))
+    session.sendline(vm.get_params().get("shutdown_command"))
     session.close()
 
     logging.info("Shutdown command sent; waiting for guest to go down...")
@@ -139,7 +139,7 @@ def run_migration(test, params, env):
     # Log into guest and get the output of migration_test_command
     logging.info("Waiting for guest to be up...")
 
-    session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
+    session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2)
     if not session:
         raise error.TestFail("Could not log into guest")
 
@@ -208,14 +208,14 @@ def run_migration(test, params, env):
 
     # Hack: it seems that the first attempt to communicate with the SSH port
     # following migration always fails (or succeeds after a very long time).
-    # So just connect to the port once so the following call to ssh_login
+    # So just connect to the port once so the following call to remote_login
     # succeeds.
     dest_vm.is_sshd_running(timeout=0.0)
 
     # Log into guest and get the output of migration_test_command
     logging.info("Logging into guest after migration...")
 
-    session = dest_vm.ssh_login()
+    session = dest_vm.remote_login()
     if not session:
         raise error.TestFail("Could not log into guest after migration")
 
@@ -252,7 +252,7 @@ def run_autotest(test, params, env):
 
     logging.info("Logging into guest...")
 
-    session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
+    session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2)
     if not session:
         raise error.TestFail("Could not log into guest")
 
@@ -298,7 +298,7 @@ def run_autotest(test, params, env):
     if copy:
         logging.info("Copying autotest.tar.bz2 to guest"
                      " (file is missing or has a different size)...")
-        if not vm.scp_to_remote(tarred_autotest_path, ""):
+        if not vm.copy_files_to(tarred_autotest_path, ""):
             raise error.TestFail("Could not copy autotest.tar.bz2 to guest")
 
     # Check if we need to copy <test_name>.tar.bz2
@@ -314,7 +314,7 @@ def run_autotest(test, params, env):
     if copy:
         logging.info("Copying %s.tar.bz2 to guest (file is missing or has a"
                      " different size)..." % test_name)
-        if not vm.scp_to_remote(tarred_test_path, ""):
+        if not vm.copy_files_to(tarred_test_path, ""):
             raise error.TestFail("Could not copy %s.tar.bz2 to guest" %
                                  test_name)
 
@@ -340,7 +340,7 @@ def run_autotest(test, params, env):
     # test.bindir/autotest_control to the autotest dir
     control_file_path = os.path.join(test.bindir, "autotest_control",
                                      test_control_file)
-    if not vm.scp_to_remote(control_file_path, "autotest/control"):
+    if not vm.copy_files_to(control_file_path, "autotest/control"):
         raise error.TestFail("Could not copy the test control file to guest")
     # Run the test
     logging.info("Running test '%s'..." % test_name)
@@ -389,7 +389,7 @@ def run_autotest(test, params, env):
     guest_results_dir = os.path.join(test.outputdir, "guest_results")
     if not os.path.exists(guest_results_dir):
         os.mkdir(guest_results_dir)
-    if not vm.scp_from_remote("autotest/results/default/*", guest_results_dir):
+    if not vm.copy_files_from("autotest/results/default/*", guest_results_dir):
         logging.error("Could not copy results back from guest")
 
     # Fail the test if necessary
@@ -403,11 +403,11 @@ def internal_yum_update(session, command, prompt, timeout):
     """
     Helper function to perform the yum update test.
 
-    @param session: SSH session stablished to the host
-    @param command: Command to be sent to the SSH connection
+    @param session: shell session stablished to the host
+    @param command: Command to be sent to the shell session
     @param prompt: Machine prompt
     @param timeout: How long to wait until we get an appropriate output from
-            the SSH session.
+            the shell session.
     """
     session.sendline(command)
     end_time = time.time() + timeout
@@ -446,7 +446,7 @@ def run_yum_update(test, params, env):
 
     logging.info("Logging into guest...")
 
-    session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
+    session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2)
     if not session:
         message = "Could not log into guest"
         logging.error(message)
@@ -454,9 +454,9 @@ def run_yum_update(test, params, env):
 
     logging.info("Logged in")
 
-    internal_yum_update(session, "yum update", params.get("ssh_prompt"), 600)
+    internal_yum_update(session, "yum update", params.get("shell_prompt"), 600)
     internal_yum_update(session, "yum update kernel",
-                        params.get("ssh_prompt"), 600)
+                        params.get("shell_prompt"), 600)
 
     session.close()
 
@@ -477,7 +477,7 @@ def run_linux_s3(test, params, env):
 
     logging.info("Waiting for guest to be up...")
 
-    session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
+    session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2)
     if not session:
         raise error.TestFail("Could not log into guest")
 
@@ -520,7 +520,7 @@ def run_stress_boot(tests, params, env):
     number of VMs successfully started:
     1) boot the first vm
     2) boot the second vm cloned from the first vm, check whether it boots up
-       and all booted vms can ssh-login
+       and all booted vms respond to shell commands
     3) go on until cannot create VM anymore or cannot allocate memory for VM
 
     @param test:   kvm test object
@@ -536,7 +536,7 @@ def run_stress_boot(tests, params, env):
 
     logging.info("Waiting for first guest to be up...")
 
-    session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
+    session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2)
     if not session:
         raise error.TestFail("Could not log into first guest")
 
@@ -560,14 +560,14 @@ def run_stress_boot(tests, params, env):
             if not curr_vm.create():
                 raise error.TestFail("Cannot create VM #%d" % num)
 
-            curr_vm_session = kvm_utils.wait_for(curr_vm.ssh_login, 240, 0, 2)
+            curr_vm_session = kvm_utils.wait_for(curr_vm.remote_login, 240, 0, 2)
             if not curr_vm_session:
                 raise error.TestFail("Could not log into guest #%d" % num)
 
             logging.info("Guest #%d boots up successfully" % num)
             sessions.append(curr_vm_session)
 
-            # check whether all previous ssh sessions are responsive
+            # check whether all previous shell sessions are responsive
             for i, se in enumerate(sessions):
                 if se.get_command_status(params.get("alive_test_cmd")) != 0:
                     raise error.TestFail("Session #%d is not responsive" % i)
@@ -651,7 +651,7 @@ def run_timedrift(test, params, env):
 
     logging.info("Waiting for guest to be up...")
 
-    session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
+    session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2)
     if not session:
         raise error.TestFail("Could not log into guest")
 
@@ -690,7 +690,7 @@ def run_timedrift(test, params, env):
         # Run some load on the guest
         logging.info("Starting load on guest...")
         for i in range(guest_load_instances):
-            load_session = vm.ssh_login()
+            load_session = vm.remote_login()
             if not load_session:
                 raise error.TestFail("Could not log into guest")
             load_session.set_output_prefix("(guest load %d) " % i)
diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index 17c2b73..d1c9781 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -492,9 +492,9 @@ def scp_to_remote(host, port, username, password, local_path, remote_path,
     """
     Copy files to a remote host (guest).
 
-    @param host: Hostname of the guest
-    @param username: User that will be used to copy the files
-    @param password: Host's password
+    @param host: Hostname or IP address
+    @param username: Username (if required)
+    @param password: Password (if required)
     @param local_path: Path on the local machine where we are copying from
     @param remote_path: Path on the remote machine where we are copying to
     @param timeout: Time in seconds that we will wait before giving up to
@@ -512,9 +512,9 @@ def scp_from_remote(host, port, username, password, remote_path, local_path,
     """
     Copy files from a remote host (guest).
 
-    @param host: Hostname of the guest
-    @param username: User that will be used to copy the files
-    @param password: Host's password
+    @param host: Hostname or IP address
+    @param username: Username (if required)
+    @param password: Password (if required)
     @param local_path: Path on the local machine where we are copying from
     @param remote_path: Path on the remote machine where we are copying to
     @param timeout: Time in seconds that we will wait before giving up to copy
@@ -531,9 +531,10 @@ def ssh(host, port, username, password, prompt, timeout=10):
     """
     Log into a remote host (guest) using SSH.
 
-    @param host: Hostname of the guest
-    @param username: User that will be used to log into the host.
-    @param password: Host's password
+    @param host: Hostname or IP address
+    @param username: Username (if required)
+    @param password: Password (if required)
+    @param prompt: Shell prompt (regular expression)
     @timeout: Time in seconds that we will wait before giving up on logging
             into the host.
 
@@ -548,9 +549,10 @@ def telnet(host, port, username, password, prompt, timeout=10):
     """
     Log into a remote host (guest) using Telnet.
 
-    @param host: Hostname of the guest
-    @param username: User that will be used to log into the host.
-    @param password: Host's password
+    @param host: Hostname or IP address
+    @param username: Username (if required)
+    @param password: Password (if required)
+    @param prompt: Shell prompt (regular expression)
     @timeout: Time in seconds that we will wait before giving up on logging
             into the host.
 
diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 2c828c6..4a862bd 100644
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -191,7 +191,10 @@ class VM:
                cdrom -- ISO filename to use with the qemu -cdrom parameter
                (iso_dir is pre-pended to the ISO filename)
                extra_params -- a string to append to the qemu command
-               ssh_port -- should be 22 for SSH, 23 for Telnet
+               shell_port -- port of the remote shell daemon on the guest
+               (SSH, Telnet or the home-made Remote Shell Server)
+               shell_client -- client program to use for connecting to the
+               remote shell daemon on the guest (ssh, telnet or nc)
                x11_display -- if specified, the DISPLAY environment variable
                will be be set to this value for the qemu process (useful for
                SDL rendering)
@@ -533,14 +536,13 @@ class VM:
         """
         Destroy the VM.
 
-        If gracefully is True, first attempt to kill the VM via SSH/Telnet
-        with a shutdown command. Then, attempt to destroy the VM via the
-        monitor with a 'quit' command. If that fails, send SIGKILL to the
-        qemu process.
+        If gracefully is True, first attempt to shutdown the VM with a shell
+        command.  Then, attempt to destroy the VM via the monitor with a 'quit'
+        command.  If that fails, send SIGKILL to the qemu process.
 
         @param gracefully: Whether an attempt will be made to end the VM
-                using monitor command before trying to kill the qemu process
-                or not.
+                using a shell command before trying to end the qemu process
+                with a 'quit' or a kill signal.
         """
         # Is it already dead?
         if self.is_dead():
@@ -551,18 +553,22 @@ class VM:
 
         logging.debug("Destroying VM with PID %d..." % self.process.get_pid())
 
-        if gracefully and self.params.get("cmd_shutdown"):
-            # Try to destroy with SSH command
-            logging.debug("Trying to shutdown VM with SSH command...")
-            (status, output) = self.ssh(self.params.get("cmd_shutdown"))
-            # Was the command sent successfully?
-            if status == 0:
-                logging.debug("Shutdown command sent; waiting for VM to go "
-                              "down...")
-                if kvm_utils.wait_for(self.is_dead, 60, 1, 1):
-                    logging.debug("VM is down")
-                    self.process.close()
-                    return
+        if gracefully and self.params.get("shutdown_command"):
+            # Try to destroy with shell command
+            logging.debug("Trying to shutdown VM with shell command...")
+            session = self.remote_login()
+            if session:
+                try:
+                    # Send the shutdown command
+                    session.sendline(self.params.get("shutdown_command"))
+                    logging.debug("Shutdown command sent; waiting for VM to go "
+                                  "down...")
+                    if kvm_utils.wait_for(self.is_dead, 60, 1, 1):
+                        logging.debug("VM is down")
+                        self.process.close()
+                        return
+                finally:
+                    session.close()
 
         # Try to destroy with a monitor command
         logging.debug("Trying to kill VM with monitor command...")
@@ -680,22 +686,22 @@ class VM:
 
     def is_sshd_running(self, timeout=10):
         """
-        Return True iff the guest's SSH port is responsive.
+        Return True iff the guest's remote shell port is responsive.
 
-        @param timeout: Time (seconds) before giving up checking the SSH daemon
+        @param timeout: Time (seconds) before giving up checking the daemon's
                 responsiveness.
         """
         address = self.get_address()
-        port = self.get_port(int(self.params.get("ssh_port")))
+        port = self.get_port(int(self.params.get("shell_port")))
         if not address or not port:
             logging.debug("IP address or port unavailable")
             return False
         return kvm_utils.is_sshd_running(address, port, timeout=timeout)
 
 
-    def ssh_login(self, nic_index=0, timeout=10):
+    def remote_login(self, nic_index=0, timeout=10):
         """
-        Log into the guest via SSH/Telnet.
+        Log into the guest via SSH/Telnet/Netcat.
         If timeout expires while waiting for output from the guest (e.g. a
         password prompt or a shell prompt) -- fail.
 
@@ -706,85 +712,76 @@ class VM:
         """
         username = self.params.get("username", "")
         password = self.params.get("password", "")
-        prompt = self.params.get("ssh_prompt", "[\#\$]")
-        use_telnet = self.params.get("use_telnet") == "yes"
+        prompt = self.params.get("shell_prompt", "[\#\$]")
+        client = self.params.get("shell_client")
         address = self.get_address(nic_index)
-        port = self.get_port(int(self.params.get("ssh_port")))
+        port = self.get_port(int(self.params.get("shell_port")))
+
         if not address or not port:
             logging.debug("IP address or port unavailable")
             return None
 
-        if use_telnet:
-            session = kvm_utils.telnet(address, port, username, password,
-                                       prompt, timeout)
-        else:
+        if client == "ssh":
             session = kvm_utils.ssh(address, port, username, password,
                                     prompt, timeout)
+        elif client == "telnet":
+            session = kvm_utils.telnet(address, port, username, password,
+                                       prompt, timeout)
+
         if session:
-            session.set_status_test_command(self.params.get("ssh_status_test_"
+            session.set_status_test_command(self.params.get("status_test_"
                                                             "command", ""))
         return session
 
 
-    def scp_to_remote(self, local_path, remote_path, nic_index=0, timeout=300):
+    def copy_files_to(self, local_path, remote_path, nic_index=0, timeout=300):
         """
-        Transfer files to the guest via SCP.
+        Transfer files to the guest.
 
         @param local_path: Host path
         @param remote_path: Guest path
+        @param nic_index: The index of the NIC to connect to.
         @param timeout: Time (seconds) before giving up on doing the remote
                 copy.
         """
         username = self.params.get("username", "")
         password = self.params.get("password", "")
+        client = self.params.get("file_transfer_client")
         address = self.get_address(nic_index)
-        port = self.get_port(int(self.params.get("ssh_port")))
+        port = self.get_port(int(self.params.get("file_transfer_port")))
+
         if not address or not port:
             logging.debug("IP address or port unavailable")
             return None
-        return kvm_utils.scp_to_remote(address, port, username, password,
-                                       local_path, remote_path, timeout)
 
+        if client == "scp":
+            return kvm_utils.scp_to_remote(address, port, username, password,
+                                           local_path, remote_path, timeout)
 
-    def scp_from_remote(self, remote_path, local_path, nic_index=0, timeout=300):
+
+    def copy_files_from(self, remote_path, local_path, nic_index=0, timeout=300):
         """
-        Transfer files from the guest via SCP.
+        Transfer files from the guest.
 
         @param local_path: Guest path
         @param remote_path: Host path
+        @param nic_index: The index of the NIC to connect to.
         @param timeout: Time (seconds) before giving up on doing the remote
                 copy.
         """
         username = self.params.get("username", "")
         password = self.params.get("password", "")
+        client = self.params.get("file_transfer_client")
         address = self.get_address(nic_index)
-        port = self.get_port(int(self.params.get("ssh_port")))
+        port = self.get_port(int(self.params.get("file_transfer_port")))
+
         if not address or not port:
             logging.debug("IP address or port unavailable")
             return None
-        return kvm_utils.scp_from_remote(address, port, username, password,
-                                         remote_path, local_path, timeout)
-
-
-    def ssh(self, command, timeout=10):
-        """
-        Login via SSH/Telnet and send a command.
-
-        @command: Command that will be sent.
-        @timeout: Time before giving up waiting on a status return.
-        @return: A tuple (status, output). status is 0 on success and 1 on
-                failure.
-        """
-        session = self.ssh_login(timeout=timeout)
-        if not session:
-            return (1, "")
-
-        logging.debug("Sending command: %s" % command)
-        session.sendline(command)
-        output = session.read_nonblocking(1.0)
-        session.close()
 
-        return (0, output)
+        if client == "scp":
+            return kvm_utils.scp_from_remote(address, port, username, password,
+                                             remote_path, local_path, timeout)
 
 
     def send_key(self, keystr):
-- 
1.5.4.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [KVM-AUTOTEST PATCH 2/6] KVM test: support Netcat as a remote shell client
  2009-08-09 16:33 ` [KVM-AUTOTEST PATCH 1/6] KVM test: rename SSH related parameters and functions and add new ones Michael Goldish
@ 2009-08-09 16:33   ` Michael Goldish
  2009-08-09 16:33     ` [KVM-AUTOTEST PATCH 3/6] KVM test: add a function that translates user specified paths to real ones Michael Goldish
  0 siblings, 1 reply; 8+ messages in thread
From: Michael Goldish @ 2009-08-09 16:33 UTC (permalink / raw)
  To: autotest, kvm; +Cc: Michael Goldish

This is useful for Windows guests that will use the homemade remote shell server.

Signed-off-by: Michael Goldish <mgoldish@redhat.com>
---
 client/tests/kvm/kvm_utils.py |   17 +++++++++++++++++
 client/tests/kvm/kvm_vm.py    |    3 +++
 2 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index d1c9781..4c4753b 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -562,6 +562,23 @@ def telnet(host, port, username, password, prompt, timeout=10):
     return remote_login(command, password, prompt, "\r\n", timeout)
 
 
+def netcat(host, port, username, password, prompt, timeout=10):
+    """
+    Log into a remote host (guest) using Netcat.
+
+    @param host: Hostname or IP address
+    @param username: Username (if required)
+    @param password: Password (if required)
+    @param prompt: Shell prompt (regular expression)
+    @timeout: Time in seconds that we will wait before giving up on logging
+            into the host.
+
+    @return: kvm_spawn object on success and None on failure.
+    """
+    command = "nc %s %s" % (host, port)
+    return remote_login(command, password, prompt, "\n", timeout)
+
+
 # The following are utility functions related to ports.
 
 def is_sshd_running(host, port, timeout=10.0):
diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 4a862bd..7bc3d75 100644
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -727,6 +727,9 @@ class VM:
         elif client == "telnet":
             session = kvm_utils.telnet(address, port, username, password,
                                        prompt, timeout)
+        elif client == "nc":
+            session = kvm_utils.netcat(address, port, username, password,
+                                       prompt, timeout)
 
         if session:
             session.set_status_test_command(self.params.get("status_test_"
-- 
1.5.4.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [KVM-AUTOTEST PATCH 3/6] KVM test: add a function that translates user specified paths to real ones
  2009-08-09 16:33   ` [KVM-AUTOTEST PATCH 2/6] KVM test: support Netcat as a remote shell client Michael Goldish
@ 2009-08-09 16:33     ` Michael Goldish
  2009-08-09 16:33       ` [KVM-AUTOTEST PATCH 4/6] KVM test: allow for regex matching of keys in the config parser Michael Goldish
  0 siblings, 1 reply; 8+ messages in thread
From: Michael Goldish @ 2009-08-09 16:33 UTC (permalink / raw)
  To: autotest, kvm; +Cc: Michael Goldish

If a user specified path is an absolute one, it is returned as is.
If it's relative, it's appended to a certain base path.

This function is meant to allow framework and test code to treat all user
specified paths equally.

Signed-off-by: Michael Goldish <mgoldish@redhat.com>
---
 client/tests/kvm/kvm_utils.py |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index 4c4753b..5e9e90d 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -677,6 +677,21 @@ def find_free_ports(start_port, end_port, count):
 
 # The following are miscellaneous utility functions.
 
+def get_path(base_path, user_path):
+    """
+    Translate a user specified path to a real path.
+    If user_path is relative, append it to base_path.
+    If user_path is absolute, return it as is.
+
+    @param base_path: The base path of relative user specified paths.
+    @param user_path: The user specified path.
+    """
+    if os.path.isabs(user_path):
+        return user_path
+    else:
+        return os.path.join(base_path, user_path)
+
+
 def generate_random_string(length):
     """
     Return a random string using alphanumeric characters.
-- 
1.5.4.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [KVM-AUTOTEST PATCH 4/6] KVM test: allow for regex matching of keys in the config parser
  2009-08-09 16:33     ` [KVM-AUTOTEST PATCH 3/6] KVM test: add a function that translates user specified paths to real ones Michael Goldish
@ 2009-08-09 16:33       ` Michael Goldish
  2009-08-09 16:33         ` [KVM-AUTOTEST PATCH 5/6] KVM test: treat all user specified paths equally Michael Goldish
  0 siblings, 1 reply; 8+ messages in thread
From: Michael Goldish @ 2009-08-09 16:33 UTC (permalink / raw)
  To: autotest, kvm; +Cc: Michael Goldish

Allow for statements with the following syntax:
regex ?= value         (set)
regex ?+= value        (append)
regex ?<= value        (prepend)

These operations are performed only for keys that match regex.
The whole key name must match the expression, so if regex is a regular string,
only the key whose name equals this string is modified.

This is useful for modifying all parameters of a certain type regardless of the
objects they apply to.  For example, the following parameters specify the cdrom
filenames for different objects: cdrom_vm1, cdrom_vm2, cdrom.  It is now
possible to modify all of them with a statement such
cdrom.* ?<= shared_
which would prepend the string 'shared_' to all cdrom filenames.

Signed-off-by: Michael Goldish <mgoldish@redhat.com>
---
 client/tests/kvm/kvm_config.py |   34 +++++++++++++++++++++++-----------
 1 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/client/tests/kvm/kvm_config.py b/client/tests/kvm/kvm_config.py
index 7ff7a07..b7bddbd 100755
--- a/client/tests/kvm/kvm_config.py
+++ b/client/tests/kvm/kvm_config.py
@@ -316,20 +316,32 @@ class config:
                 for filter in filters:
                     filtered_list = self.filter(filter, filtered_list)
                 # Apply the operation to the filtered list
-                for dict in filtered_list:
-                    if op_found == "=":
+                if op_found == "=":
+                    for dict in filtered_list:
                         dict[key] = value
-                    elif op_found == "+=":
+                elif op_found == "+=":
+                    for dict in filtered_list:
                         dict[key] = dict.get(key, "") + value
-                    elif op_found == "<=":
+                elif op_found == "<=":
+                    for dict in filtered_list:
                         dict[key] = value + dict.get(key, "")
-                    elif op_found.startswith("?") and dict.has_key(key):
-                        if op_found == "?=":
-                            dict[key] = value
-                        elif op_found == "?+=":
-                            dict[key] = dict.get(key, "") + value
-                        elif op_found == "?<=":
-                            dict[key] = value + dict.get(key, "")
+                elif op_found.startswith("?"):
+                    exp = re.compile("^(%s)$" % key)
+                    if op_found == "?=":
+                        for dict in filtered_list:
+                            for key in dict.keys():
+                                if exp.match(key):
+                                    dict[key] = value
+                    elif op_found == "?+=":
+                        for dict in filtered_list:
+                            for key in dict.keys():
+                                if exp.match(key):
+                                    dict[key] = dict.get(key, "") + value
+                    elif op_found == "?<=":
+                        for dict in filtered_list:
+                            for key in dict.keys():
+                                if exp.match(key):
+                                    dict[key] = value + dict.get(key, "")
 
             # Parse 'no' and 'only' statements
             elif words[0] == "no" or words[0] == "only":
-- 
1.5.4.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [KVM-AUTOTEST PATCH 5/6] KVM test: treat all user specified paths equally
  2009-08-09 16:33       ` [KVM-AUTOTEST PATCH 4/6] KVM test: allow for regex matching of keys in the config parser Michael Goldish
@ 2009-08-09 16:33         ` Michael Goldish
  2009-08-09 16:33           ` [KVM-AUTOTEST PATCH 6/6] KVM test: allow the user to specify the paths of the qemu and qemu-img binaries Michael Goldish
  0 siblings, 1 reply; 8+ messages in thread
From: Michael Goldish @ 2009-08-09 16:33 UTC (permalink / raw)
  To: autotest, kvm; +Cc: Michael Goldish

(This patch breaks compatibility with existing config files.)

The user must now specify paths relative to test.bindir whenever a path is
required.  For example, image filenames specified in the config file should now
begin with 'images/', cdrom filenames should begin with 'isos/' and stepfile
filenames should begin with 'steps/'.

This patch modifies kvm_vm.py, kvm_preprocessing.py, kvm_guest_wizard.py,
stepmaker.py and and kvm_tests.cfg.sample.

Signed-off-by: Michael Goldish <mgoldish@redhat.com>
---
 client/tests/kvm/kvm_guest_wizard.py  |    2 +-
 client/tests/kvm/kvm_preprocessing.py |   21 ++-----
 client/tests/kvm/kvm_tests.cfg.sample |    5 ++
 client/tests/kvm/kvm_vm.py            |  106 ++++++++++++---------------------
 client/tests/kvm/stepmaker.py         |    2 +-
 5 files changed, 51 insertions(+), 85 deletions(-)

diff --git a/client/tests/kvm/kvm_guest_wizard.py b/client/tests/kvm/kvm_guest_wizard.py
index 73b830e..732e427 100644
--- a/client/tests/kvm/kvm_guest_wizard.py
+++ b/client/tests/kvm/kvm_guest_wizard.py
@@ -185,7 +185,7 @@ def run_steps(test, params, env):
     steps_filename = params.get("steps")
     if not steps_filename:
         raise error.TestError("Steps filename not specified")
-    steps_filename = os.path.join(test.bindir, "steps", steps_filename)
+    steps_filename = kvm_utils.get_path(test.bindir, steps_filename)
     if not os.path.exists(steps_filename):
         raise error.TestError("Steps file not found: %s" % steps_filename)
 
diff --git a/client/tests/kvm/kvm_preprocessing.py b/client/tests/kvm/kvm_preprocessing.py
index a5a32dc..17a82f4 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -13,8 +13,7 @@ def preprocess_image(test, params):
     @note: Currently this function just creates an image if requested.
     """
     qemu_img_path = os.path.join(test.bindir, "qemu-img")
-    image_dir = os.path.join(test.bindir, "images")
-    image_filename = kvm_vm.get_image_filename(params, image_dir)
+    image_filename = kvm_vm.get_image_filename(params, test.bindir)
 
     create_image = False
 
@@ -27,7 +26,7 @@ def preprocess_image(test, params):
         create_image = True
 
     if create_image:
-        if not kvm_vm.create_image(params, qemu_img_path, image_dir):
+        if not kvm_vm.create_image(params, qemu_img_path, test.bindir):
             message = "Could not create image"
             logging.error(message)
             raise error.TestError(message)
@@ -44,9 +43,6 @@ def preprocess_vm(test, params, env, name):
     @param name: The name of the VM object.
     """
     qemu_path = os.path.join(test.bindir, "qemu")
-    image_dir = os.path.join(test.bindir, "images")
-    iso_dir = os.path.join(test.bindir, "isos")
-    script_dir = test.bindir
 
     logging.debug("Preprocessing VM '%s'..." % name)
     vm = kvm_utils.env_get_vm(env, name)
@@ -54,7 +50,7 @@ def preprocess_vm(test, params, env, name):
         logging.debug("VM object found in environment")
     else:
         logging.debug("VM object does not exist; creating it")
-        vm = kvm_vm.VM(name, params, qemu_path, image_dir, iso_dir, script_dir,
+        vm = kvm_vm.VM(name, params, qemu_path, test.bindir,
                        env.get("address_cache"))
         kvm_utils.env_register_vm(env, name, vm)
 
@@ -75,16 +71,13 @@ def preprocess_vm(test, params, env, name):
             start_vm = True
         elif vm.make_qemu_command() != vm.make_qemu_command(name, params,
                                                             qemu_path,
-                                                            image_dir,
-                                                            iso_dir,
-                                                            script_dir):
+                                                            test.bindir):
             logging.debug("VM's qemu command differs from requested one; "
                           "restarting it...")
             start_vm = True
 
     if start_vm:
-        if not vm.create(name, params, qemu_path, image_dir, iso_dir,
-                         script_dir, for_migration):
+        if not vm.create(name, params, qemu_path, test.bindir, for_migration):
             message = "Could not start VM"
             logging.error(message)
             raise error.TestError(message)
@@ -101,10 +94,8 @@ def postprocess_image(test, params):
     @param test: An Autotest test object.
     @param params: A dict containing image postprocessing parameters.
     """
-    image_dir = os.path.join(test.bindir, "images")
-
     if params.get("remove_image") == "yes":
-        kvm_vm.remove_image(params, image_dir)
+        kvm_vm.remove_image(params, test.bindir)
 
 
 def postprocess_vm(test, params, env, name):
diff --git a/client/tests/kvm/kvm_tests.cfg.sample b/client/tests/kvm/kvm_tests.cfg.sample
index 8238f3e..baebd64 100644
--- a/client/tests/kvm/kvm_tests.cfg.sample
+++ b/client/tests/kvm/kvm_tests.cfg.sample
@@ -634,5 +634,10 @@ variants:
 include kvm_cdkeys.cfg
 
 
+image_name.* ?<= images/
+cdrom.* ?<= isos/
+steps ?<= steps/
+
+
 # Choose your test list
 only fc8_quick
diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 7bc3d75..b2f0345 100644
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -9,12 +9,12 @@ Utility classes and functions to handle Virtual Machine creation using qemu.
 """
 
 
-def get_image_filename(params, image_dir):
+def get_image_filename(params, root_dir):
     """
-    Generate an image path from params and image_dir.
+    Generate an image path from params and root_dir.
 
     @param params: Dictionary containing the test parameters.
-    @param image_dir: The directory where the image is to be located
+    @param root_dir: Base directory for relative filenames.
 
     @note: params should contain:
            image_name -- the name of the image file, without extension
@@ -23,17 +23,17 @@ def get_image_filename(params, image_dir):
     image_name = params.get("image_name", "image")
     image_format = params.get("image_format", "qcow2")
     image_filename = "%s.%s" % (image_name, image_format)
-    image_filename = os.path.join(image_dir, image_filename)
+    image_filename = kvm_utils.get_path(root_dir, image_filename)
     return image_filename
 
 
-def create_image(params, qemu_img_path, image_dir):
+def create_image(params, qemu_img_path, root_dir):
     """
     Create an image using qemu_image.
 
     @param params: Dictionary containing the test parameters.
     @param qemu_img_path: The path of the qemu-img binary
-    @param image_dir: The directory where the image is to be located
+    @param root_dir: Base directory for relative filenames.
 
     @note: params should contain:
            image_name -- the name of the image file, without extension
@@ -47,7 +47,7 @@ def create_image(params, qemu_img_path, image_dir):
     format = params.get("image_format", "qcow2")
     qemu_img_cmd += " -f %s" % format
 
-    image_filename = get_image_filename(params, image_dir)
+    image_filename = get_image_filename(params, root_dir)
     qemu_img_cmd += " %s" % image_filename
 
     size = params.get("image_size", "10G")
@@ -76,18 +76,18 @@ def create_image(params, qemu_img_path, image_dir):
     return image_filename
 
 
-def remove_image(params, image_dir):
+def remove_image(params, root_dir):
     """
     Remove an image file.
 
     @param params: A dict
-    @param image_dir: The directory where the image is to be located
+    @param root_dir: Base directory for relative filenames.
 
     @note: params should contain:
            image_name -- the name of the image file, without extension
            image_format -- the format of the image (qcow2, raw etc)
     """
-    image_filename = get_image_filename(params, image_dir)
+    image_filename = get_image_filename(params, root_dir)
     logging.debug("Removing image file %s..." % image_filename)
     if os.path.exists(image_filename):
         os.unlink(image_filename)
@@ -100,8 +100,7 @@ class VM:
     This class handles all basic VM operations.
     """
 
-    def __init__(self, name, params, qemu_path, image_dir, iso_dir,
-                 script_dir, address_cache):
+    def __init__(self, name, params, qemu_path, root_dir, address_cache):
         """
         Initialize the object and set a few attributes.
 
@@ -109,9 +108,7 @@ class VM:
         @param params: A dict containing VM params
                 (see method make_qemu_command for a full description)
         @param qemu_path: The path of the qemu binary
-        @param image_dir: The directory where images reside
-        @param iso_dir: The directory where ISOs reside
-        @param script_dir: The directory where -net tap scripts reside
+        @param root_dir: Base directory for relative filenames
         @param address_cache: A dict that maps MAC addresses to IP addresses
         """
         self.process = None
@@ -122,9 +119,7 @@ class VM:
         self.name = name
         self.params = params
         self.qemu_path = qemu_path
-        self.image_dir = image_dir
-        self.iso_dir = iso_dir
-        self.script_dir = script_dir
+        self.root_dir = root_dir
         self.address_cache = address_cache
 
         # Find available monitor filename
@@ -138,8 +133,8 @@ class VM:
                 break
 
 
-    def clone(self, name=None, params=None, qemu_path=None, image_dir=None,
-              iso_dir=None, script_dir=None, address_cache=None):
+    def clone(self, name=None, params=None, qemu_path=None, root_dir=None,
+              address_cache=None):
         """
         Return a clone of the VM object with optionally modified parameters.
         The clone is initially not alive and needs to be started using create().
@@ -149,9 +144,7 @@ class VM:
         @param name: Optional new VM name
         @param params: Optional new VM creation parameters
         @param qemu_path: Optional new path to qemu
-        @param image_dir: Optional new image dir
-        @param iso_dir: Optional new iso directory
-        @param script_dir: Optional new -net tap script directory
+        @param root_dir: Optional new base directory for relative filenames
         @param address_cache: A dict that maps MAC addresses to IP addresses
         """
         if name == None:
@@ -160,20 +153,15 @@ class VM:
             params = self.params.copy()
         if qemu_path == None:
             qemu_path = self.qemu_path
-        if image_dir == None:
-            image_dir = self.image_dir
-        if iso_dir == None:
-            iso_dir = self.iso_dir
-        if script_dir == None:
-            script_dir = self.script_dir
+        if root_dir == None:
+            root_dir = self.root_dir
         if address_cache == None:
             address_cache = self.address_cache
-        return VM(name, params, qemu_path, image_dir, iso_dir, script_dir,
-                  address_cache)
+        return VM(name, params, qemu_path, root_dir, address_cache)
 
 
     def make_qemu_command(self, name=None, params=None, qemu_path=None,
-                          image_dir=None, iso_dir=None, script_dir=None):
+                          root_dir=None):
         """
         Generate a qemu command line. All parameters are optional. If a
         parameter is not supplied, the corresponding value stored in the
@@ -182,14 +170,11 @@ class VM:
         @param name: The name of the object
         @param params: A dict containing VM params
         @param qemu_path: The path of the qemu binary
-        @param image_dir: The directory where images reside
-        @param iso_dir: The directory where ISOs reside
-        @param script_dir: The directory where -net tap scripts reside
+        @param root_dir: Base directory for relative filenames
 
         @note: The params dict should contain:
                mem -- memory size in MBs
                cdrom -- ISO filename to use with the qemu -cdrom parameter
-               (iso_dir is pre-pended to the ISO filename)
                extra_params -- a string to append to the qemu command
                shell_port -- port of the remote shell daemon on the guest
                (SSH, Telnet or the home-made Remote Shell Server)
@@ -219,12 +204,8 @@ class VM:
             params = self.params
         if qemu_path == None:
             qemu_path = self.qemu_path
-        if image_dir == None:
-            image_dir = self.image_dir
-        if iso_dir == None:
-            iso_dir = self.iso_dir
-        if script_dir == None:
-            script_dir = self.script_dir
+        if root_dir == None:
+            root_dir = self.root_dir
 
         # Start constructing the qemu command
         qemu_cmd = ""
@@ -241,7 +222,7 @@ class VM:
         for image_name in kvm_utils.get_sub_dict_names(params, "images"):
             image_params = kvm_utils.get_sub_dict(params, image_name)
             qemu_cmd += " -drive file=%s" % get_image_filename(image_params,
-                                                               image_dir)
+                                                               root_dir)
             if image_params.get("drive_format"):
                 qemu_cmd += ",if=%s" % image_params.get("drive_format")
             if image_params.get("drive_cache"):
@@ -269,15 +250,13 @@ class VM:
             if mode == "tap":
                 if nic_params.get("nic_ifname"):
                     qemu_cmd += ",ifname=%s" % nic_params.get("nic_ifname")
-                if nic_params.get("nic_script"):
-                    script_path = nic_params.get("nic_script")
-                    if not os.path.isabs(script_path):
-                        script_path = os.path.join(script_dir, script_path)
+                script_path = nic_params.get("nic_script")
+                if script_path:
+                    script_path = kvm_utils.get_path(root_dir, script_path)
                     qemu_cmd += ",script=%s" % script_path
-                if nic_params.get("nic_downscript"):
-                    script_path = nic_params.get("nic_downscript")
-                    if not os.path.isabs(script_path):
-                        script_path = os.path.join(script_dir, script_path)
+                script_path = nic_params.get("nic_downscript")
+                if script_path:
+                    script_path = kvm_utils.get_path(root_dir, script_path)
                     qemu_cmd += ",downscript=%s" % script_path
             # Proceed to next NIC
             vlan += 1
@@ -288,7 +267,7 @@ class VM:
 
         iso = params.get("cdrom")
         if iso:
-            iso = os.path.join(iso_dir, iso)
+            iso = kvm_utils.get_path(root_dir, iso)
             qemu_cmd += " -cdrom %s" % iso
 
         extra_params = params.get("extra_params")
@@ -316,9 +295,8 @@ class VM:
         return qemu_cmd
 
 
-    def create(self, name=None, params=None, qemu_path=None, image_dir=None,
-               iso_dir=None, script_dir=None, for_migration=False,
-               timeout=5.0):
+    def create(self, name=None, params=None, qemu_path=None, root_dir=None,
+               for_migration=False, timeout=5.0):
         """
         Start the VM by running a qemu command.
         All parameters are optional. The following applies to all parameters
@@ -329,9 +307,7 @@ class VM:
         @param name: The name of the object
         @param params: A dict containing VM params
         @param qemu_path: The path of the qemu binary
-        @param image_dir: The directory where images reside
-        @param iso_dir: The directory where ISOs reside
-        @param script_dir: The directory where -net tap scripts reside
+        @param root_dir: Base directory for relative filenames
         @param for_migration: If True, start the VM with the -incoming
         option
         """
@@ -343,23 +319,17 @@ class VM:
             self.params = params
         if qemu_path != None:
             self.qemu_path = qemu_path
-        if image_dir != None:
-            self.image_dir = image_dir
-        if iso_dir != None:
-            self.iso_dir = iso_dir
-        if script_dir != None:
-            self.script_dir = script_dir
+        if root_dir != None:
+            self.root_dir = root_dir
         name = self.name
         params = self.params
         qemu_path = self.qemu_path
-        image_dir = self.image_dir
-        iso_dir = self.iso_dir
-        script_dir = self.script_dir
+        root_dir = self.root_dir
 
         # Verify the md5sum of the ISO image
         iso = params.get("cdrom")
         if iso:
-            iso = os.path.join(iso_dir, iso)
+            iso = kvm_utils.get_path(root_dir, iso)
             if not os.path.exists(iso):
                 logging.error("ISO file not found: %s" % iso)
                 return False
diff --git a/client/tests/kvm/stepmaker.py b/client/tests/kvm/stepmaker.py
index 8f16ffd..6f1e6a1 100644
--- a/client/tests/kvm/stepmaker.py
+++ b/client/tests/kvm/stepmaker.py
@@ -349,7 +349,7 @@ def run_stepmaker(test, params, env):
     steps_filename = params.get("steps")
     if not steps_filename:
         raise error.TestError("Steps filename not specified")
-    steps_filename = os.path.join(test.bindir, "steps", steps_filename)
+    steps_filename = kvm_utils.get_path(test.bindir, steps_filename)
     if os.path.exists(steps_filename):
         raise error.TestError("Steps file %s already exists" % steps_filename)
 
-- 
1.5.4.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [KVM-AUTOTEST PATCH 6/6] KVM test: allow the user to specify the paths of the qemu and qemu-img binaries
  2009-08-09 16:33         ` [KVM-AUTOTEST PATCH 5/6] KVM test: treat all user specified paths equally Michael Goldish
@ 2009-08-09 16:33           ` Michael Goldish
  0 siblings, 0 replies; 8+ messages in thread
From: Michael Goldish @ 2009-08-09 16:33 UTC (permalink / raw)
  To: autotest, kvm; +Cc: Michael Goldish

Currently, qemu and qemu-img are accessed via symlinks that must be present in
test.bindir (the KVM test dir).

This patch adds new parameters qemu_binary and qemu_img_binary, which specify
the paths of the qemu and qemu-img binaries.
They may be absolute paths or relative to test.bindir (the KVM test dir).
In kvm_tests.cfg.sample they are set to 'qemu' and 'qemu-img', which means the
binaries are expected to be found in test.bindir, which is the current behavior.

Adding these parameters results in slightly cleaner code, but also allows for
some more flexibility in defining tests.  For example, the user can 'variant'
on the parameter qemu_binary, i.e. define several variants of a test set that
differ only in this parameter.  This will make the test set run several times,
each time using a different pre-installed version of qemu.  The parameters also
make it possible to use pre-installed qemu and qemu-img that reside somewhere
outside the Autotest dir, e.g. in /usr/bin.

Signed-off-by: Michael Goldish <mgoldish@redhat.com>
---
 client/tests/kvm/kvm_preprocessing.py |   18 +++++++-----------
 client/tests/kvm/kvm_tests.cfg.sample |    2 ++
 client/tests/kvm/kvm_vm.py            |   33 ++++++++++-----------------------
 3 files changed, 19 insertions(+), 34 deletions(-)

diff --git a/client/tests/kvm/kvm_preprocessing.py b/client/tests/kvm/kvm_preprocessing.py
index 17a82f4..7c16305 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -12,7 +12,6 @@ def preprocess_image(test, params):
     @param params: A dict containing image preprocessing parameters.
     @note: Currently this function just creates an image if requested.
     """
-    qemu_img_path = os.path.join(test.bindir, "qemu-img")
     image_filename = kvm_vm.get_image_filename(params, test.bindir)
 
     create_image = False
@@ -20,13 +19,13 @@ def preprocess_image(test, params):
     if params.get("force_create_image") == "yes":
         logging.debug("'force_create_image' specified; creating image...")
         create_image = True
-    elif params.get("create_image") == "yes" and not \
-    os.path.exists(image_filename):
+    elif (params.get("create_image") == "yes" and not 
+          os.path.exists(image_filename)):
         logging.debug("Creating image...")
         create_image = True
 
     if create_image:
-        if not kvm_vm.create_image(params, qemu_img_path, test.bindir):
+        if not kvm_vm.create_image(params, test.bindir):
             message = "Could not create image"
             logging.error(message)
             raise error.TestError(message)
@@ -42,16 +41,13 @@ def preprocess_vm(test, params, env, name):
     @param env: The environment (a dict-like object).
     @param name: The name of the VM object.
     """
-    qemu_path = os.path.join(test.bindir, "qemu")
-
     logging.debug("Preprocessing VM '%s'..." % name)
     vm = kvm_utils.env_get_vm(env, name)
     if vm:
         logging.debug("VM object found in environment")
     else:
         logging.debug("VM object does not exist; creating it")
-        vm = kvm_vm.VM(name, params, qemu_path, test.bindir,
-                       env.get("address_cache"))
+        vm = kvm_vm.VM(name, params, test.bindir, env.get("address_cache"))
         kvm_utils.env_register_vm(env, name, vm)
 
     start_vm = False
@@ -70,14 +66,13 @@ def preprocess_vm(test, params, env, name):
             logging.debug("VM is not alive; starting it...")
             start_vm = True
         elif vm.make_qemu_command() != vm.make_qemu_command(name, params,
-                                                            qemu_path,
                                                             test.bindir):
             logging.debug("VM's qemu command differs from requested one; "
                           "restarting it...")
             start_vm = True
 
     if start_vm:
-        if not vm.create(name, params, qemu_path, test.bindir, for_migration):
+        if not vm.create(name, params, test.bindir, for_migration):
             message = "Could not start VM"
             logging.error(message)
             raise error.TestError(message)
@@ -247,7 +242,8 @@ def preprocess(test, params, env):
 
     # Get the KVM userspace version and write it as a keyval
     logging.debug("Fetching KVM userspace version...")
-    qemu_path = os.path.join(test.bindir, "qemu")
+    qemu_path = kvm_utils.get_path(test.bindir, params.get("qemu_binary",
+                                                           "qemu"))
     version_line = commands.getoutput("%s -help | head -n 1" % qemu_path)
     exp = re.compile("[Vv]ersion .*?,")
     match = exp.search(version_line)
diff --git a/client/tests/kvm/kvm_tests.cfg.sample b/client/tests/kvm/kvm_tests.cfg.sample
index baebd64..74901a6 100644
--- a/client/tests/kvm/kvm_tests.cfg.sample
+++ b/client/tests/kvm/kvm_tests.cfg.sample
@@ -15,6 +15,8 @@ kill_vm = no
 kill_vm_gracefully = yes
 
 # Some default VM params
+qemu_binary = qemu
+qemu_img_binary = qemu-img
 mem = 512
 image_size = 10G
 shell_port = 22
diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index b2f0345..9016ed3 100644
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -27,12 +27,11 @@ def get_image_filename(params, root_dir):
     return image_filename
 
 
-def create_image(params, qemu_img_path, root_dir):
+def create_image(params, root_dir):
     """
     Create an image using qemu_image.
 
     @param params: Dictionary containing the test parameters.
-    @param qemu_img_path: The path of the qemu-img binary
     @param root_dir: Base directory for relative filenames.
 
     @note: params should contain:
@@ -41,7 +40,8 @@ def create_image(params, qemu_img_path, root_dir):
            image_size -- the requested size of the image (a string
            qemu-img can understand, such as '10G')
     """
-    qemu_img_cmd = qemu_img_path
+    qemu_img_cmd = kvm_utils.get_path(root_dir, params.get("qemu_img_binary",
+                                                           "qemu-img"))
     qemu_img_cmd += " create"
 
     format = params.get("image_format", "qcow2")
@@ -100,14 +100,13 @@ class VM:
     This class handles all basic VM operations.
     """
 
-    def __init__(self, name, params, qemu_path, root_dir, address_cache):
+    def __init__(self, name, params, root_dir, address_cache):
         """
         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)
-        @param qemu_path: The path of the qemu binary
         @param root_dir: Base directory for relative filenames
         @param address_cache: A dict that maps MAC addresses to IP addresses
         """
@@ -118,7 +117,6 @@ class VM:
 
         self.name = name
         self.params = params
-        self.qemu_path = qemu_path
         self.root_dir = root_dir
         self.address_cache = address_cache
 
@@ -133,8 +131,7 @@ class VM:
                 break
 
 
-    def clone(self, name=None, params=None, qemu_path=None, root_dir=None,
-              address_cache=None):
+    def clone(self, name=None, params=None, root_dir=None, address_cache=None):
         """
         Return a clone of the VM object with optionally modified parameters.
         The clone is initially not alive and needs to be started using create().
@@ -143,7 +140,6 @@ class VM:
 
         @param name: Optional new VM name
         @param params: Optional new VM creation parameters
-        @param qemu_path: Optional new path to qemu
         @param root_dir: Optional new base directory for relative filenames
         @param address_cache: A dict that maps MAC addresses to IP addresses
         """
@@ -151,17 +147,14 @@ class VM:
             name = self.name
         if params == None:
             params = self.params.copy()
-        if qemu_path == None:
-            qemu_path = self.qemu_path
         if root_dir == None:
             root_dir = self.root_dir
         if address_cache == None:
             address_cache = self.address_cache
-        return VM(name, params, qemu_path, root_dir, address_cache)
+        return VM(name, params, root_dir, address_cache)
 
 
-    def make_qemu_command(self, name=None, params=None, qemu_path=None,
-                          root_dir=None):
+    def make_qemu_command(self, name=None, params=None, root_dir=None):
         """
         Generate a qemu command line. All parameters are optional. If a
         parameter is not supplied, the corresponding value stored in the
@@ -169,7 +162,6 @@ class VM:
 
         @param name: The name of the object
         @param params: A dict containing VM params
-        @param qemu_path: The path of the qemu binary
         @param root_dir: Base directory for relative filenames
 
         @note: The params dict should contain:
@@ -202,8 +194,6 @@ class VM:
             name = self.name
         if params == None:
             params = self.params
-        if qemu_path == None:
-            qemu_path = self.qemu_path
         if root_dir == None:
             root_dir = self.root_dir
 
@@ -213,7 +203,8 @@ class VM:
         if params.get("x11_display"):
             qemu_cmd += "DISPLAY=%s " % params.get("x11_display")
         # Add the qemu binary
-        qemu_cmd += qemu_path
+        qemu_cmd += kvm_utils.get_path(root_dir, params.get("qemu_binary",
+                                                            "qemu"))
         # Add the VM's name
         qemu_cmd += " -name '%s'" % name
         # Add the monitor socket parameter
@@ -295,7 +286,7 @@ class VM:
         return qemu_cmd
 
 
-    def create(self, name=None, params=None, qemu_path=None, root_dir=None,
+    def create(self, name=None, params=None, root_dir=None,
                for_migration=False, timeout=5.0):
         """
         Start the VM by running a qemu command.
@@ -306,7 +297,6 @@ class VM:
 
         @param name: The name of the object
         @param params: A dict containing VM params
-        @param qemu_path: The path of the qemu binary
         @param root_dir: Base directory for relative filenames
         @param for_migration: If True, start the VM with the -incoming
         option
@@ -317,13 +307,10 @@ class VM:
             self.name = name
         if params != None:
             self.params = params
-        if qemu_path != None:
-            self.qemu_path = qemu_path
         if root_dir != None:
             self.root_dir = root_dir
         name = self.name
         params = self.params
-        qemu_path = self.qemu_path
         root_dir = self.root_dir
 
         # Verify the md5sum of the ISO image
-- 
1.5.4.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Autotest] [KVM-AUTOTEST PATCH 0/6] KVM test: configuration interface changes
  2009-08-09 16:33 [KVM-AUTOTEST PATCH 0/6] KVM test: configuration interface changes Michael Goldish
  2009-08-09 16:33 ` [KVM-AUTOTEST PATCH 1/6] KVM test: rename SSH related parameters and functions and add new ones Michael Goldish
@ 2009-08-17 20:54 ` Lucas Meneghel Rodrigues
  1 sibling, 0 replies; 8+ messages in thread
From: Lucas Meneghel Rodrigues @ 2009-08-17 20:54 UTC (permalink / raw)
  To: Michael Goldish; +Cc: autotest, kvm

Due to the order I've applied some patchsets, I had to rebase the
first patch, then tested the changes. Everything looks good, all
changes on this patchset commited.

http://autotest.kernel.org/changeset/3545
http://autotest.kernel.org/changeset/3546
http://autotest.kernel.org/changeset/3547
http://autotest.kernel.org/changeset/3548
http://autotest.kernel.org/changeset/3549
http://autotest.kernel.org/changeset/3550

Thanks, Michael!

On Sun, Aug 9, 2009 at 1:33 PM, Michael Goldish<mgoldish@redhat.com> wrote:
>
> This patch set modifies the names and functionality of several config
> parameters and adds new ones.
> It also adds support for Netcat as a remote shell client.
>
> It breaks compatibility with existing test configurations.
> _______________________________________________
> Autotest mailing list
> Autotest@test.kernel.org
> http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
>



-- 
Lucas Meneghel

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2009-08-17 20:54 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-09 16:33 [KVM-AUTOTEST PATCH 0/6] KVM test: configuration interface changes Michael Goldish
2009-08-09 16:33 ` [KVM-AUTOTEST PATCH 1/6] KVM test: rename SSH related parameters and functions and add new ones Michael Goldish
2009-08-09 16:33   ` [KVM-AUTOTEST PATCH 2/6] KVM test: support Netcat as a remote shell client Michael Goldish
2009-08-09 16:33     ` [KVM-AUTOTEST PATCH 3/6] KVM test: add a function that translates user specified paths to real ones Michael Goldish
2009-08-09 16:33       ` [KVM-AUTOTEST PATCH 4/6] KVM test: allow for regex matching of keys in the config parser Michael Goldish
2009-08-09 16:33         ` [KVM-AUTOTEST PATCH 5/6] KVM test: treat all user specified paths equally Michael Goldish
2009-08-09 16:33           ` [KVM-AUTOTEST PATCH 6/6] KVM test: allow the user to specify the paths of the qemu and qemu-img binaries Michael Goldish
2009-08-17 20:54 ` [Autotest] [KVM-AUTOTEST PATCH 0/6] KVM test: configuration interface changes Lucas Meneghel Rodrigues

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.