@@ -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
@@ -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)
@@ -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.
@@ -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):
(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(-)