def virtio_serial_login(self, port='vs1'): error_context.context("Try to login guest via '%s'" % port, logging.info) username = self.params.get("username") password = self.params.get("password") prompt = self.params.get("shell_prompt", "[#$]") linesep = eval("'%s'" % self.params.get("shell_linesep", r"\n")) for vport in self.get_virtio_ports(self.vm)[1]: if vport.name == port: break vport = None if not vport: self.test.error("Not virtio serial port '%s' found" % port) logfile = "serial-%s-%s.log" % (vport.name, self.vm.name) socat_cmd = "nc -U %s" % vport.hostfile session = aexpect.ShellSession(socat_cmd, auto_close=False, output_func=utils_misc.log_line, output_params=(logfile, ), prompt=prompt) session.set_linesep(linesep) session.sendline() self.__sessions__.append(session) try: remote.handle_prompts(session, username, password, prompt, 180) self.test.fail("virtio serial '%s' should no " % port + "channel to login") except remote.LoginTimeoutError: self.__sessions__.append(session) logging.info("Can't login via %s" % port) return session
def edit_net_xml(edit_cmd, expect_error, **dargs): """ Edit net xml with virsh net-edit :params edit_cmd: The edit cmd to execute :params expect_error: Boolen, expect success or not :params **dargs: The virsh edit's option """ logging.debug("edit_cmd: %s", edit_cmd) readonly = dargs.get("readonly", False) session = aexpect.ShellSession("sudo -s") try: logging.info("Execute virsh net-edit %s", net_name) virsh_cmd = "virsh net-edit %s" % net_name if readonly: virsh_cmd = "virsh -r net-edit %s" % net_name logging.debug("virsh_cmd: %s", virsh_cmd) session.sendline(virsh_cmd) session.sendline(edit_cmd) session.send('\x1b') session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() except (aexpect.ShellError, aexpect.ExpectError, remote.LoginTimeoutError) as details: log = session.get_output() session.close() if not expect_error: test.fail("Failed to do net-edit: %s\n%s" % (details, log)) logging.debug("Expected error: %s" % log) if readonly and "read only" not in log: test.fail("Not expected error")
def wait_for_login(self, username, password, timeout=240, internal_timeout=10): """ Make multiple attempts to log into the guest via serial console. :param timeout: Time (seconds) to keep trying to log in. :param internal_timeout: Timeout to pass to handle_prompts(). """ end_time = time.time() + timeout while time.time() < end_time: try: self.sendline() remote.handle_prompts(self, username, password, self.prompt, internal_timeout) return except aexpect.ExpectTimeoutError as detail: raise remote.LoginTimeoutError(detail.output) except aexpect.ExpectProcessTerminatedError as detail: raise remote.LoginProcessTerminatedError( detail.status, detail.output) time.sleep(2) # Timeout expired; try one more time but don't catch exceptions self.sendline() remote.handle_prompts(self, username, password, self.prompt, timeout)
def edit_net_xml(edit_cmd, expect_error, **dargs): """ Edit net xml with virsh net-edit :params edit_cmd: The edit cmd to execute :params expect_error: Boolean, expect success or not :params **dargs: The virsh edit's option """ logging.debug("edit_cmd: %s", edit_cmd) readonly = dargs.get("readonly", False) session = aexpect.ShellSession("sudo -s") try: logging.info("Execute virsh net-edit %s", net_name) virsh_cmd = "virsh net-edit %s" % net_name if readonly: virsh_cmd = "virsh -r net-edit %s" % net_name logging.debug("virsh_cmd: %s", virsh_cmd) session.sendline(virsh_cmd) session.sendline(edit_cmd) session.send('\x1b') session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() except (aexpect.ShellError, aexpect.ExpectError, remote.LoginTimeoutError) as details: log = session.get_output() session.close() if not expect_error: test.fail("Failed to do net-edit: %s\n%s" % (details, log)) logging.debug("Expected error: %s" % log) if readonly and "read only" not in log: test.fail("Not expected error")
def virtio_serial_login(self, port='vs1'): error.context("Try to login guest via '%s'" % port, logging.info) username = self.params.get("username") password = self.params.get("password") prompt = self.params.get("shell_prompt", "[\#\$]") linesep = eval("'%s'" % self.params.get("shell_linesep", r"\n")) for vport in self.get_virtio_ports(self.vm)[1]: if vport.name == port: break vport = None if not vport: raise error.TestError("Not virtio serial port '%s' found" % port) logfile = "serial-%s-%s.log" % (vport.name, self.vm.name) socat_cmd = "nc -U %s" % vport.hostfile session = aexpect.ShellSession(socat_cmd, auto_close=False, output_func=utils_misc.log_line, output_params=(logfile,), prompt=prompt) session.set_linesep(linesep) session.sendline() self.__sessions__.append(session) try: remote.handle_prompts(session, username, password, prompt, 180) raise error.TestFail("virtio serial '%s' should no " % port + "channel to login") except remote.LoginTimeoutError: self.__sessions__.append(session) logging.info("Can't login via %s" % port) return session
def edit_image_xml(): edit_cmd = r":%s /<boot dev='hd'\/>/<boot dev='cdrom'\/>" if restore_state == "running": option = "--running" elif restore_state == "paused": option = "--paused" else: raise error.TestFail("Unknown save-image-define option") session = aexpect.ShellSession("sudo -s") try: logging.info("Execute virsh save-image-edit %s %s", vm_save, option) session.sendline("virsh save-image-edit %s %s " % (vm_save, option)) logging.info("Replace '<boot dev='hd'/>' to '<boot dev='cdrom'/>'") session.sendline(edit_cmd) session.send('\x1b') session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() except (aexpect.ShellError, aexpect.ExpectError), details: log = session.get_output() session.close() raise error.TestFail("Failed to do save-image-edit: %s\n%s" % (details, log))
def edit_snap_xml(dom_name, edit_opts, edit_cmd): """ Edit domain snapshot xml :param dom_name: name of domain :param snap_name: name of snapshot :param edit_opts: snapshot-edit options :param edit_cmd: edit command list in interactive mode """ session = aexpect.ShellSession("sudo -s") try: logging.debug("snapshot-edit options is: %s" % edit_opts) logging.debug("edit cmd is: %s" % edit_cmd) session.sendline("virsh snapshot-edit %s %s" % (dom_name, edit_opts)) for i in edit_cmd: session.sendline(i) # Press ESC session.send('\x1b') # Save and quit session.send('ZZ') # use sleep(1) to make sure the modify has been completed. remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() logging.info("Succeed to do snapshot edit") except (aexpect.ShellError, aexpect.ExpectError), details: log = session.get_output() session.close() raise error.TestFail("Failed to do snapshot-edit: %s\n%s" % (details, log))
def conn_setup(self): """ Setup of SSH connection. (1).Initialization of some variables. (2).Check tools. (3).Initialization of id_rsa. (4).set a ssh_agent. (5).copy pub key to server. """ client_session = self.client_session ssh_rsa_pub_path = self.ssh_rsa_pub_path ssh_id_rsa_path = self.ssh_id_rsa_path server_user = self.server_user server_ip = self.server_ip server_pwd = self.server_pwd ssh_keygen = self.SSH_KEYGEN ssh_add = self.SSH_ADD ssh_copy_id = self.SSH_COPY_ID ssh_agent = self.SSH_AGENT shell = self.SHELL tool_dict = {'ssh_keygen': ssh_keygen, 'ssh_add': ssh_add, 'ssh_copy_id': ssh_copy_id, 'ssh_agent': ssh_agent, 'shell': shell} for tool_name in tool_dict: tool = tool_dict[tool_name] if tool is '/bin/true': raise ConnToolNotFoundError(tool_name, "executable not set or found on path,") if os.path.exists("/root/.ssh/id_rsa"): pass else: cmd = "%s -t rsa -f /root/.ssh/id_rsa -N '' " % (ssh_keygen) status, output = client_session.cmd_status_output(cmd) if status: raise ConnCmdClientError(cmd, output) cmd = "%s %s" % (ssh_agent, shell) status, output = client_session.cmd_status_output(cmd) if status: raise ConnCmdClientError(cmd, output) cmd = "%s %s" % (ssh_add, ssh_id_rsa_path) status, output = client_session.cmd_status_output(cmd) if status: raise ConnCmdClientError(cmd, output) cmd = "%s -i %s %s@%s" % (ssh_copy_id, ssh_rsa_pub_path, server_user, server_ip) client_session.sendline(cmd) try: remote.handle_prompts(client_session, server_user, server_pwd, prompt=r"[\#\$]\s*$") except remote.LoginError, detail: raise ConnCmdClientError(cmd, detail)
def run(test, params, env): """ Test steps: 1) Check the environment and get the params from params. 2) while(loop_time < timeout): ttcp command. 3) clean up. """ # Find the ttcp command. try: path.find_command("ttcp") except path.CmdNotFoundError: test.cancel("Not find ttcp command on host.") # Get VM. vms = env.get_all_vms() for vm in vms: session = vm.wait_for_login() status, _ = session.cmd_status_output("which ttcp") if status: test.cancel("Not find ttcp command on guest.") # Get parameters from params. timeout = int(params.get("LB_ttcp_timeout", "300")) ttcp_server_command = params.get("LB_ttcp_server_command", "ttcp -s -r -v -D -p5015") ttcp_client_command = params.get("LB_ttcp_client_command", "ttcp -s -t -v -D -p5015 -b65536 -l65536 -n1000 -f K") host_session = aexpect.ShellSession("sh") try: current_time = int(time.time()) end_time = current_time + timeout # Start the loop from current_time to end_time. while current_time < end_time: for vm in vms: session = vm.wait_for_login() host_session.sendline(ttcp_server_command) cmd = ("%s %s" % (ttcp_client_command, utils_net.get_host_ip_address(params))) def _ttcp_good(): status, output = session.cmd_status_output(cmd) logging.debug(output) if status: return False return True if not utils_misc.wait_for(_ttcp_good, timeout=60): status, output = session.cmd_status_output(cmd) if status: test.fail("Failed to run ttcp command on guest.\n" "Detail: %s." % output) remote.handle_prompts(host_session, None, None, r"[\#\$]\s*$") current_time = int(time.time()) finally: # Clean up. host_session.close() session.close()
def run(test, params, env): """ Test steps: 1) Check the environment and get the params from params. 2) while(loop_time < timeout): ttcp command. 3) clean up. """ # Find the ttcp command. try: os_dep.command("ttcp") except ValueError: raise error.TestNAError("Not find ttcp command on host.") # Get VM. vms = env.get_all_vms() for vm in vms: session = vm.wait_for_login() status, _ = session.cmd_status_output("which ttcp") if status: raise error.TestNAError("Not find ttcp command on guest.") # Get parameters from params. timeout = int(params.get("LB_ttcp_timeout", "600")) ttcp_server_command = params.get("LB_ttcp_server_command", "ttcp -s -r -v -D -p5015") ttcp_client_command = params.get("LB_ttcp_client_command", "ttcp -s -t -v -D -p5015 -b65536 -l65536 -n1000 -f K") host_session = aexpect.ShellSession("sh") try: current_time = int(time.time()) end_time = current_time + timeout # Start the loop from current_time to end_time. while current_time < end_time: for vm in vms: session = vm.wait_for_login() host_session.sendline(ttcp_server_command) cmd = ("%s %s" % (ttcp_client_command, utils_net.get_host_ip_address(params))) def _ttcp_good(): status, output = session.cmd_status_output(cmd) logging.debug(output) if status: return False return True if not utils_misc.wait_for(_ttcp_good, timeout=5): status, output = session.cmd_status_output(cmd) if status: raise error.TestFail("Failed to run ttcp command on guest.\n" "Detail: %s." % output) remote.handle_prompts(host_session, None, None, r"[\#\$]\s*$") current_time = int(time.time()) finally: # Clean up. host_session.close() session.close()
def run(test, params, env): """ Test virsh nwfilter-edit with uuid. 1) Prepare parameters. 2) Run nwfilter-edit command. 3) Check result. 4) Clean env """ # Prepare parameters filter_name = params.get("edit_filter_name", "") status_error = params.get("status_error", "no") new_uuid = "11111111-1111-1111-1111-111111111111" edit_cmd = ":2s/<uuid>.*$/<uuid>%s<\/uuid>/" % new_uuid # Since commit 46a811d, the logic changed for not allow update filter # uuid, so decide status_error with libvirt version. if libvirt_version.version_compare(1, 2, 7): status_error = True else: status_error = False # Backup filter xml new_filter = libvirt_xml.NwfilterXML() filterxml = new_filter.new_from_filter_dumpxml(filter_name) logging.debug("the filter xml is: %s" % filterxml.xmltreefile) try: # Run command session = aexpect.ShellSession("sudo -s") try: session.sendline("virsh nwfilter-edit %s" % filter_name) session.sendline(edit_cmd) # Press ESC session.send('\x1b') # Save and quit session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() if not status_error: logging.info("Succeed to do nwfilter edit") else: test.fail("edit uuid should fail but got succeed.") except (aexpect.ShellError, aexpect.ExpectError, remote.LoginTimeoutError) as details: log = session.get_output() session.close() if "Try again? [y,n,f,?]:" in log and status_error: logging.debug("edit uuid failed as expected.") else: test.fail("Failed to do nwfilter-edit: %s\n%s" % (details, log)) finally: # Clean env virsh.nwfilter_undefine(filter_name, debug=True) virsh.nwfilter_define(filterxml.xml, debug=True)
def _start_remote(self): address, port, username, password, prompt = self._remote_opts cmd = "%s %s" % (self.command, self.options) logging.debug("Run '%s' on host '%s'", cmd, address) login_cmd = ("ssh -o UserKnownHostsFile=/dev/null " "-o StrictHostKeyChecking=no " "-o PreferredAuthentications=password -p %s %s@%s" % (port, username, address)) self._process = aexpect.ShellSession( login_cmd, output_func=self._output_logger_handler) handle_prompts(self._process, username, password, prompt) self._process.sendline(cmd)
def execute_ttcp(vm, params): """ Run ttcp between guest and host. :param vm: guest vm """ remote_ip = params.get("vfio_remote_ip", "REMOTE_IP.EXAMPLE") remote_pwd = params.get("vfio_remote_passwd", "REMOTE_PWD.EXAMPLE") if remote_ip.count("EXAMPLE"): logging.debug("Please provider remote host for ttcp test.") return session1 = vm.wait_for_login() if session1.cmd_status("which ttcp"): session1.close() logging.debug("Did not find ttcp command on guest.SKIP...") return # Check connection first try: session1.cmd("ping -c 4 %s" % remote_ip) except error.CmdError: raise error.TestFail("Couldn't connect to %s through %s" % (remote_ip, vm.name)) # Execute ttcp server on remote host ttcp_server = "ttcp -s -r -v -D -p5015" session1.sendline("ssh %s" % remote_ip) remote.handle_prompts(session1, "root", remote_pwd, r"[\#\$]\s*$", timeout=30, debug=True) logging.debug("Executing ttcp server:%s", ttcp_server) session1.sendline(ttcp_server) # Another session for client session2 = vm.wait_for_login() ttcp_client = ("ttcp -s -t -v -D -p5015 -b65536 -l65536 -n1000 -f K %s" % remote_ip) try: ttcp_s, ttcp_o = session2.cmd_status_output(ttcp_client) logging.debug(ttcp_o) if ttcp_s: raise error.TestFail("Run ttcp between %s and %s failed." % (vm.name, remote_ip)) finally: session1.close() session2.close()
def remote_login(client, host, src, params_login, host_ip): src_name = src if src != "localhost": src_name = src.name logging.info("Login %s from %s" % (host, src)) port = params_login["target_port"] username = params_login["username"] password = params_login["password"] prompt = params_login["shell_prompt"] linesep = eval("'%s'" % params_login.get("shell_linesep", r"\n")) quit_cmd = params.get("quit_cmd", "exit") if host == host_ip: # Try to login from guest to host. prompt = r"^\[.*\][\#\$]\s*$" linesep = "\n" username = params_login["host_username"] password = params_login["host_password"] quit_cmd = "exit" if client == "ssh": # We only support ssh for Linux in this test cmd = ("ssh -o UserKnownHostsFile=/dev/null " "-o StrictHostKeyChecking=no " "-o PreferredAuthentications=password -p %s %s@%s" % (port, username, host)) elif client == "telnet": cmd = "telnet -l %s %s %s" % (username, host, port) else: raise remote.LoginBadClientError(client) if src == "localhost": logging.debug("Login with command %s" % cmd) session = aexpect.ShellSession(cmd, linesep=linesep, prompt=prompt) else: if params_login.get("os_type") == "windows": if client == "telnet": cmd = "C:\\telnet.py %s %s " % (host, username) cmd += "%s \"%s\" && " % (password, prompt) cmd += "C:\\wait_for_quit.py" cmd = "%s || ping 127.0.0.1 -n 5 -w 1000 > nul" % cmd else: cmd += " || sleep 5" session = src.wait_for_login() logging.debug("Sending login command: %s" % cmd) session.sendline(cmd) try: out = remote.handle_prompts(session, username, password, prompt, timeout, debug=True) except Exception as err: session.close() raise err try: session.cmd(quit_cmd) session.close() except Exception: pass return out
def edit_net_xml(): edit_cmd = r":%s /100.254/100.253" session = aexpect.ShellSession("sudo -s") try: logging.info("Execute virsh net-edit %s", net_name) session.sendline("virsh net-edit %s" % net_name) logging.info("Change the ip value of dhcp end") session.sendline(edit_cmd) session.send('\x1b') session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() except (aexpect.ShellError, aexpect.ExpectError) as details: log = session.get_output() session.close() test.fail("Failed to do net-edit: %s\n%s" % (details, log))
def remote_login(client, host, src, params_login, host_ip): src_name = src if src != "localhost": src_name = src.name logging.info("Login %s from %s" % (host, src_name)) port = params_login["target_port"] username = params_login["username"] password = params_login["password"] prompt = params_login["shell_prompt"] linesep = eval("'%s'" % params_login.get("shell_linesep", r"\n")) quit_cmd = params.get("quit_cmd", "exit") if host == host_ip: # Try to login from guest to host. prompt = r"^\[.*\][\#\$]\s*$" linesep = "\n" username = params_login["host_username"] password = params_login["host_password"] quit_cmd = "exit" if client == "ssh": # We only support ssh for Linux in this test cmd = ("ssh -o UserKnownHostsFile=/dev/null " "-o StrictHostKeyChecking=no " "-o PreferredAuthentications=password -p %s %s@%s" % (port, username, host)) elif client == "telnet": cmd = "telnet -l %s %s %s" % (username, host, port) else: raise remote.LoginBadClientError(client) if src == "localhost": logging.debug("Login with command %s" % cmd) session = aexpect.ShellSession(cmd, linesep=linesep, prompt=prompt) else: if params_login.get("os_type") == "windows": if client == "telnet": cmd = "C:\\telnet.py %s %s " % (host, username) cmd += "%s \"%s\" && " % (password, prompt) cmd += "C:\\wait_for_quit.py" cmd = "%s || ping 127.0.0.1 -n 5 -w 1000 > nul" % cmd else: cmd += " || sleep 5" session = src.wait_for_login() logging.debug("Sending login command: %s" % cmd) session.sendline(cmd) try: out = remote.handle_prompts(session, username, password, prompt, timeout, debug=True) except Exception as err: session.close() raise err try: session.cmd(quit_cmd) session.close() except Exception: pass return out
def edit_ifstart_mode(iface_name, old_mode, new_mode, test): """ Set the start mode of a interface. """ edit_cmd = ":%s/mode='{0}'/mode='{1}'".format(old_mode, new_mode) session = aexpect.ShellSession("sudo -s") try: session.sendline("virsh iface-edit %s" % iface_name) logging.info("Change start mode from %s to %s", old_mode, new_mode) session.sendline(edit_cmd) session.send('\x1b') session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() except (aexpect.ShellError, aexpect.ExpectError) as details: log = session.get_output() session.close() test.fail("Failed to do iface-edit: %s\n%s" % (details, log))
def edit_net_xml(): edit_cmd = r":%s /100.254/100.253" session = aexpect.ShellSession("sudo -s") try: logging.info("Execute virsh net-edit %s", net_name) session.sendline("virsh net-edit %s" % net_name) logging.info("Change the ip value of dhcp end") session.sendline(edit_cmd) session.send('\x1b') session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() except (aexpect.ShellError, aexpect.ExpectError), details: log = session.get_output() session.close() raise error.TestFail("Failed to do net-edit: %s\n%s" % (details, log))
def modify_vcpu(source, edit_cmd): """ Modify vm's cpu information. :param source : virsh edit's option. :param dic_mode : a edit commad line . :return: True if edit successed,False if edit failed. """ session = aexpect.ShellSession("sudo -s") try: session.sendline("virsh edit %s" % source) session.sendline(edit_cmd) session.send('\x1b') session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() return True except: return False
def modify_vcpu(source, edit_cmd): """ Modify vm's cpu information. :param source : virsh edit's option. :param dic_mode : a edit commad line . :return: True if edit successed,False if edit failed. """ session = aexpect.ShellSession("sudo -s") try: session.sendline("virsh -c %s edit %s" % (vm.connect_uri, source)) session.sendline(edit_cmd) session.send('\x1b') session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() return True except: return False
def edit_ifstart_mode(iface_name, old_mode, new_mode): """ Set the start mode of a interface. """ edit_cmd = ":%s/mode='{0}'/mode='{1}'".format(old_mode, new_mode) session = aexpect.ShellSession("sudo -s") try: session.sendline("virsh iface-edit %s" % iface_name) logging.info("Change start mode from %s to %s", old_mode, new_mode) session.sendline(edit_cmd) session.send('\x1b') session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() except (aexpect.ShellError, aexpect.ExpectError), details: log = session.get_output() session.close() raise error.TestFail("Failed to do iface-edit: %s\n%s" % (details, log))
def edit_pool(test, pool, edit_cmd): """ Edit libvirt storage pool. :param pool: pool name or uuid. :param edit_cmd : edit command line. """ session = aexpect.ShellSession("sudo -s") try: session.sendline("virsh pool-edit %s" % pool) for cmd in edit_cmd: logging.info("cmd: %s", cmd) session.sendline(cmd) session.send('\x1b') session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() logging.info("Succeed to do pool edit.") except (aexpect.ShellError, aexpect.ExpectError) as details: log = session.get_output() session.close() test.fail("Failed to do pool edit: %s\n%s" % (details, log))
def exec_edit(source, edit_cmd): """ Execute edit command. :param source : virsh edit's option. :param edit_cmd: Edit command list to execute. :return: True if edit successed, False if edit failed. """ session = aexpect.ShellSession("sudo -s") try: session.sendline("virsh -c %s edit %s" % (vm.connect_uri, source)) for cmd in edit_cmd: session.sendline(cmd) session.send('\x1b') session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$", debug=True) session.close() return True except Exception, e: session.close() logging.error("Error occured: %s", e) return False
def edit_pool(pool, edit_cmd): """ Edit libvirt storage pool. :param pool: pool name or uuid. :param edit_cmd : edit commad line. """ session = aexpect.ShellSession("sudo -s") try: session.sendline("virsh pool-edit %s" % pool) for cmd in edit_cmd: session.sendline(cmd) session.send('\x1b') session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() logging.info("Succeed to do pool edit.") except (aexpect.ShellError, aexpect.ExpectError), details: log = session.get_output() session.close() raise error.TestFail("Failed to do pool edit: %s\n%s" % (details, log))
def file_transfer(sessions, addresses, timeout): prepare_cmd = "dd if=/dev/zero of=/tmp/copy_file count=1024 bs=1M" md5_cmd = "md5sum /tmp/copy_file" port = params.get("shell_port") prompt = params.get("shell_prompt") username = params.get("username") password = params.get("password") sessions[0].cmd(prepare_cmd, timeout=timeout) ori_md5 = sessions[0].cmd_output(md5_cmd) scp_cmd = ("scp -v -o UserKnownHostsFile=/dev/null " "-o StrictHostKeyChecking=no " "-o PreferredAuthentications=password -r " "-P %s /tmp/copy_file %s@\[%s\]:/tmp/copy_file" % (port, username, addresses[1])) sessions[0].sendline(scp_cmd) remote.handle_prompts(sessions[0], username, password, prompt, 600) new_md5 = sessions[1].cmd_output(md5_cmd) for session in sessions: session.cmd("rm -f /tmp/copy_file") if new_md5 != ori_md5: raise error.TestFail("Md5 value changed after file transfer, " "original is %s and the new file" " is: %s" % (ori_md5, new_md5))
def edit_filter_xml(test, filter_name, edit_cmd): """ Edit network filter xml :param filter_name: filter name or uuid :param edit_cmd: edit command list in interactive mode """ session = aexpect.ShellSession("sudo -s") try: session.sendline("virsh nwfilter-edit %s" % filter_name) for i in edit_cmd: session.sendline(i) # Press ESC session.send('\x1b') # Save and quit session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() logging.info("Succeed to do nwfilter edit") except (aexpect.ShellError, aexpect.ExpectError) as details: log = session.get_output() session.close() test.fail("Failed to do nwfilter-edit: %s\n%s" % (details, log))
def file_transfer(sessions, addresses, timeout): prepare_cmd = "dd if=/dev/zero of=/tmp/copy_file count=1024 bs=1M" md5_cmd = "md5sum /tmp/copy_file" port = params.get("shell_port") prompt = params.get("shell_prompt") username = params.get("username") password = params.get("password") sessions[0].cmd(prepare_cmd, timeout=timeout) ori_md5 = sessions[0].cmd_output(md5_cmd) scp_cmd = (r"scp -v -o UserKnownHostsFile=/dev/null " r"-o StrictHostKeyChecking=no " r"-o PreferredAuthentications=password -r " r"-P %s /tmp/copy_file %s@\[%s\]:/tmp/copy_file" % (port, username, addresses[1])) sessions[0].sendline(scp_cmd) remote.handle_prompts(sessions[0], username, password, prompt, 600) new_md5 = sessions[1].cmd_output(md5_cmd) for session in sessions: session.cmd("rm -f /tmp/copy_file") if new_md5 != ori_md5: test.fail("Md5 value changed after file transfer, " "original is %s and the new file" " is: %s" % (ori_md5, new_md5))
def run(test, params, env): """ Test interafce xml options. 1.Prepare test environment,destroy or suspend a VM. 2.Edit xml and start the domain. 3.Perform test operation. 4.Recover test environment. 5.Confirm the test result. """ vm_name = params.get("main_vm") vm = env.get_vm(vm_name) virsh_dargs = {'debug': True, 'ignore_status': False} def create_iface_xml(iface_mac): """ Create interface xml file """ iface = Interface(type_name=iface_type) source = ast.literal_eval(iface_source) if source: iface.source = source iface.model = iface_model if iface_model else "virtio" iface.mac_address = iface_mac driver_dict = {} driver_host = {} driver_guest = {} if iface_driver: driver_dict = ast.literal_eval(iface_driver) if iface_driver_host: driver_host = ast.literal_eval(iface_driver_host) if iface_driver_guest: driver_guest = ast.literal_eval(iface_driver_guest) iface.driver = iface.new_driver(driver_attr=driver_dict, driver_host=driver_host, driver_guest=driver_guest) logging.debug("Create new interface xml: %s", iface) return iface def modify_iface_xml(update, status_error=False): """ Modify interface xml options """ vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) xml_devices = vmxml.devices iface_index = xml_devices.index( xml_devices.by_device_tag("interface")[0]) iface = xml_devices[iface_index] if iface_model: iface.model = iface_model else: del iface.model if iface_type: iface.type_name = iface_type del iface.source source = ast.literal_eval(iface_source) if source: net_ifs = utils_net.get_net_if(state="UP") # Check source device is valid or not, # if it's not in host interface list, try to set # source device to first active interface of host if (iface.type_name == "direct" and source.has_key('dev') and source['dev'] not in net_ifs): logging.warn("Source device %s is not a interface" " of host, reset to %s", source['dev'], net_ifs[0]) source['dev'] = net_ifs[0] iface.source = source backend = ast.literal_eval(iface_backend) if backend: iface.backend = backend driver_dict = {} driver_host = {} driver_guest = {} if iface_driver: driver_dict = ast.literal_eval(iface_driver) if iface_driver_host: driver_host = ast.literal_eval(iface_driver_host) if iface_driver_guest: driver_guest = ast.literal_eval(iface_driver_guest) iface.driver = iface.new_driver(driver_attr=driver_dict, driver_host=driver_host, driver_guest=driver_guest) if iface.address: del iface.address logging.debug("New interface xml file: %s", iface) if unprivileged_user: # Create disk image for unprivileged user disk_index = xml_devices.index( xml_devices.by_device_tag("disk")[0]) disk_xml = xml_devices[disk_index] logging.debug("source: %s", disk_xml.source) disk_source = disk_xml.source.attrs["file"] cmd = ("cp -fZ {0} {1} && chown {2}:{2} {1}" "".format(disk_source, dst_disk, unprivileged_user)) utils.run(cmd) disk_xml.source = disk_xml.new_disk_source( attrs={"file": dst_disk}) vmxml.devices = xml_devices # Remove all channels to avoid of permission problem channels = vmxml.get_devices(device_type="channel") for channel in channels: vmxml.del_device(channel) vmxml.xmltreefile.write() logging.debug("New VM xml: %s", vmxml) utils.run("chmod a+rw %s" % vmxml.xml) virsh.define(vmxml.xml, **virsh_dargs) # Try to modify interface xml by update-device or edit xml elif update: iface.xmltreefile.write() ret = virsh.update_device(vm_name, iface.xml, ignore_status=True) libvirt.check_exit_status(ret, status_error) else: vmxml.devices = xml_devices vmxml.xmltreefile.write() vmxml.sync() def check_offloads_option(if_name, driver_options, session=None): """ Check interface offloads by ethtool output """ offloads = {"csum": "tx-checksumming", "gso": "generic-segmentation-offload", "tso4": "tcp-segmentation-offload", "tso6": "tx-tcp6-segmentation", "ecn": "tx-tcp-ecn-segmentation", "ufo": "udp-fragmentation-offload"} if session: ret, output = session.cmd_status_output("ethtool -k %s | head" " -18" % if_name) else: out = utils.run("ethtool -k %s | head -18" % if_name) ret, output = out.exit_status, out.stdout if ret: raise error.TestFail("ethtool return error code") logging.debug("ethtool output: %s", output) for offload in driver_options.keys(): if offloads.has_key(offload): if (output.count(offloads[offload]) and not output.count("%s: %s" % ( offloads[offload], driver_options[offload]))): raise error.TestFail("offloads option %s: %s isn't" " correct in ethtool output" % (offloads[offload], driver_options[offload])) def run_xml_test(iface_mac): """ Test for interface options in vm xml """ # Get the interface object according the mac address vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) iface_devices = vmxml.get_devices(device_type="interface") iface = None for iface_dev in iface_devices: if iface_dev.mac_address == iface_mac: iface = iface_dev if not iface: raise error.TestFail("Can't find interface with mac" " '%s' in vm xml" % iface_mac) driver_dict = {} if iface_driver: driver_dict = ast.literal_eval(iface_driver) for driver_opt in driver_dict.keys(): if not driver_dict[driver_opt] == iface.driver.driver_attr[driver_opt]: raise error.TestFail("Can't see driver option %s=%s in vm xml" % (driver_opt, driver_dict[driver_opt])) if iface_target: if (not iface.target.has_key("dev") or not iface.target["dev"].startswith(iface_target)): raise error.TestFail("Can't see device target dev in vm xml") # Check macvtap mode by ip link command if iface_target == "macvtap" and iface.source.has_key("mode"): cmd = "ip -d link show %s" % iface.target["dev"] output = utils.run(cmd).stdout logging.debug("ip link output: %s", output) mode = iface.source["mode"] if mode == "passthrough": mode = "passthru" if not output.count("macvtap mode %s" % mode): raise error.TestFail("Failed to verify macvtap mode") def run_cmdline_test(iface_mac): """ Test for qemu-kvm command line options """ cmd = ("ps -ef | grep %s | grep -v grep " % vm_name) if test_vhost_net: cmd += " | grep 'vhost=on'" ret = utils.run(cmd) if ret.exit_status: raise error.TestFail("Can't parse qemu-kvm command line") logging.debug("Command line %s", ret.stdout) if iface_model == "virtio": model_option = "device virtio-net-pci" else: model_option = "device rtl8139" iface_cmdline = re.findall(r"%s,(.+),mac=%s" % (model_option, iface_mac), ret.stdout) if not iface_cmdline: raise error.TestFail("Can't see %s with mac %s in command" " line" % (model_option, iface_mac)) cmd_opt = {} for opt in iface_cmdline[0].split(','): tmp = opt.rsplit("=") cmd_opt[tmp[0]] = tmp[1] logging.debug("Command line options %s", cmd_opt) driver_dict = {} # Test <driver> xml options. if iface_driver: iface_driver_dict = ast.literal_eval(iface_driver) for driver_opt in iface_driver_dict.keys(): if driver_opt == "name": continue elif driver_opt == "txmode": if iface_driver_dict["txmode"] == "iothread": driver_dict["tx"] = "bh" else: driver_dict["tx"] = iface_driver_dict["txmode"] elif driver_opt == "queues": driver_dict["mq"] = "on" driver_dict["vectors"] = str(int( iface_driver_dict["queues"]) * 2 + 2) else: driver_dict[driver_opt] = iface_driver_dict[driver_opt] # Test <driver><host/><driver> xml options. if iface_driver_host: driver_dict.update(ast.literal_eval(iface_driver_host)) # Test <driver><guest/><driver> xml options. if iface_driver_guest: driver_dict.update(ast.literal_eval(iface_driver_guest)) for driver_opt in driver_dict.keys(): if (not cmd_opt.has_key(driver_opt) or not cmd_opt[driver_opt] == driver_dict[driver_opt]): raise error.TestFail("Can't see option '%s=%s' in qemu-kvm " " command line" % (driver_opt, driver_dict[driver_opt])) if test_backend: guest_pid = ret.stdout.rsplit()[1] cmd = "lsof %s | grep %s" % (backend["tap"], guest_pid) if utils.system(cmd, ignore_status=True): raise error.TestFail("Guest process didn't open backend file" % backend["tap"]) cmd = "lsof %s | grep %s" % (backend["vhost"], guest_pid) if utils.system(cmd, ignore_status=True): raise error.TestFail("Guest process didn't open backend file" % backend["tap"]) def get_guest_ip(session, mac): """ Wrapper function to get guest ip address """ utils_net.restart_guest_network(session, mac) # Wait for IP address is ready utils_misc.wait_for( lambda: utils_net.get_guest_ip_addr(session, mac), 10) return utils_net.get_guest_ip_addr(session, mac) def check_user_network(session): """ Check user network ip address on guest """ vm_ips = [] vm_ips.append(get_guest_ip(session, iface_mac_old)) if attach_device: vm_ips.append(get_guest_ip(session, iface_mac)) logging.debug("IP address on guest: %s", vm_ips) if len(vm_ips) != len(set(vm_ips)): raise error.TestFail("Duplicated IP address on guest. " "Check bug: https://bugzilla.redhat." "com/show_bug.cgi?id=1147238") for vm_ip in vm_ips: if vm_ip is None or not vm_ip.startswith("10.0.2."): raise error.TestFail("Found wrong IP address" " on guest") # Check gateway address gateway = utils_net.get_net_gateway(session.cmd_output) if gateway != "10.0.2.2": raise error.TestFail("The gateway on guest is not" " right") # Check dns server address ns_list = utils_net.get_net_nameserver(session.cmd_output) if "10.0.2.3" not in ns_list: raise error.TestFail("The dns server can't be found" " on guest") def check_mcast_network(session): """ Check multicast ip address on guests """ src_addr = ast.literal_eval(iface_source)['address'] add_session = additional_vm.wait_for_serial_login() vms_sess_dict = {vm_name: session, additional_vm.name: add_session} # Check mcast address on host cmd = "netstat -g | grep %s" % src_addr if utils.run(cmd, ignore_status=True).exit_status: raise error.TestFail("Can't find multicast ip address" " on host") vms_ip_dict = {} # Get ip address on each guest for vms in vms_sess_dict.keys(): vm_mac = vm_xml.VMXML.get_first_mac_by_name(vms) vm_ip = get_guest_ip(vms_sess_dict[vms], vm_mac) if not vm_ip: raise error.TestFail("Can't get multicast ip" " address on guest") vms_ip_dict.update({vms: vm_ip}) if len(set(vms_ip_dict.values())) != len(vms_sess_dict): raise error.TestFail("Got duplicated multicast ip address") logging.debug("Found ips on guest: %s", vms_ip_dict) # Run omping server on host if not utils_misc.yum_install(["omping"]): raise error.TestError("Failed to install omping" " on host") cmd = ("iptables -F;omping -m %s %s" % (src_addr, "192.168.122.1 %s" % ' '.join(vms_ip_dict.values()))) # Run a backgroup job waiting for connection of client bgjob = utils.AsyncJob(cmd) # Run omping client on guests for vms in vms_sess_dict.keys(): # omping should be installed first if not utils_misc.yum_install(["omping"], vms_sess_dict[vms]): raise error.TestError("Failed to install omping" " on guest") cmd = ("iptables -F; omping -c 5 -T 5 -m %s %s" % (src_addr, "192.168.122.1 %s" % vms_ip_dict[vms])) ret, output = vms_sess_dict[vms].cmd_status_output(cmd) logging.debug("omping ret: %s, output: %s", ret, output) if (not output.count('multicast, xmt/rcv/%loss = 5/5/0%') or not output.count('unicast, xmt/rcv/%loss = 5/5/0%')): raise error.TestFail("omping failed on guest") # Kill the backgroup job bgjob.kill_func() status_error = "yes" == params.get("status_error", "no") start_error = "yes" == params.get("start_error", "no") unprivileged_user = params.get("unprivileged_user") # Interface specific attributes. iface_type = params.get("iface_type", "network") iface_source = params.get("iface_source", "{}") iface_driver = params.get("iface_driver") iface_model = params.get("iface_model") iface_target = params.get("iface_target") iface_backend = params.get("iface_backend", "{}") iface_driver_host = params.get("iface_driver_host") iface_driver_guest = params.get("iface_driver_guest") attach_device = params.get("attach_iface_device") change_option = "yes" == params.get("change_iface_options", "no") update_device = "yes" == params.get("update_iface_device", "no") additional_guest = "yes" == params.get("additional_guest", "no") serial_login = "******" == params.get("serial_login", "no") test_option_cmd = "yes" == params.get( "test_iface_option_cmd", "no") test_option_xml = "yes" == params.get( "test_iface_option_xml", "no") test_vhost_net = "yes" == params.get( "test_vhost_net", "no") test_option_offloads = "yes" == params.get( "test_option_offloads", "no") test_iface_user = "******" == params.get( "test_iface_user", "no") test_iface_mcast = "yes" == params.get( "test_iface_mcast", "no") test_libvirtd = "yes" == params.get("test_libvirtd", "no") test_guest_ip = "yes" == params.get("test_guest_ip", "no") test_backend = "yes" == params.get("test_backend", "no") if iface_driver_host or iface_driver_guest or test_backend: if not libvirt_version.version_compare(1, 2, 8): raise error.TestNAError("Offloading/backend options not " "supported in this libvirt version") if iface_driver and "queues" in ast.literal_eval(iface_driver): if not libvirt_version.version_compare(1, 0, 6): raise error.TestNAError("Queues options not supported" " in this libvirt version") if unprivileged_user: virsh_dargs["unprivileged_user"] = unprivileged_user # Create unprivileged user if needed cmd = ("grep {0} /etc/passwd || " "useradd {0}".format(unprivileged_user)) utils.run(cmd) # Need another disk image for unprivileged user to access dst_disk = "/tmp/%s.img" % unprivileged_user # Destroy VM first if vm.is_alive(): vm.destroy(gracefully=False) # Back up xml file. vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_mac_old = vm_xml.VMXML.get_first_mac_by_name(vm_name) # iface_mac will update if attach a new interface iface_mac = iface_mac_old # Additional vm for test additional_vm = None libvirtd = utils_libvirtd.Libvirtd() try: # Build the xml and run test. try: # Prepare interface backend files if test_backend: if not os.path.exists("/dev/vhost-net"): utils.run("modprobe vhost-net") backend = ast.literal_eval(iface_backend) backend_tap = "/dev/net/tun" backend_vhost = "/dev/vhost-net" if not backend: backend["tap"] = backend_tap backend["vhost"] = backend_vhost if not start_error: # Create backend files for normal test if not os.path.exists(backend["tap"]): os.rename(backend_tap, backend["tap"]) if not os.path.exists(backend["vhost"]): os.rename(backend_vhost, backend["vhost"]) # Edit the interface xml. if change_option: modify_iface_xml(update=False) # Check vhost driver. if test_vhost_net: if os.path.exists("/dev/vhost-net"): cmd = ("modprobe -r {0}; lsmod | " "grep {0}".format("vhost_net")) if not utils.system(cmd, ignore_status=True): raise error.TestError("Can't remove " "vhost_net driver") # Attach a interface when vm is shutoff if attach_device == 'config': iface_mac = utils_net.generate_mac_address_simple() iface_xml_obj = create_iface_xml(iface_mac) iface_xml_obj.xmltreefile.write() ret = virsh.attach_device(vm_name, iface_xml_obj.xml, flagstr="--config", ignore_status=True) libvirt.check_exit_status(ret) # Clone additional vm if additional_guest: guest_name = "%s_%s" % (vm_name, '1') # Clone additional guest timeout = params.get("clone_timeout", 360) utils_libguestfs.virt_clone_cmd(vm_name, guest_name, True, timeout=timeout) additional_vm = vm.clone(guest_name) additional_vm.start() #additional_vm.wait_for_login() # Start the VM. if unprivileged_user: virsh.start(vm_name, **virsh_dargs) cmd = ("su - %s -c 'virsh console %s'" % (unprivileged_user, vm_name)) session = aexpect.ShellSession(cmd) session.sendline() remote.handle_prompts(session, params.get("username"), params.get("password"), "[\#\$]", 30) # Get ip address on guest if not get_guest_ip(session, iface_mac): raise error.TestError("Can't get ip address on guest") else: # Will raise VMStartError exception if start fails vm.start() if serial_login: session = vm.wait_for_serial_login() else: session = vm.wait_for_login() if start_error: raise error.TestFail("VM started unexpectedly") if test_vhost_net: if utils.system("lsmod | grep vhost_net", ignore_status=True): raise error.TestFail("vhost_net module can't be" " loaded automatically") # Attach a interface when vm is running if attach_device == 'live': iface_mac = utils_net.generate_mac_address_simple() iface_xml_obj = create_iface_xml(iface_mac) iface_xml_obj.xmltreefile.write() ret = virsh.attach_device(vm_name, iface_xml_obj.xml, flagstr="--live", ignore_status=True) libvirt.check_exit_status(ret) # Need sleep here for attachment take effect time.sleep(5) # Update a interface options if update_device: modify_iface_xml(update=True, status_error=status_error) # Run tests for qemu-kvm command line options if test_option_cmd: run_cmdline_test(iface_mac) # Run tests for vm xml if test_option_xml: run_xml_test(iface_mac) # Run tests for offloads options if test_option_offloads: if iface_driver_host: ifname_guest = utils_net.get_linux_ifname( session, iface_mac) check_offloads_option( ifname_guest, ast.literal_eval( iface_driver_host), session) if iface_driver_guest: ifname_host = libvirt.get_ifname_host(vm_name, iface_mac) check_offloads_option( ifname_host, ast.literal_eval(iface_driver_guest)) if test_iface_user: # Test user type network check_user_network(session) if test_iface_mcast: # Test mcast type network check_mcast_network(session) # Check guest ip address if test_guest_ip: if not get_guest_ip(session, iface_mac): raise error.TestFail("Guest can't get a" " valid ip address") session.close() # Restart libvirtd and guest, then test again if test_libvirtd: libvirtd.restart() vm.destroy() vm.start() if test_option_xml: run_xml_test(iface_mac) # Detach hot/cold-plugged interface at last if attach_device: ret = virsh.detach_device(vm_name, iface_xml_obj.xml, flagstr="", ignore_status=True) libvirt.check_exit_status(ret) except virt_vm.VMStartError, e: logging.info(str(e)) if start_error: pass else: raise error.TestFail('VM Failed to start for some reason!') finally: # Recover VM. logging.info("Restoring vm...") # Restore interface backend files if test_backend: if not os.path.exists(backend_tap): os.rename(backend["tap"], backend_tap) if not os.path.exists(backend_vhost): os.rename(backend["vhost"], backend_vhost) if unprivileged_user: virsh.remove_domain(vm_name, "--remove-all-storage", **virsh_dargs) if additional_vm: virsh.remove_domain(additional_vm.name, "--remove-all-storage") # Kill all omping server process on host utils.system("pidof omping && killall omping", ignore_status=True) if vm.is_alive(): vm.destroy(gracefully=False) vmxml_backup.sync()
def run(test, params, env): """ Test the command virsh metadata Run in 4 steps: 1. Set domain metadata 2. Get domain metadata 3. Restart libvirtd then get domain metadata again 4. Remove domain metadata then get domain metadata again """ vm_name = params.get("main_vm") vm = env.get_vm(vm_name) metadata_uri = params.get("metadata_uri") metadata_key = params.get("metadata_key") metadata_value = params.get("metadata_value", "") metadata_option = params.get("metadata_option", "") virsh_dargs = {'debug': True, 'ignore_status': True} metadata_set = "yes" == params.get("metadata_set", "no") metadata_get = "yes" == params.get("metadata_get", "yes") metadata_remove = "yes" == params.get("metadata_remove", "no") restart_libvirtd = "yes" == params.get("restart_libvirtd", "no") status_error = "yes" == params.get("status_error", "no") if not metadata_uri: raise error.TestErrorr("'uri' is needed") vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) # Start VM if vm.state() != "running": vm.destroy() vm.start() def pretty_xml(xml_str): return xml.dom.minidom.parseString(xml_str).toprettyxml() def check_result(result, expect_status, expect_output=None): """ Check virsh metadata command """ utlv.check_exit_status(result, expect_status) if result.exit_status == 0 and expect_output: expect_output = pretty_xml(expect_output) logging.debug("Expect metadata: %s", expect_output) output = result.stdout.strip() output = pretty_xml(output) logging.debug("Command get metadata: %s", output) if output != expect_output: raise error.TestFail("Metadat is not expected") def get_metadata(): """ Get domain metadata """ option = metadata_option.replace("--edit", "") result = virsh.metadata(vm_name, metadata_uri, options=option, key=metadata_key, **virsh_dargs) return result try: # Set metadata XML if metadata_set: if not metadata_key: raise error.TestErrorr("'key' is needed") if not metadata_value: raise error.TestErrorr("New metadata is needed") # Parse metadata value if "--edit" in metadata_option: virsh_cmd = r"virsh metadata %s --uri %s --key %s %s" virsh_cmd = virsh_cmd % (vm_name, metadata_uri, metadata_key, metadata_option) session = aexpect.ShellSession("sudo -s") logging.info("Running command: %s", virsh_cmd) try: session.sendline(virsh_cmd) session.sendline(r":insert") session.sendline(metadata_value) session.sendline(".") session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$", debug=True) except Exception, e: logging.error("Error occured: %s", e) session.close() else: result = virsh.metadata(vm_name, metadata_uri, options=metadata_option, key=metadata_key, new_metadata=metadata_value, **virsh_dargs) check_result(result, status_error) if "--config" in metadata_option: vm.destroy() vm.start() check_result(get_metadata(), status_error, metadata_value) # Get metadata if metadata_get: check_result(get_metadata(), status_error, metadata_value) # Restart libvirtd: if restart_libvirtd: libvirtd = Libvirtd() libvirtd.restart() # Get metadata again check_result(get_metadata(), status_error, metadata_value) # Remove metadata if metadata_remove: remove_option = metadata_option.replace("--edit", "") remove_option += " --remove" result = virsh.metadata(vm_name, metadata_uri, options=remove_option, key=metadata_key, **virsh_dargs) check_result(result, status_error) # Get metadata again check_result(get_metadata(), True)
def run(test, params, env): """ Test command: virsh start. 1) Get the params from params. 2) Prepare libvirtd's status. 3) Do the start operation. 4) Result check. 5) clean up. """ # get the params from params vm_name = params.get("main_vm", "virt-tests-vm1") vm_ref = params.get("vm_ref", "vm1") opt = params.get("vs_opt", "") # Backup for recovery. vmxml_backup = libvirt_xml.vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) backup_name = vm_ref vm = None if vm_ref is not "": vm = env.get_vm(vm_ref) vmxml = libvirt_xml.VMXML() libvirtd_state = params.get("libvirtd", "on") pre_operation = params.get("vs_pre_operation", "") status_error = params.get("status_error", "no") # get the params for remote test remote_ip = params.get("remote_ip", "ENTER.YOUR.REMOTE.IP") remote_pwd = params.get("remote_pwd", "ENTER.YOUR.REMOTE.PASSWORD") local_ip = params.get("local_ip", "ENTER.YOUR.LOCAL.IP") if pre_operation == "remote" and (remote_ip.count("ENTER.YOUR.") or local_ip.count("ENTER.YOUR.")): raise error.TestNAError("Remote test parameters not configured") try: # prepare before start vm if libvirtd_state == "on": utils_libvirtd.libvirtd_start() elif libvirtd_state == "off": utils_libvirtd.libvirtd_stop() if pre_operation == "rename": new_vm_name = params.get("vs_new_vm_name", "virsh_start_vm1") vm = libvirt_xml.VMXML.vm_rename(vm, new_vm_name) vm_ref = new_vm_name elif pre_operation == "undefine": vmxml = vmxml.new_from_dumpxml(vm_ref) vmxml.undefine() # do the start operation try: if pre_operation == "remote": # get remote session session = remote.wait_for_login("ssh", remote_ip, "22", "root", remote_pwd, "#") # get uri of local uri = libvirt_vm.complete_uri(local_ip) cmd = "virsh -c %s start %s" % (uri, vm_ref) status, output = session.cmd_status_output(cmd) if status: raise error.TestError(vm_ref, output) elif opt.count("console"): # With --console, start command will print the # dmesg of guest in starting and turn into the # login prompt. In this case, we start it with # --console and login vm in console by # remote.handle_prompts(). cmd = "start %s --console" % vm_ref virsh_session = virsh.VirshSession(virsh_exec=virsh.VIRSH_EXEC, auto_close=True) virsh_session.sendline(cmd) remote.handle_prompts(virsh_session, params.get("username", ""), params.get("password", ""), r"[\#\$]\s*$", timeout=60, debug=True) elif opt.count("autodestroy"): # With --autodestroy, vm will be destroyed when # virsh session closed. Then we execute start # command in a virsh session and start vm with # --autodestroy. Then we closed the virsh session, # and check the vm is destroyed or not. virsh_session = virsh.VirshSession(virsh_exec=virsh.VIRSH_EXEC, auto_close=True) cmd = "start %s --autodestroy" % vm_ref status = virsh_session.cmd_status(cmd) if status: raise error.TestFail("Failed to start vm with --autodestroy.") # Close the session, then the vm shoud be destroyed. virsh_session.close() elif opt.count("force-boot"): # With --force-boot, VM will be stared from boot # even we have saved it with virsh managedsave. # In this case, we start vm and execute sleep 1000&, # then save it with virsh managedsave. At last, we # start vm with --force-boot. To verify the result, # we check the sleep process. If the process exists, # force-boot failed, else case pass. vm.start() session = vm.wait_for_login() status = session.cmd_status("sleep 1000&") if status: raise error.TestError("Can not execute command in guest.") sleep_pid = session.cmd_output("echo $!").strip() virsh.managedsave(vm_ref) virsh.start(vm_ref, options=opt) else: cmd_result = virsh.start(vm_ref, options=opt) if cmd_result.exit_status: if status_error == "no": raise error.TestFail("Start vm failed.\n Detail: %s" % cmd_result) else: # start vm successfully if status_error == "yes": raise error.TestFail("Run successfully with wrong " "command!\n Detail:%s" % cmd_result) if opt.count("paused"): if not (vm.state() == "paused"): raise error.TestFail("VM is not paused when started with " "--paused.") elif opt.count("autodestroy"): if vm.is_alive(): raise error.TestFail("VM was started with --autodestroy," "but not destroyed when virsh session " "closed.") elif opt.count("force-boot"): session = vm.wait_for_login() status = session.cmd_status("ps %s |grep '[s]leep 1000'" % sleep_pid) if not status: raise error.TestFail("VM was started with --force-boot," "but it is restored from a" " managedsave.") else: if status_error == "no" and not vm.is_alive(): raise error.TestFail("VM was started but it is not alive.") except remote.LoginError, detail: raise error.TestFail("Failed to login guest.") finally: # clean up if libvirtd_state == "off": utils_libvirtd.libvirtd_start() elif pre_operation == "rename": libvirt_xml.VMXML.vm_rename(vm, backup_name) if vm and vm.is_paused(): vm.resume() # Restore VM vmxml_backup.sync()
def run(test, params, env): """ Test command: virsh start. 1) Get the params from params. 2) Prepare libvirtd's status. 3) Do the start operation. 4) Result check. 5) clean up. """ # get the params from params vm_name = params.get("main_vm", "avocado-vt-vm1") vm_ref = params.get("vm_ref", "vm1") opt = params.get("vs_opt", "") # Backup for recovery. vmxml_backup = libvirt_xml.vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) backup_name = vm_ref vm = None if vm_ref is not "": vm = env.get_vm(vm_ref) vmxml = libvirt_xml.VMXML() libvirtd_state = params.get("libvirtd", "on") pre_operation = params.get("vs_pre_operation", "") status_error = params.get("status_error", "no") try: # prepare before start vm if libvirtd_state == "on": utils_libvirtd.libvirtd_start() elif libvirtd_state == "off": utils_libvirtd.libvirtd_stop() if pre_operation == "rename": new_vm_name = params.get("vs_new_vm_name", "virsh_start_vm1") vm = libvirt_xml.VMXML.vm_rename(vm, new_vm_name) vm_ref = new_vm_name elif pre_operation == "undefine": vmxml = vmxml.new_from_dumpxml(vm_ref) vmxml.undefine() # do the start operation try: if pre_operation == "remote": # get the params for remote test remote_ip = params.get("remote_ip", "ENTER.YOUR.REMOTE.IP") remote_user = params.get("remote_user", "root") remote_pwd = params.get("remote_pwd", "ENTER.YOUR.REMOTE.PASSWORD") if pre_operation == "remote" and remote_ip.count( "ENTER.YOUR."): test.cancel("Remote test parameters not configured") ssh_key.setup_ssh_key(remote_ip, remote_user, remote_pwd) remote_uri = "qemu+ssh://%s/system" % remote_ip cmd_result = virsh.start(vm_ref, ignore_status=True, debug=True, uri=remote_uri) if cmd_result.exit_status: test.fail("Start vm failed.\n Detail: %s" % cmd_result) elif opt.count("console"): # With --console, start command will print the # dmesg of guest in starting and turn into the # login prompt. In this case, we start it with # --console and login vm in console by # remote.handle_prompts(). cmd = "start %s --console" % vm_ref virsh_session = virsh.VirshSession(virsh_exec=virsh.VIRSH_EXEC, auto_close=True) virsh_session.sendline(cmd) remote.handle_prompts(virsh_session, params.get("username", ""), params.get("password", ""), r"[\#\$]\s*$", timeout=60, debug=True) elif opt.count("autodestroy"): # With --autodestroy, vm will be destroyed when # virsh session closed. Then we execute start # command in a virsh session and start vm with # --autodestroy. Then we closed the virsh session, # and check the vm is destroyed or not. virsh_session = virsh.VirshSession(virsh_exec=virsh.VIRSH_EXEC, auto_close=True) cmd = "start %s --autodestroy" % vm_ref status = virsh_session.cmd_status(cmd) if status: test.fail("Failed to start vm with --autodestroy.") # Close the session, then the vm shoud be destroyed. virsh_session.close() elif opt.count("force-boot"): # With --force-boot, VM will be stared from boot # even we have saved it with virsh managedsave. # In this case, we start vm and execute sleep 1000&, # then save it with virsh managedsave. At last, we # start vm with --force-boot. To verify the result, # we check the sleep process. If the process exists, # force-boot failed, else case pass. vm.start() session = vm.wait_for_login() status = session.cmd_status("sleep 1000&") if status: test.error("Can not execute command in guest.") sleep_pid = session.cmd_output("echo $!").strip() virsh.managedsave(vm_ref) virsh.start(vm_ref, options=opt) else: cmd_result = virsh.start(vm_ref, options=opt) if cmd_result.exit_status: if status_error == "no": test.fail("Start vm failed.\n Detail: %s" % cmd_result) else: # start vm successfully if status_error == "yes": test.fail("Run successfully with wrong " "command!\n Detail:%s" % cmd_result) if opt.count("paused"): if not (vm.state() == "paused"): test.fail("VM is not paused when started with " "--paused.") elif opt.count("autodestroy"): if vm.is_alive(): test.fail("VM was started with --autodestroy," "but not destroyed when virsh session " "closed.") elif opt.count("force-boot"): session = vm.wait_for_login() status = session.cmd_status("ps %s |grep '[s]leep 1000'" % sleep_pid) if not status: test.fail("VM was started with --force-boot," "but it is restored from a" " managedsave.") else: if status_error == "no" and not vm.is_alive( ) and pre_operation != "remote": test.fail("VM was started but it is not alive.") except remote.LoginError as detail: test.fail("Failed to login guest.") finally: # clean up if libvirtd_state == "off": utils_libvirtd.libvirtd_start() elif pre_operation == "rename": libvirt_xml.VMXML.vm_rename(vm, backup_name) elif pre_operation == "remote": virsh.destroy(vm_ref, ignore_status=False, debug=True, uri=remote_uri) if vm and vm.is_paused(): vm.resume() # Restore VM vmxml_backup.sync()
def trigger_events(dom, events_list=[]): """ Trigger various events in events_list :param dom: the vm objects corresponding to the domain :return: the expected output that virsh event command prints out """ expected_events_list = [] save_path = os.path.join(tmpdir, "%s_event.save" % dom.name) print(dom.name) xmlfile = dom.backup_xml() try: for event in events_list: logging.debug("Current event is: %s", event) if event in ['start', 'restore', 'create', 'edit', 'define', 'undefine', 'crash']: if dom.is_alive(): dom.destroy() if event in ['create', 'define']: dom.undefine() else: if not dom.is_alive(): dom.start() dom.wait_for_login().close() if event == "resume": dom.pause() if event == "undefine": virsh.undefine(dom.name, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Undefined Removed") elif event == "create": virsh.create(xmlfile, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Resumed Unpaused") expected_events_list.append("'lifecycle' for %s:" " Started Booted") elif event == "destroy": virsh.destroy(dom.name, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Stopped Destroyed") elif event == "define": virsh.define(xmlfile, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Defined Added") elif event == "start": virsh.start(dom.name, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Resumed Unpaused") expected_events_list.append("'lifecycle' for %s:" " Started Booted") dom.wait_for_login().close() elif event == "suspend": virsh.suspend(dom.name, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Suspended Paused") if not libvirt_version.version_compare(5, 3, 0): expected_events_list.append("'lifecycle' for %s:" " Suspended Paused") elif event == "resume": virsh.resume(dom.name, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Resumed Unpaused") elif event == "save": virsh.save(dom.name, save_path, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Suspended Paused") expected_events_list.append("'lifecycle' for %s:" " Stopped Saved") elif event == "restore": if not os.path.exists(save_path): logging.error("%s not exist", save_path) else: virsh.restore(save_path, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Started Restored") expected_events_list.append("'lifecycle' for %s:" " Resumed Snapshot") elif event == "edit": #Check whether 'description' element exists. domxml = virsh.dumpxml(dom.name).stdout.strip() find_desc = parseString(domxml).getElementsByTagName("description") if find_desc == []: #If not exists, add one for it. logging.info("Adding <description> to guest") virsh.desc(dom.name, "--config", "Added desc for testvm", **virsh_dargs) #The edit operation is to delete 'description' element. edit_cmd = [r":g/<description.*<\/description>/d"] utlv.exec_virsh_edit(dom.name, edit_cmd) expected_events_list.append("'lifecycle' for %s:" " Defined Updated") elif event == "shutdown": if signal_name is None: virsh.shutdown(dom.name, **virsh_dargs) # Wait a few seconds for shutdown finish time.sleep(3) if utils_misc.compare_qemu_version(2, 9, 0): #Shutdown reason distinguished from qemu_2.9.0-9 expected_events_list.append("'lifecycle' for %s:" " Shutdown Finished after guest request") else: os.kill(dom.get_pid(), getattr(signal, signal_name)) if utils_misc.compare_qemu_version(2, 9, 0): expected_events_list.append("'lifecycle' for %s:" " Shutdown Finished after host request") if not utils_misc.compare_qemu_version(2, 9, 0): expected_events_list.append("'lifecycle' for %s:" " Shutdown Finished") wait_for_shutoff(dom) expected_events_list.append("'lifecycle' for %s:" " Stopped Shutdown") elif event == "crash": if not vmxml.xmltreefile.find('devices').findall('panic'): # Set panic device panic_dev = Panic() panic_dev.model = panic_model panic_dev.addr_type = addr_type panic_dev.addr_iobase = addr_iobase vmxml.add_device(panic_dev) vmxml.on_crash = "coredump-restart" vmxml.sync() logging.info("Guest xml now is: %s", vmxml) dom.start() session = dom.wait_for_login() # Stop kdump in the guest session.cmd("systemctl stop kdump", ignore_all_errors=True) # Enable sysRq session.cmd("echo 1 > /proc/sys/kernel/sysrq") try: # Crash the guest session.cmd("echo c > /proc/sysrq-trigger", timeout=60) except (ShellTimeoutError, ShellProcessTerminatedError) as details: logging.info(details) session.close() expected_events_list.append("'lifecycle' for %s:" " Crashed Panicked") expected_events_list.append("'lifecycle' for %s:" " Resumed Unpaused") elif event == "reset": virsh.reset(dom.name, **virsh_dargs) expected_events_list.append("'reboot' for %s") elif event == "vcpupin": virsh.vcpupin(dom.name, '0', '0', **virsh_dargs) expected_events_list.append("'tunable' for %s:" "\n\tcputune.vcpupin0: 0") elif event == "emulatorpin": virsh.emulatorpin(dom.name, '0', **virsh_dargs) expected_events_list.append("'tunable' for %s:" "\n\tcputune.emulatorpin: 0") elif event == "setmem": mem_size = int(params.get("mem_size", 512000)) virsh.setmem(dom.name, mem_size, **virsh_dargs) expected_events_list.append("'balloon-change' for %s:") elif event == "device-added-removed": add_disk(dom.name, new_disk, 'vdb', '') expected_events_list.append("'device-added' for %s:" " virtio-disk1") virsh.detach_disk(dom.name, 'vdb', **virsh_dargs) expected_events_list.append("'device-removed' for %s:" " virtio-disk1") iface_xml_obj = create_iface_xml() iface_xml_obj.xmltreefile.write() virsh.detach_device(dom.name, iface_xml_obj.xml, **virsh_dargs) expected_events_list.append("'device-removed' for %s:" " net0") time.sleep(2) virsh.attach_device(dom.name, iface_xml_obj.xml, **virsh_dargs) expected_events_list.append("'device-added' for %s:" " net0") elif event == "block-threshold": add_disk(dom.name, new_disk, 'vdb', '', format=disk_format) logging.debug(process.run('qemu-img info %s -U' % new_disk)) virsh.domblkthreshold(vm_name, 'vdb', '100M') session = dom.wait_for_login() session.cmd("mkfs.ext4 /dev/vdb && mount /dev/vdb /mnt && ls /mnt && " "dd if=/dev/urandom of=/mnt/bigfile bs=1M count=300 && sync") time.sleep(5) session.close() expected_events_list.append("'block-threshold' for %s:" " dev: vdb(%s) 104857600 29368320") virsh.detach_disk(dom.name, 'vdb', **virsh_dargs) elif event == "change-media": target_device = "hdc" device_target_bus = params.get("device_target_bus", "ide") disk_blk = vm_xml.VMXML.get_disk_blk(dom.name) logging.info("disk_blk %s", disk_blk) if target_device not in disk_blk: logging.info("Adding cdrom to guest") if dom.is_alive(): dom.destroy() add_disk(dom.name, "''", target_device, ("--type cdrom --sourcetype file --driver qemu " + "--config --targetbus %s" % device_target_bus)) dom.start() all_options = new_disk + " --insert" virsh.change_media(dom.name, target_device, all_options, **virsh_dargs) expected_events_list.append("'tray-change' for %s disk" + " .*%s.*:" % device_target_bus + " opened") expected_events_list.append("'tray-change' for %s disk" + " .*%s.*:" % device_target_bus + " closed") all_options = new_disk + " --eject" virsh.change_media(dom.name, target_device, all_options, **virsh_dargs) expected_events_list.append("'tray-change' for %s disk" + " .*%s.*:" % device_target_bus + " opened") elif event == "hwclock": session = dom.wait_for_login() try: session.cmd("hwclock --systohc", timeout=60) except (ShellTimeoutError, ShellProcessTerminatedError) as details: logging.info(details) session.close() expected_events_list.append("'rtc-change' for %s:") elif event == "metadata_set": metadata_uri = params.get("metadata_uri") metadata_key = params.get("metadata_key") metadata_value = params.get("metadata_value") virsh.metadata(dom.name, metadata_uri, options="", key=metadata_key, new_metadata=metadata_value, **virsh_dargs) expected_events_list.append("'metadata-change' for %s: " "element http://app.org/") elif event == "metadata_edit": metadata_uri = "http://herp.derp/" metadata_key = "herp" metadata_value = "<derp xmlns:foobar='http://foo.bar/'>foo<bar></bar></derp>" virsh_cmd = r"virsh metadata %s --uri %s --key %s %s" virsh_cmd = virsh_cmd % (dom.name, metadata_uri, metadata_key, "--edit") session = aexpect.ShellSession("sudo -s") logging.info("Running command: %s", virsh_cmd) try: session.sendline(virsh_cmd) session.sendline(r":insert") session.sendline(metadata_value) session.sendline(".") session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$", debug=True, timeout=60) except Exception as e: test.error("Error occured: %s" % e) session.close() # Check metadata after edit virsh.metadata(dom.name, metadata_uri, options="", key=metadata_key, **virsh_dargs) expected_events_list.append("'metadata-change' for %s: " "element http://app.org/") elif event == "metadata_remove": virsh.metadata(dom.name, metadata_uri, options="--remove", key=metadata_key, **virsh_dargs) expected_events_list.append("'metadata-change' for %s: " "element http://app.org/") else: test.error("Unsupported event: %s" % event) # Event may not received immediately time.sleep(3) finally: if os.path.exists(save_path): os.unlink(save_path) if os.path.exists(new_disk): os.unlink(new_disk) return [(dom.name, event) for event in expected_events_list]
def run(test, params, env): """ Test interface with unprivileged user """ def create_bridge(br_name, iface_name): """ Create bridge attached to physical interface """ # Make sure the bridge not exist if libvirt.check_iface(br_name, "exists", "--all"): test.cancel("The bridge %s already exist" % br_name) # Create bridge utils_package.package_install('tmux') cmd = 'tmux -c "ip link add name {0} type bridge; ip link set {1} up;' \ ' ip link set {1} master {0}; ip link set {0} up; pkill dhclient; ' \ 'sleep 6; dhclient {0}; ifconfig {1} 0"'.format(br_name, iface_name) process.run(cmd, shell=True, verbose=True) def check_ping(dest_ip, ping_count, timeout, src_ip=None, session=None, expect_success=True): """ Check if ping result meets expectation """ status, output = utils_net.ping(dest=dest_ip, count=ping_count, interface=src_ip, timeout=timeout, session=session, force_ipv4=True) success = True if status == 0 else False if success != expect_success: test.fail('Ping result not met expectation, ' 'actual result is {}'.format(success)) if not libvirt_version.version_compare(5, 6, 0): test.cancel('Libvirt version is too low for this test.') vm_name = params.get('main_vm') rand_id = '_' + utils_misc.generate_random_string(3) upu_vm_name = 'upu_vm' + rand_id user_vm_name = params.get('user_vm_name', 'non_root_vm') bridge_name = params.get('bridge_name', 'test_br0') + rand_id device_type = params.get('device_type', '') iface_name = utils_net.get_net_if(state="UP")[0] tap_name = params.get('tap_name', 'mytap0') + rand_id macvtap_name = params.get('macvtap_name', 'mymacvtap0') + rand_id remote_ip = params.get('remote_ip') up_user = params.get('up_user', 'test_upu') + rand_id case = params.get('case', '') # Create unprivileged user logging.info('Create unprivileged user %s', up_user) process.run('useradd %s' % up_user, shell=True, verbose=True) root_vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) upu_args = { 'unprivileged_user': up_user, 'ignore_status': False, 'debug': True, } try: # Create vm as unprivileged user logging.info('Create vm as unprivileged user') upu_vmxml = root_vmxml.copy() # Prepare vm for unprivileged user xml_devices = upu_vmxml.devices disks = xml_devices.by_device_tag("disk") for disk in disks: ori_path = disk.source['attrs'].get('file') if not ori_path: continue file_name = ori_path.split('/')[-1] new_disk_path = '/home/{}/{}'.format(up_user, file_name) logging.debug('New disk path:{}'.format(new_disk_path)) # Copy disk image file and chown to make sure that # unprivileged user has access shutil.copyfile(ori_path, new_disk_path) shutil.chown(new_disk_path, up_user, up_user) # Modify xml to set new path of disk disk_index = xml_devices.index(disk) source = xml_devices[disk_index].source new_attrs = source.attrs new_attrs['file'] = new_disk_path source.attrs = new_attrs xml_devices[disk_index].source = source logging.debug(xml_devices[disk_index].source) upu_vmxml.devices = xml_devices new_xml_path = '/home/{}/upu.xml'.format(up_user) shutil.copyfile(upu_vmxml.xml, new_xml_path) # Define vm for unprivileged user virsh.define(new_xml_path, **upu_args) virsh.domrename(vm_name, upu_vm_name, **upu_args) logging.debug(virsh.dumpxml(upu_vm_name, **upu_args)) upu_vmxml = vm_xml.VMXML() upu_vmxml.xml = virsh.dumpxml(upu_vm_name, **upu_args).stdout_text if case == 'precreated': if device_type == 'tap': # Create bridge create_bridge(bridge_name, iface_name) # Create tap device tap_cmd = 'ip tuntap add mode tap user {user} group {user} ' \ 'name {tap};ip link set {tap} up;ip link set {tap} ' \ 'master {br}'.format(tap=tap_name, user=up_user, br=bridge_name) # Execute command as root process.run(tap_cmd, shell=True, verbose=True) if device_type == 'macvtap': # Create macvtap device mac_addr = utils_net.generate_mac_address_simple() macvtap_cmd = 'ip link add link {iface} name {macvtap} address' \ ' {mac} type macvtap mode bridge;' \ 'ip link set {macvtap} up'.format( iface=iface_name, macvtap=macvtap_name, mac=mac_addr) process.run(macvtap_cmd, shell=True, verbose=True) cmd_get_tap = 'ip link show {} | head -1 | cut -d: -f1'.format(macvtap_name) tap_index = process.run(cmd_get_tap, shell=True, verbose=True).stdout_text.strip() device_path = '/dev/tap{}'.format(tap_index) logging.debug('device_path: {}'.format(device_path)) # Change owner and group for device process.run('chown {user} {path};chgrp {user} {path}'.format( user=up_user, path=device_path), shell=True, verbose=True) # Check if device owner is changed to unprivileged user process.run('ls -l %s' % device_path, shell=True, verbose=True) # Modify interface all_devices = upu_vmxml.devices iface_list = all_devices.by_device_tag('interface') if not iface_list: test.error('No iface to modify') iface = iface_list[0] # Remove other interfaces for ifc in iface_list[1:]: all_devices.remove(ifc) if device_type == 'tap': dev_name = tap_name elif device_type == 'macvtap': dev_name = macvtap_name else: test.error('Invalid device type: {}'.format(device_type)) if_index = all_devices.index(iface) iface = all_devices[if_index] iface.type_name = 'ethernet' iface.target = { 'dev': dev_name, 'managed': 'no' } if device_type == 'macvtap': iface.mac_address = mac_addr logging.debug(iface) upu_vmxml.devices = all_devices logging.debug(upu_vmxml) # Define updated xml shutil.copyfile(upu_vmxml.xml, new_xml_path) upu_vmxml.xml = new_xml_path virsh.define(new_xml_path, **upu_args) # Switch to unprivileged user and modify vm's interface # Start vm as unprivileged user and test network virsh.start(upu_vm_name, debug=True, ignore_status=False, unprivileged_user=up_user) cmd = ("su - %s -c 'virsh console %s'" % (up_user, upu_vm_name)) session = aexpect.ShellSession(cmd) session.sendline() remote.handle_prompts(session, params.get("username"), params.get("password"), r"[\#\$]\s*$", 60) logging.debug(session.cmd_output('ifconfig')) check_ping(remote_ip, 5, 10, session=session) session.close() finally: if 'upu_virsh' in locals(): virsh.destroy(upu_vm_name, unprivileged_user=up_user) virsh.undefine(upu_vm_name, unprivileged_user=up_user) if case == 'precreated': try: if device_type == 'tap': process.run('ip tuntap del mode tap {}'.format(tap_name), shell=True, verbose=True) elif device_type == 'macvtap': process.run('ip l del {}'.format(macvtap_name), shell=True, verbose=True) except Exception: pass finally: cmd = 'tmux -c "ip link set {1} nomaster; ip link delete {0};' \ 'pkill dhclient; sleep 6; dhclient {1}"'.format(bridge_name, iface_name) process.run(cmd, shell=True, verbose=True, ignore_status=True) process.run('pkill -u {0};userdel -f -r {0}'.format(up_user), shell=True, verbose=True, ignore_status=True)
def conn_setup(self): """ Setup of SSH connection. (1).Initialization of some variables. (2).Check tools. (3).Initialization of id_rsa. (4).set a ssh_agent. (5).copy pub key to server. """ client_session = self.client_session ssh_rsa_pub_path = self.ssh_rsa_pub_path ssh_id_rsa_path = self.ssh_id_rsa_path server_user = self.server_user server_ip = self.server_ip server_pwd = self.server_pwd ssh_keygen = self.SSH_KEYGEN ssh_add = self.SSH_ADD ssh_copy_id = self.SSH_COPY_ID ssh_agent = self.SSH_AGENT shell = self.SHELL tool_dict = { 'ssh_keygen': ssh_keygen, 'ssh_add': ssh_add, 'ssh_copy_id': ssh_copy_id, 'ssh_agent': ssh_agent, 'shell': shell } for tool_name in tool_dict: tool = tool_dict[tool_name] if tool is '/bin/true': raise ConnToolNotFoundError( tool_name, "executable not set or found on path,") if os.path.exists("/root/.ssh/id_rsa"): pass else: cmd = "%s -t rsa -f /root/.ssh/id_rsa -N '' " % (ssh_keygen) status, output = client_session.cmd_status_output(cmd) if status: raise ConnCmdClientError(cmd, output) cmd = "%s %s" % (ssh_agent, shell) status, output = client_session.cmd_status_output(cmd) if status: raise ConnCmdClientError(cmd, output) cmd = "%s %s" % (ssh_add, ssh_id_rsa_path) status, output = client_session.cmd_status_output(cmd) if status: raise ConnCmdClientError(cmd, output) cmd = "%s -i %s %s@%s" % (ssh_copy_id, ssh_rsa_pub_path, server_user, server_ip) client_session.sendline(cmd) try: remote.handle_prompts(client_session, server_user, server_pwd, prompt=r"[\#\$]\s*$") except remote.LoginError, detail: raise ConnCmdClientError(cmd, detail)
def run(test, params, env): """ Test interafce xml options. 1.Prepare test environment,destroy or suspend a VM. 2.Edit xml and start the domain. 3.Perform test operation. 4.Recover test environment. 5.Confirm the test result. """ vm_name = params.get("main_vm") vm = env.get_vm(vm_name) virsh_dargs = {'debug': True, 'ignore_status': False} def create_iface_xml(iface_mac): """ Create interface xml file """ iface = Interface(type_name=iface_type) source = ast.literal_eval(iface_source) if source: iface.source = source iface.model = iface_model if iface_model else "virtio" iface.mac_address = iface_mac driver_dict = {} driver_host = {} driver_guest = {} if iface_driver: driver_dict = ast.literal_eval(iface_driver) if iface_driver_host: driver_host = ast.literal_eval(iface_driver_host) if iface_driver_guest: driver_guest = ast.literal_eval(iface_driver_guest) iface.driver = iface.new_driver(driver_attr=driver_dict, driver_host=driver_host, driver_guest=driver_guest) logging.debug("Create new interface xml: %s", iface) return iface def modify_iface_xml(update, status_error=False): """ Modify interface xml options """ vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) xml_devices = vmxml.devices iface_index = xml_devices.index( xml_devices.by_device_tag("interface")[0]) iface = xml_devices[iface_index] if iface_model: iface.model = iface_model else: del iface.model if iface_type: iface.type_name = iface_type del iface.source source = ast.literal_eval(iface_source) if source: net_ifs = utils_net.get_net_if(state="UP") # Check source device is valid or not, # if it's not in host interface list, try to set # source device to first active interface of host if (iface.type_name == "direct" and source.has_key('dev') and source['dev'] not in net_ifs): logging.warn( "Source device %s is not a interface" " of host, reset to %s", source['dev'], net_ifs[0]) source['dev'] = net_ifs[0] iface.source = source backend = ast.literal_eval(iface_backend) if backend: iface.backend = backend driver_dict = {} driver_host = {} driver_guest = {} if iface_driver: driver_dict = ast.literal_eval(iface_driver) if iface_driver_host: driver_host = ast.literal_eval(iface_driver_host) if iface_driver_guest: driver_guest = ast.literal_eval(iface_driver_guest) iface.driver = iface.new_driver(driver_attr=driver_dict, driver_host=driver_host, driver_guest=driver_guest) if iface.address: del iface.address logging.debug("New interface xml file: %s", iface) if unprivileged_user: # Create disk image for unprivileged user disk_index = xml_devices.index( xml_devices.by_device_tag("disk")[0]) disk_xml = xml_devices[disk_index] logging.debug("source: %s", disk_xml.source) disk_source = disk_xml.source.attrs["file"] cmd = ("cp -fZ {0} {1} && chown {2}:{2} {1}" "".format(disk_source, dst_disk, unprivileged_user)) utils.run(cmd) disk_xml.source = disk_xml.new_disk_source( attrs={"file": dst_disk}) vmxml.devices = xml_devices # Remove all channels to avoid of permission problem channels = vmxml.get_devices(device_type="channel") for channel in channels: vmxml.del_device(channel) vmxml.xmltreefile.write() logging.debug("New VM xml: %s", vmxml) utils.run("chmod a+rw %s" % vmxml.xml) virsh.define(vmxml.xml, **virsh_dargs) # Try to modify interface xml by update-device or edit xml elif update: iface.xmltreefile.write() ret = virsh.update_device(vm_name, iface.xml, ignore_status=True) libvirt.check_exit_status(ret, status_error) else: vmxml.devices = xml_devices vmxml.xmltreefile.write() vmxml.sync() def check_offloads_option(if_name, driver_options, session=None): """ Check interface offloads by ethtool output """ offloads = { "csum": "tx-checksumming", "gso": "generic-segmentation-offload", "tso4": "tcp-segmentation-offload", "tso6": "tx-tcp6-segmentation", "ecn": "tx-tcp-ecn-segmentation", "ufo": "udp-fragmentation-offload" } if session: ret, output = session.cmd_status_output("ethtool -k %s | head" " -18" % if_name) else: out = utils.run("ethtool -k %s | head -18" % if_name) ret, output = out.exit_status, out.stdout if ret: raise error.TestFail("ethtool return error code") logging.debug("ethtool output: %s", output) for offload in driver_options.keys(): if offloads.has_key(offload): if (output.count(offloads[offload]) and not output.count( "%s: %s" % (offloads[offload], driver_options[offload]))): raise error.TestFail( "offloads option %s: %s isn't" " correct in ethtool output" % (offloads[offload], driver_options[offload])) def run_xml_test(iface_mac): """ Test for interface options in vm xml """ # Get the interface object according the mac address vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) iface_devices = vmxml.get_devices(device_type="interface") iface = None for iface_dev in iface_devices: if iface_dev.mac_address == iface_mac: iface = iface_dev if not iface: raise error.TestFail("Can't find interface with mac" " '%s' in vm xml" % iface_mac) driver_dict = {} if iface_driver: driver_dict = ast.literal_eval(iface_driver) for driver_opt in driver_dict.keys(): if not driver_dict[driver_opt] == iface.driver.driver_attr[ driver_opt]: raise error.TestFail( "Can't see driver option %s=%s in vm xml" % (driver_opt, driver_dict[driver_opt])) if iface_target: if (not iface.target.has_key("dev") or not iface.target["dev"].startswith(iface_target)): raise error.TestFail("Can't see device target dev in vm xml") # Check macvtap mode by ip link command if iface_target == "macvtap" and iface.source.has_key("mode"): cmd = "ip -d link show %s" % iface.target["dev"] output = utils.run(cmd).stdout logging.debug("ip link output: %s", output) mode = iface.source["mode"] if mode == "passthrough": mode = "passthru" if not output.count("macvtap mode %s" % mode): raise error.TestFail("Failed to verify macvtap mode") def run_cmdline_test(iface_mac): """ Test for qemu-kvm command line options """ cmd = ("ps -ef | grep %s | grep -v grep " % vm_name) ret = utils.run(cmd) logging.debug("Command line %s", ret.stdout) if test_vhost_net: if not ret.stdout.count("vhost=on") and not rm_vhost_driver: raise error.TestFail("Can't see vhost options in" " qemu-kvm command line") if iface_model == "virtio": model_option = "device virtio-net-pci" else: model_option = "device rtl8139" iface_cmdline = re.findall( r"%s,(.+),mac=%s" % (model_option, iface_mac), ret.stdout) if not iface_cmdline: raise error.TestFail("Can't see %s with mac %s in command" " line" % (model_option, iface_mac)) cmd_opt = {} for opt in iface_cmdline[0].split(','): tmp = opt.rsplit("=") cmd_opt[tmp[0]] = tmp[1] logging.debug("Command line options %s", cmd_opt) driver_dict = {} # Test <driver> xml options. if iface_driver: iface_driver_dict = ast.literal_eval(iface_driver) for driver_opt in iface_driver_dict.keys(): if driver_opt == "name": continue elif driver_opt == "txmode": if iface_driver_dict["txmode"] == "iothread": driver_dict["tx"] = "bh" else: driver_dict["tx"] = iface_driver_dict["txmode"] elif driver_opt == "queues": driver_dict["mq"] = "on" driver_dict["vectors"] = str( int(iface_driver_dict["queues"]) * 2 + 2) else: driver_dict[driver_opt] = iface_driver_dict[driver_opt] # Test <driver><host/><driver> xml options. if iface_driver_host: driver_dict.update(ast.literal_eval(iface_driver_host)) # Test <driver><guest/><driver> xml options. if iface_driver_guest: driver_dict.update(ast.literal_eval(iface_driver_guest)) for driver_opt in driver_dict.keys(): if (not cmd_opt.has_key(driver_opt) or not cmd_opt[driver_opt] == driver_dict[driver_opt]): raise error.TestFail("Can't see option '%s=%s' in qemu-kvm " " command line" % (driver_opt, driver_dict[driver_opt])) if test_backend: guest_pid = ret.stdout.rsplit()[1] cmd = "lsof %s | grep %s" % (backend["tap"], guest_pid) if utils.system(cmd, ignore_status=True): raise error.TestFail("Guest process didn't open backend file" " %s" % backend["tap"]) cmd = "lsof %s | grep %s" % (backend["vhost"], guest_pid) if utils.system(cmd, ignore_status=True): raise error.TestFail("Guest process didn't open backend file" " %s" % backend["tap"]) def get_guest_ip(session, mac): """ Wrapper function to get guest ip address """ utils_net.restart_guest_network(session, mac) # Wait for IP address is ready utils_misc.wait_for(lambda: utils_net.get_guest_ip_addr(session, mac), 10) return utils_net.get_guest_ip_addr(session, mac) def check_user_network(session): """ Check user network ip address on guest """ vm_ips = [] vm_ips.append(get_guest_ip(session, iface_mac_old)) if attach_device: vm_ips.append(get_guest_ip(session, iface_mac)) logging.debug("IP address on guest: %s", vm_ips) if len(vm_ips) != len(set(vm_ips)): raise error.TestFail("Duplicated IP address on guest. " "Check bug: https://bugzilla.redhat." "com/show_bug.cgi?id=1147238") for vm_ip in vm_ips: if vm_ip is None or not vm_ip.startswith("10.0.2."): raise error.TestFail("Found wrong IP address" " on guest") # Check gateway address gateway = utils_net.get_net_gateway(session.cmd_output) if gateway != "10.0.2.2": raise error.TestFail("The gateway on guest is not" " right") # Check dns server address ns_list = utils_net.get_net_nameserver(session.cmd_output) if "10.0.2.3" not in ns_list: raise error.TestFail("The dns server can't be found" " on guest") def check_mcast_network(session): """ Check multicast ip address on guests """ username = params.get("username") password = params.get("password") src_addr = ast.literal_eval(iface_source)['address'] add_session = additional_vm.wait_for_serial_login(username=username, password=password) vms_sess_dict = {vm_name: session, additional_vm.name: add_session} # Check mcast address on host cmd = "netstat -g | grep %s" % src_addr if utils.run(cmd, ignore_status=True).exit_status: raise error.TestFail("Can't find multicast ip address" " on host") vms_ip_dict = {} # Get ip address on each guest for vms in vms_sess_dict.keys(): vm_mac = vm_xml.VMXML.get_first_mac_by_name(vms) vm_ip = get_guest_ip(vms_sess_dict[vms], vm_mac) if not vm_ip: raise error.TestFail("Can't get multicast ip" " address on guest") vms_ip_dict.update({vms: vm_ip}) if len(set(vms_ip_dict.values())) != len(vms_sess_dict): raise error.TestFail("Got duplicated multicast ip address") logging.debug("Found ips on guest: %s", vms_ip_dict) # Run omping server on host if not utils_package.package_install(["omping"]): raise error.TestError("Failed to install omping" " on host") cmd = ("iptables -F;omping -m %s %s" % (src_addr, "192.168.122.1 %s" % ' '.join(vms_ip_dict.values()))) # Run a backgroup job waiting for connection of client bgjob = utils.AsyncJob(cmd) # Run omping client on guests for vms in vms_sess_dict.keys(): # omping should be installed first if not utils_package.package_install(["omping"], vms_sess_dict[vms]): raise error.TestError("Failed to install omping" " on guest") cmd = ("iptables -F; omping -c 5 -T 5 -m %s %s" % (src_addr, "192.168.122.1 %s" % vms_ip_dict[vms])) ret, output = vms_sess_dict[vms].cmd_status_output(cmd) logging.debug("omping ret: %s, output: %s", ret, output) if (not output.count('multicast, xmt/rcv/%loss = 5/5/0%') or not output.count('unicast, xmt/rcv/%loss = 5/5/0%')): raise error.TestFail("omping failed on guest") # Kill the backgroup job bgjob.kill_func() status_error = "yes" == params.get("status_error", "no") start_error = "yes" == params.get("start_error", "no") unprivileged_user = params.get("unprivileged_user") # Interface specific attributes. iface_type = params.get("iface_type", "network") iface_source = params.get("iface_source", "{}") iface_driver = params.get("iface_driver") iface_model = params.get("iface_model", "virtio") iface_target = params.get("iface_target") iface_backend = params.get("iface_backend", "{}") iface_driver_host = params.get("iface_driver_host") iface_driver_guest = params.get("iface_driver_guest") attach_device = params.get("attach_iface_device") change_option = "yes" == params.get("change_iface_options", "no") update_device = "yes" == params.get("update_iface_device", "no") additional_guest = "yes" == params.get("additional_guest", "no") serial_login = "******" == params.get("serial_login", "no") rm_vhost_driver = "yes" == params.get("rm_vhost_driver", "no") test_option_cmd = "yes" == params.get("test_iface_option_cmd", "no") test_option_xml = "yes" == params.get("test_iface_option_xml", "no") test_vhost_net = "yes" == params.get("test_vhost_net", "no") test_option_offloads = "yes" == params.get("test_option_offloads", "no") test_iface_user = "******" == params.get("test_iface_user", "no") test_iface_mcast = "yes" == params.get("test_iface_mcast", "no") test_libvirtd = "yes" == params.get("test_libvirtd", "no") test_guest_ip = "yes" == params.get("test_guest_ip", "no") test_backend = "yes" == params.get("test_backend", "no") if iface_driver_host or iface_driver_guest or test_backend: if not libvirt_version.version_compare(1, 2, 8): raise error.TestNAError("Offloading/backend options not " "supported in this libvirt version") if iface_driver and "queues" in ast.literal_eval(iface_driver): if not libvirt_version.version_compare(1, 0, 6): raise error.TestNAError("Queues options not supported" " in this libvirt version") if unprivileged_user: if not libvirt_version.version_compare(1, 1, 1): raise error.TestNAError("qemu-bridge-helper not supported" " on this host") virsh_dargs["unprivileged_user"] = unprivileged_user # Create unprivileged user if needed cmd = ("grep {0} /etc/passwd || " "useradd {0}".format(unprivileged_user)) utils.run(cmd) # Need another disk image for unprivileged user to access dst_disk = "/tmp/%s.img" % unprivileged_user # Destroy VM first if vm.is_alive(): vm.destroy(gracefully=False) # Back up xml file. vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_mac_old = vm_xml.VMXML.get_first_mac_by_name(vm_name) # iface_mac will update if attach a new interface iface_mac = iface_mac_old # Additional vm for test additional_vm = None libvirtd = utils_libvirtd.Libvirtd() try: # Build the xml and run test. try: # Prepare interface backend files if test_backend: if not os.path.exists("/dev/vhost-net"): utils.run("modprobe vhost-net") backend = ast.literal_eval(iface_backend) backend_tap = "/dev/net/tun" backend_vhost = "/dev/vhost-net" if not backend: backend["tap"] = backend_tap backend["vhost"] = backend_vhost if not start_error: # Create backend files for normal test if not os.path.exists(backend["tap"]): os.rename(backend_tap, backend["tap"]) if not os.path.exists(backend["vhost"]): os.rename(backend_vhost, backend["vhost"]) # Edit the interface xml. if change_option: modify_iface_xml(update=False) if rm_vhost_driver: # Check vhost driver. kvm_version = os.uname()[2] driver_path = ("/lib/modules/%s/kernel/drivers/vhost/" "vhost_net.ko" % kvm_version) driver_backup = driver_path + ".bak" cmd = ("modprobe -r {0}; lsmod | " "grep {0}".format("vhost_net")) if not utils.system(cmd, ignore_status=True): raise error.TestError("Failed to remove vhost_net driver") # Move the vhost_net driver if os.path.exists(driver_path): os.rename(driver_path, driver_backup) else: # Load vhost_net driver by default cmd = "modprobe vhost_net" utils.system(cmd) # Attach a interface when vm is shutoff if attach_device == 'config': iface_mac = utils_net.generate_mac_address_simple() iface_xml_obj = create_iface_xml(iface_mac) iface_xml_obj.xmltreefile.write() ret = virsh.attach_device(vm_name, iface_xml_obj.xml, flagstr="--config", ignore_status=True) libvirt.check_exit_status(ret) # Clone additional vm if additional_guest: guest_name = "%s_%s" % (vm_name, '1') # Clone additional guest timeout = params.get("clone_timeout", 360) utils_libguestfs.virt_clone_cmd(vm_name, guest_name, True, timeout=timeout) additional_vm = vm.clone(guest_name) additional_vm.start() # additional_vm.wait_for_login() # Start the VM. if unprivileged_user: virsh.start(vm_name, **virsh_dargs) cmd = ("su - %s -c 'virsh console %s'" % (unprivileged_user, vm_name)) session = aexpect.ShellSession(cmd) session.sendline() remote.handle_prompts(session, params.get("username"), params.get("password"), "[\#\$]", 30) # Get ip address on guest if not get_guest_ip(session, iface_mac): raise error.TestError("Can't get ip address on guest") else: # Will raise VMStartError exception if start fails vm.start() if serial_login: session = vm.wait_for_serial_login() else: session = vm.wait_for_login() if start_error: raise error.TestFail("VM started unexpectedly") # Attach a interface when vm is running if attach_device == 'live': iface_mac = utils_net.generate_mac_address_simple() iface_xml_obj = create_iface_xml(iface_mac) iface_xml_obj.xmltreefile.write() ret = virsh.attach_device(vm_name, iface_xml_obj.xml, flagstr="--live", ignore_status=True) libvirt.check_exit_status(ret) # Need sleep here for attachment take effect time.sleep(5) # Update a interface options if update_device: modify_iface_xml(update=True, status_error=status_error) # Run tests for qemu-kvm command line options if test_option_cmd: run_cmdline_test(iface_mac) # Run tests for vm xml if test_option_xml: run_xml_test(iface_mac) # Run tests for offloads options if test_option_offloads: if iface_driver_host: ifname_guest = utils_net.get_linux_ifname( session, iface_mac) check_offloads_option(ifname_guest, ast.literal_eval(iface_driver_host), session) if iface_driver_guest: ifname_host = libvirt.get_ifname_host(vm_name, iface_mac) check_offloads_option(ifname_host, ast.literal_eval(iface_driver_guest)) if test_iface_user: # Test user type network check_user_network(session) if test_iface_mcast: # Test mcast type network check_mcast_network(session) # Check guest ip address if test_guest_ip: if not get_guest_ip(session, iface_mac): raise error.TestFail("Guest can't get a" " valid ip address") session.close() # Restart libvirtd and guest, then test again if test_libvirtd: libvirtd.restart() vm.destroy() vm.start() if test_option_xml: run_xml_test(iface_mac) # Detach hot/cold-plugged interface at last if attach_device: ret = virsh.detach_device(vm_name, iface_xml_obj.xml, flagstr="", ignore_status=True) libvirt.check_exit_status(ret) except virt_vm.VMStartError as e: logging.info(str(e)) if not start_error: raise error.TestFail('VM failed to start\n%s' % e) finally: # Recover VM. logging.info("Restoring vm...") # Restore interface backend files if test_backend: if not os.path.exists(backend_tap): os.rename(backend["tap"], backend_tap) if not os.path.exists(backend_vhost): os.rename(backend["vhost"], backend_vhost) if rm_vhost_driver: # Restore vhost_net driver if os.path.exists(driver_backup): os.rename(driver_backup, driver_path) if unprivileged_user: virsh.remove_domain(vm_name, "--remove-all-storage", **virsh_dargs) if additional_vm: virsh.remove_domain(additional_vm.name, "--remove-all-storage") # Kill all omping server process on host utils.system("pidof omping && killall omping", ignore_status=True) if vm.is_alive(): vm.destroy(gracefully=False) vmxml_backup.sync()
def run(test, params, env): """ Test the command virsh metadata Run in 4 steps: 1. Set domain metadata 2. Get domain metadata 3. Restart libvirtd then get domain metadata again 4. Remove domain metadata then get domain metadata again """ vm_name = params.get("main_vm") vm = env.get_vm(vm_name) metadata_uri = params.get("metadata_uri") metadata_key = params.get("metadata_key") metadata_value = params.get("metadata_value", "") metadata_option = params.get("metadata_option", "") virsh_dargs = {'debug': True, 'ignore_status': True} metadata_set = "yes" == params.get("metadata_set", "no") metadata_get = "yes" == params.get("metadata_get", "yes") metadata_remove = "yes" == params.get("metadata_remove", "no") restart_libvirtd = "yes" == params.get("restart_libvirtd", "no") status_error = "yes" == params.get("status_error", "no") if not metadata_uri: test.error("'uri' is needed") vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) # Start VM if vm.state() != "running": vm.destroy() vm.start() def pretty_xml(xml_str): return xml.dom.minidom.parseString(xml_str).toprettyxml() def check_result(result, expect_status, expect_output=None): """ Check virsh metadata command """ utlv.check_exit_status(result, expect_status) if result.exit_status == 0 and expect_output: expect_output = pretty_xml(expect_output) logging.debug("Expect metadata: %s", expect_output) output = result.stdout.strip() output = pretty_xml(output) logging.debug("Command get metadata: %s", output) if output != expect_output: test.fail("Metadat is not expected") def get_metadata(metadata_option=""): """ Get domain metadata """ option = metadata_option.replace("--edit", "") result = virsh.metadata(vm_name, metadata_uri, options=option, key=metadata_key, **virsh_dargs) return result try: # Set metadata XML if metadata_set: if not metadata_key: test.error("'key' is needed") if not metadata_value: test.error("New metadata is needed") # Parse metadata value if "--edit" in metadata_option: virsh_cmd = r"virsh metadata %s --uri %s --key %s %s" virsh_cmd = virsh_cmd % (vm_name, metadata_uri, metadata_key, metadata_option) session = aexpect.ShellSession("sudo -s") logging.info("Running command: %s", virsh_cmd) try: session.sendline(virsh_cmd) session.sendline(r":insert") session.sendline(metadata_value) session.sendline(".") session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$", debug=True, timeout=CMD_TIMEOUT) except Exception as e: logging.error("Error occurred: %s", e) session.close() else: result = virsh.metadata(vm_name, metadata_uri, options=metadata_option, key=metadata_key, new_metadata=metadata_value, **virsh_dargs) check_result(result, status_error) # Get metadata for option in metadata_option.split(): if option == "--config": vm.destroy() vm.start() check_result(get_metadata(metadata_option=option), status_error, metadata_value) elif metadata_get: check_result(get_metadata(metadata_option=option), status_error, metadata_value) # Restart libvirtd: if restart_libvirtd: libvirtd = Libvirtd() libvirtd.restart() # Get metadata again for option in metadata_option.split(): check_result(get_metadata(metadata_option=option), status_error, metadata_value) # Remove metadata if metadata_remove: remove_option = metadata_option.replace("--edit", "") remove_option += " --remove" result = virsh.metadata(vm_name, metadata_uri, options=remove_option, key=metadata_key, **virsh_dargs) check_result(result, status_error) # Get metadata again for option in metadata_option.split(): check_result(get_metadata(metadata_option=option), True) finally: vmxml.sync()
def trigger_events(dom, events_list=[]): """ Trigger various events in events_list :param dom: the vm objects corresponding to the domain :return: the expected output that virsh event command prints out """ expected_events_list = [] save_path = os.path.join(tmpdir, "%s_event.save" % dom.name) print(dom.name) xmlfile = dom.backup_xml() new_disk = os.path.join(tmpdir, "%s_new_disk.img" % dom.name) dest_path = os.path.join(data_dir.get_data_dir(), "copy") try: for event in events_list: logging.debug("Current event is: %s", event) if event in ['start', 'restore', 'create', 'edit', 'define', 'undefine', 'crash', 'device-removal-failed', 'watchdog', 'io-error']: if dom.is_alive(): dom.destroy() if event in ['create', 'define']: dom.undefine() else: if not dom.is_alive(): dom.start() dom.wait_for_login().close() if event == "resume": dom.pause() if event == "undefine": virsh.undefine(dom.name, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Undefined Removed") elif event == "create": virsh.create(xmlfile, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Resumed Unpaused") expected_events_list.append("'lifecycle' for %s:" " Started Booted") elif event == "destroy": virsh.destroy(dom.name, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Stopped Destroyed") elif event == "define": virsh.define(xmlfile, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Defined Added") elif event == "start": virsh.start(dom.name, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Resumed Unpaused") expected_events_list.append("'lifecycle' for %s:" " Started Booted") dom.wait_for_login().close() elif event == "suspend": virsh.suspend(dom.name, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Suspended Paused") if not libvirt_version.version_compare(5, 3, 0): expected_events_list.append("'lifecycle' for %s:" " Suspended Paused") elif event == "resume": virsh.resume(dom.name, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Resumed Unpaused") elif event == "save": virsh.save(dom.name, save_path, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Suspended Paused") expected_events_list.append("'lifecycle' for %s:" " Stopped Saved") elif event == "restore": if not os.path.exists(save_path): logging.error("%s not exist", save_path) else: virsh.restore(save_path, **virsh_dargs) expected_events_list.append("'lifecycle' for %s:" " Started Restored") expected_events_list.append("'lifecycle' for %s:" " Resumed Snapshot") elif event == "edit": #Check whether 'description' element exists. domxml = virsh.dumpxml(dom.name).stdout.strip() find_desc = parseString(domxml).getElementsByTagName("description") if find_desc == []: #If not exists, add one for it. logging.info("Adding <description> to guest") virsh.desc(dom.name, "--config", "Added desc for testvm", **virsh_dargs) #The edit operation is to delete 'description' element. edit_cmd = [r":g/<description.*<\/description>/d"] utlv.exec_virsh_edit(dom.name, edit_cmd) expected_events_list.append("'lifecycle' for %s:" " Defined Updated") elif event == "shutdown": if signal_name is None: virsh.shutdown(dom.name, **virsh_dargs) # Wait a few seconds for shutdown finish time.sleep(3) if utils_misc.compare_qemu_version(2, 9, 0): #Shutdown reason distinguished from qemu_2.9.0-9 expected_events_list.append("'lifecycle' for %s:" " Shutdown Finished after guest request") else: os.kill(dom.get_pid(), getattr(signal, signal_name)) if utils_misc.compare_qemu_version(2, 9, 0): expected_events_list.append("'lifecycle' for %s:" " Shutdown Finished after host request") if not utils_misc.compare_qemu_version(2, 9, 0): expected_events_list.append("'lifecycle' for %s:" " Shutdown Finished") wait_for_shutoff(dom) expected_events_list.append("'lifecycle' for %s:" " Stopped Shutdown") elif event == "crash": if not vmxml.xmltreefile.find('devices').findall('panic'): # Set panic device panic_dev = Panic() panic_dev.model = panic_model panic_dev.addr_type = addr_type panic_dev.addr_iobase = addr_iobase vmxml.add_device(panic_dev) vmxml.on_crash = "coredump-restart" vmxml.sync() logging.info("Guest xml now is: %s", vmxml) dom.start() session = dom.wait_for_login() # Stop kdump in the guest session.cmd("systemctl stop kdump", ignore_all_errors=True) # Enable sysRq session.cmd("echo 1 > /proc/sys/kernel/sysrq") try: # Crash the guest session.cmd("echo c > /proc/sysrq-trigger", timeout=90) except (ShellTimeoutError, ShellProcessTerminatedError) as details: logging.info(details) session.close() expected_events_list.append("'lifecycle' for %s:" " Crashed Panicked") expected_events_list.append("'lifecycle' for %s:" " Resumed Unpaused") elif event == "reset": virsh.reset(dom.name, **virsh_dargs) expected_events_list.append("'reboot' for %s") elif event == "vcpupin": virsh.vcpupin(dom.name, '0', '0', **virsh_dargs) expected_events_list.append("'tunable' for %s:" "\n\tcputune.vcpupin0: 0") elif event == "emulatorpin": virsh.emulatorpin(dom.name, '0', **virsh_dargs) expected_events_list.append("'tunable' for %s:" "\n\tcputune.emulatorpin: 0") elif event == "setmem": mem_size = int(params.get("mem_size", 512000)) virsh.setmem(dom.name, mem_size, **virsh_dargs) expected_events_list.append("'balloon-change' for %s:") elif event == "device-added-removed": add_disk(dom.name, new_disk, 'vdb', '') expected_events_list.append("'device-added' for %s:" " virtio-disk1") virsh.detach_disk(dom.name, 'vdb', **virsh_dargs) expected_events_list.append("'device-removed' for %s:" " virtio-disk1") iface_xml_obj = create_iface_xml() iface_xml_obj.xmltreefile.write() virsh.detach_device(dom.name, iface_xml_obj.xml, **virsh_dargs) expected_events_list.append("'device-removed' for %s:" " net0") time.sleep(2) virsh.attach_device(dom.name, iface_xml_obj.xml, **virsh_dargs) expected_events_list.append("'device-added' for %s:" " net0") elif event == "block-threshold": add_disk(dom.name, new_disk, 'vdb', '', format=disk_format) logging.debug(process.run('qemu-img info %s -U' % new_disk)) virsh.domblkthreshold(vm_name, 'vdb', '100M') session = dom.wait_for_login() session.cmd("mkfs.ext4 /dev/vdb && mount /dev/vdb /mnt && ls /mnt && " "dd if=/dev/urandom of=/mnt/bigfile bs=1M count=300 && sync") time.sleep(5) session.close() expected_events_list.append("'block-threshold' for %s:" " dev: vdb(%s) 104857600 29368320") virsh.detach_disk(dom.name, 'vdb', **virsh_dargs) elif event == "change-media": target_device = "hdc" device_target_bus = params.get("device_target_bus", "ide") disk_blk = vm_xml.VMXML.get_disk_blk(dom.name) logging.info("disk_blk %s", disk_blk) if target_device not in disk_blk: logging.info("Adding cdrom to guest") if dom.is_alive(): dom.destroy() add_disk(dom.name, new_disk, target_device, ("--type cdrom --sourcetype file --driver qemu " + "--config --targetbus %s" % device_target_bus)) dom.start() all_options = new_disk + " --insert" virsh.change_media(dom.name, target_device, all_options, **virsh_dargs) expected_events_list.append("'tray-change' for %s disk" + " .*%s.*:" % device_target_bus + " opened") expected_events_list.append("'tray-change' for %s disk" + " .*%s.*:" % device_target_bus + " closed") all_options = new_disk + " --eject" virsh.change_media(dom.name, target_device, all_options, **virsh_dargs) expected_events_list.append("'tray-change' for %s disk" + " .*%s.*:" % device_target_bus + " opened") elif event == "hwclock": session = dom.wait_for_login() try: session.cmd("hwclock --systohc", timeout=60) except (ShellTimeoutError, ShellProcessTerminatedError) as details: logging.info(details) session.close() expected_events_list.append("'rtc-change' for %s:") elif event == "metadata_set": metadata_uri = params.get("metadata_uri") metadata_key = params.get("metadata_key") metadata_value = params.get("metadata_value") virsh.metadata(dom.name, metadata_uri, options="", key=metadata_key, new_metadata=metadata_value, **virsh_dargs) expected_events_list.append("'metadata-change' for %s: " "element http://app.org/") elif event == "metadata_edit": metadata_uri = "http://herp.derp/" metadata_key = "herp" metadata_value = "<derp xmlns:foobar='http://foo.bar/'>foo<bar></bar></derp>" virsh_cmd = r"virsh metadata %s --uri %s --key %s %s" virsh_cmd = virsh_cmd % (dom.name, metadata_uri, metadata_key, "--edit") session = aexpect.ShellSession("sudo -s") logging.info("Running command: %s", virsh_cmd) try: session.sendline(virsh_cmd) session.sendline(r":insert") session.sendline(metadata_value) session.sendline(".") session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$", debug=True, timeout=60) except Exception as e: test.error("Error occured: %s" % e) session.close() # Check metadata after edit virsh.metadata(dom.name, metadata_uri, options="", key=metadata_key, **virsh_dargs) expected_events_list.append("'metadata-change' for %s: " "element http://app.org/") elif event == "metadata_remove": virsh.metadata(dom.name, metadata_uri, options="--remove", key=metadata_key, **virsh_dargs) expected_events_list.append("'metadata-change' for %s: " "element http://app.org/") elif event == "blockcommit": disk_path = dom.get_blk_devices()['vda']['source'] virsh.snapshot_create_as(dom.name, "s1 --disk-only --no-metadata", **virsh_dargs) snapshot_path = dom.get_blk_devices()['vda']['source'] virsh.blockcommit(dom.name, "vda", "--active --pivot", **virsh_dargs) expected_events_list.append("'block-job' for %s: " "Active Block Commit for " + "%s" % snapshot_path + " ready") expected_events_list.append("'block-job-2' for %s: " "Active Block Commit for vda ready") expected_events_list.append("'block-job' for %s: " "Active Block Commit for " + "%s" % disk_path + " completed") expected_events_list.append("'block-job-2' for %s: " "Active Block Commit for vda completed") os.unlink(snapshot_path) elif event == "blockcopy": disk_path = dom.get_blk_devices()['vda']['source'] dom.undefine() virsh.blockcopy(dom.name, "vda", dest_path, "--pivot", **virsh_dargs) expected_events_list.append("'block-job' for %s: " "Block Copy for " + "%s" % disk_path + " ready") expected_events_list.append("'block-job-2' for %s: " "Block Copy for vda ready") expected_events_list.append("'block-job' for %s: " "Block Copy for " + "%s" % dest_path + " completed") expected_events_list.append("'block-job-2' for %s: " "Block Copy for vda completed") elif event == "detach-dimm": prepare_vmxml_mem(vmxml) tg_size = params.get("dimm_size") tg_sizeunit = params.get("dimm_unit") dimm_xml = utils_hotplug.create_mem_xml(tg_size, None, None, tg_sizeunit) virsh.attach_device(dom.name, dimm_xml.xml, flagstr="--config", **virsh_dargs) vmxml_dimm = vm_xml.VMXML.new_from_dumpxml(dom.name) logging.debug("Current vmxml with plugged dimm dev is %s\n" % vmxml_dimm) virsh.start(dom.name, **virsh_dargs) dom.wait_for_login().close() result = virsh.detach_device(dom.name, dimm_xml.xml, debug=True, ignore_status=True) expected_fails = params.get("expected_fails") utlv.check_result(result, expected_fails) vmxml_live = vm_xml.VMXML.new_from_dumpxml(dom.name) logging.debug("Current vmxml after hot-unplug dimm is %s\n" % vmxml_live) expected_events_list.append("'device-removal-failed' for %s: dimm0") elif event == "watchdog": vmxml.remove_all_device_by_type('watchdog') watchdog_dev = Watchdog() watchdog_dev.model_type = params.get("watchdog_model") action = params.get("action") watchdog_dev.action = action vmxml.add_device(watchdog_dev) vmxml.sync() logging.debug("Current vmxml with watchdog dev is %s\n" % vmxml) virsh.start(dom.name, **virsh_dargs) session = dom.wait_for_login() try: session.cmd("echo 0 > /dev/watchdog") except (ShellTimeoutError, ShellProcessTerminatedError) as details: test.fail("Failed to trigger watchdog: %s" % details) session.close() # watchdog acts slowly, waiting for it. time.sleep(30) expected_events_list.append("'watchdog' for %s: " + "%s" % action) if action == 'pause': expected_events_list.append("'lifecycle' for %s: Suspended Watchdog") virsh.resume(dom.name, **virsh_dargs) else: # action == 'reset' expected_events_list.append("'reboot' for %s") elif event == "io-error": part_size = params.get("part_size") resume_event = params.get("resume_event") suspend_event = params.get("suspend_event") process.run("truncate -s %s %s" % (part_size, small_part), shell=True) utlv.mkfs(small_part, part_format) utils_misc.mount(small_part, mount_point, None) add_disk(dom.name, new_disk, 'vdb', '--subdriver qcow2 --config', 'qcow2') dom.start() session = dom.wait_for_login() session.cmd("mkfs.ext4 /dev/vdb && mount /dev/vdb /mnt && ls /mnt && " "dd if=/dev/zero of=/mnt/test.img bs=1M count=50", ignore_all_errors=True) time.sleep(5) session.close() expected_events_list.append("'io-error' for %s: " + "%s" % new_disk + r" \(virtio-disk1\) pause") expected_events_list.append("'io-error-reason' for %s: " + "%s" % new_disk + r" \(virtio-disk1\) pause due to enospc") expected_events_list.append(suspend_event) process.run("df -hT") virsh.resume(dom.name, **virsh_dargs) time.sleep(5) expected_events_list.append(resume_event) expected_events_list.append("'io-error' for %s: " + "%s" % new_disk + r" \(virtio-disk1\) pause") expected_events_list.append("'io-error-reason' for %s: " + "%s" % new_disk + r" \(virtio-disk1\) pause due to enospc") expected_events_list.append(suspend_event) ret = virsh.domstate(dom.name, "--reason", **virsh_dargs) if ret.stdout.strip() != "paused (I/O error)": test.fail("Domain state should still be paused due to I/O error!") else: test.error("Unsupported event: %s" % event) # Event may not received immediately time.sleep(3) finally: if os.path.exists(save_path): os.unlink(save_path) if os.path.exists(new_disk): os.unlink(new_disk) if os.path.exists(dest_path): os.unlink(dest_path) return [(dom.name, event) for event in expected_events_list]
def run(test, params, env): """ Test interafce xml options. 1.Prepare test environment,destroy or suspend a VM. 2.Edit xml and start the domain. 3.Perform test operation. 4.Recover test environment. 5.Confirm the test result. """ vm_name = params.get("main_vm") vm = env.get_vm(vm_name) host_arch = platform.machine() virsh_dargs = {'debug': True, 'ignore_status': False} if not utils_package.package_install(["lsof"]): test.cancel("Failed to install dependency package lsof" " on host") def create_iface_xml(iface_mac): """ Create interface xml file """ iface = Interface(type_name=iface_type) source = ast.literal_eval(iface_source) if source: iface.source = source iface.model = iface_model if iface_model else "virtio" iface.mac_address = iface_mac driver_dict = {} driver_host = {} driver_guest = {} if iface_driver: driver_dict = ast.literal_eval(iface_driver) if iface_driver_host: driver_host = ast.literal_eval(iface_driver_host) if iface_driver_guest: driver_guest = ast.literal_eval(iface_driver_guest) iface.driver = iface.new_driver(driver_attr=driver_dict, driver_host=driver_host, driver_guest=driver_guest) if test_target: iface.target = {"dev": target_dev} logging.debug("Create new interface xml: %s", iface) return iface def modify_iface_xml(update, status_error=False): """ Modify interface xml options """ vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) xml_devices = vmxml.devices iface_index = xml_devices.index( xml_devices.by_device_tag("interface")[0]) iface = xml_devices[iface_index] if iface_model: iface.model = iface_model else: del iface.model if iface_type: iface.type_name = iface_type del iface.source source = ast.literal_eval(iface_source) if source: net_ifs = utils_net.get_net_if(state="UP") # Check source device is valid or not, # if it's not in host interface list, try to set # source device to first active interface of host if (iface.type_name == "direct" and 'dev' in source and source['dev'] not in net_ifs): logging.warn( "Source device %s is not a interface" " of host, reset to %s", source['dev'], net_ifs[0]) source['dev'] = net_ifs[0] iface.source = source backend = ast.literal_eval(iface_backend) if backend: iface.backend = backend driver_dict = {} driver_host = {} driver_guest = {} if iface_driver: driver_dict = ast.literal_eval(iface_driver) if iface_driver_host: driver_host = ast.literal_eval(iface_driver_host) if iface_driver_guest: driver_guest = ast.literal_eval(iface_driver_guest) iface.driver = iface.new_driver(driver_attr=driver_dict, driver_host=driver_host, driver_guest=driver_guest) if test_target: logging.debug("iface.target is %s" % target_dev) iface.target = {"dev": target_dev} if iface.address: del iface.address if set_ip: iface.ips = [ast.literal_eval(x) for x in set_ips] logging.debug("New interface xml file: %s", iface) if unprivileged_user: # Create disk image for unprivileged user disk_index = xml_devices.index( xml_devices.by_device_tag("disk")[0]) disk_xml = xml_devices[disk_index] logging.debug("source: %s", disk_xml.source) disk_source = disk_xml.source.attrs["file"] cmd = ("cp -fZ {0} {1} && chown {2}:{2} {1}" "".format(disk_source, dst_disk, unprivileged_user)) process.run(cmd, shell=True) disk_xml.source = disk_xml.new_disk_source( attrs={"file": dst_disk}) vmxml.devices = xml_devices # Remove all channels to avoid of permission problem channels = vmxml.get_devices(device_type="channel") for channel in channels: vmxml.del_device(channel) logging.info("Unprivileged users can't use 'dac' security driver," " removing from domain xml if present...") vmxml.del_seclabel([('model', 'dac')]) # Set vm memory to 2G if it's larger than 2G if vmxml.memory > 2097152: vmxml.memory = vmxml.current_mem = 2097152 vmxml.xmltreefile.write() logging.debug("New VM xml: %s", vmxml) process.run("chmod a+rw %s" % vmxml.xml, shell=True) virsh.define(vmxml.xml, **virsh_dargs) # Try to modify interface xml by update-device or edit xml elif update: iface.xmltreefile.write() ret = virsh.update_device(vm_name, iface.xml, ignore_status=True) libvirt.check_exit_status(ret, status_error) else: vmxml.devices = xml_devices vmxml.xmltreefile.write() try: vmxml.sync() if define_error: test.fail("Define VM succeed, but it should fail") except xcepts.LibvirtXMLError as e: if not define_error: test.fail("Define VM fail: %s" % e) def check_offloads_option(if_name, driver_options, session=None): """ Check interface offloads by ethtool output """ offloads = { "csum": "tx-checksumming", "tso4": "tcp-segmentation-offload", "tso6": "tx-tcp6-segmentation", "ecn": "tx-tcp-ecn-segmentation", "ufo": "udp-fragmentation-offload" } if session: ret, output = session.cmd_status_output("ethtool -k %s | head" " -18" % if_name) else: out = process.run("ethtool -k %s | head -18" % if_name, shell=True) ret, output = out.exit_status, out.stdout_text if ret: test.fail("ethtool return error code") logging.debug("ethtool output: %s", output) for offload in list(driver_options.keys()): if offload in offloads: if (output.count(offloads[offload]) and not output.count( "%s: %s" % (offloads[offload], driver_options[offload]))): test.fail("offloads option %s: %s isn't" " correct in ethtool output" % (offloads[offload], driver_options[offload])) def run_xml_test(iface_mac): """ Test for interface options in vm xml """ # Get the interface object according the mac address vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) iface_devices = vmxml.get_devices(device_type="interface") iface = None for iface_dev in iface_devices: if iface_dev.mac_address == iface_mac: iface = iface_dev if not iface: test.fail("Can't find interface with mac" " '%s' in vm xml" % iface_mac) driver_dict = {} if iface_driver: driver_dict = ast.literal_eval(iface_driver) for driver_opt in list(driver_dict.keys()): if not driver_dict[driver_opt] == iface.driver.driver_attr[ driver_opt]: test.fail("Can't see driver option %s=%s in vm xml" % (driver_opt, driver_dict[driver_opt])) else: logging.info("Find %s=%s in vm xml" % (driver_opt, driver_dict[driver_opt])) if iface_target: if ("dev" not in iface.target or not iface.target["dev"].startswith(iface_target)): test.fail("Can't see device target dev in vm xml") # Check macvtap mode by ip link command if iface_target == "macvtap" and "mode" in iface.source: cmd = "ip -d link show %s" % iface.target["dev"] output = process.run(cmd, shell=True).stdout_text logging.debug("ip link output: %s", output) mode = iface.source["mode"] if mode == "passthrough": mode = "passthru" if not re.search(r"macvtap\s+mode %s" % mode, output): test.fail("Failed to verify macvtap mode") # Check if the "target dev" is set successfully # 1. Target dev name with prefix as "vnet" will always be override; # 2. Target dev name with prefix as "macvtap" or "macvlan" with direct # type interface will be override; # 3. Other scenarios, the target dev should be set successfully. if test_target: if target_dev != iface.target["dev"]: if target_dev.startswith("vnet") or \ (iface_type == "direct" and (target_dev.startswith("macvtap") or target_dev.startswith("macvlan"))): logging.debug("target dev %s is override" % target_dev) else: test.fail("Failed to set target dev to %s", target_dev) else: logging.debug("target dev set successfully to %s", iface.target["dev"]) def run_cmdline_test(iface_mac, host_arch): """ Test qemu command line :param iface_mac: expected MAC :param host_arch: host architecture, e.g. x86_64 :raise avocado.core.exceptions.TestError: if preconditions are not met :raise avocado.core.exceptions.TestFail: if commandline doesn't match :return: None """ cmd = ("ps -ef | grep %s | grep -v grep " % vm_name) ret = process.run(cmd, shell=True) logging.debug("Command line %s", ret.stdout_text) if test_vhost_net: if not ret.stdout_text.count("vhost=on") and not rm_vhost_driver: test.fail("Can't see vhost options in" " qemu-kvm command line") if iface_model == "virtio": if host_arch == 's390x': model_option = "device virtio-net-ccw" else: model_option = "device virtio-net-pci" elif iface_model == 'rtl8139': model_option = "device rtl8139" else: test.error( "Don't know which device driver to expect on qemu cmdline" " for iface_model %s" % iface_model) iface_cmdline = re.findall( r"%s,(.+),mac=%s" % (model_option, iface_mac), ret.stdout_text) if not iface_cmdline: test.fail("Can't see %s with mac %s in command" " line" % (model_option, iface_mac)) cmd_opt = {} for opt in iface_cmdline[0].split(','): tmp = opt.rsplit("=") cmd_opt[tmp[0]] = tmp[1] logging.debug("Command line options %s", cmd_opt) driver_dict = {} # Test <driver> xml options. if iface_driver: iface_driver_dict = ast.literal_eval(iface_driver) for driver_opt in list(iface_driver_dict.keys()): if driver_opt == "name": continue elif driver_opt == "txmode": if iface_driver_dict["txmode"] == "iothread": driver_dict["tx"] = "bh" else: driver_dict["tx"] = iface_driver_dict["txmode"] elif driver_opt == "queues": driver_dict["mq"] = "on" if "pci" in model_option: driver_dict["vectors"] = str( int(iface_driver_dict["queues"]) * 2 + 2) else: driver_dict[driver_opt] = iface_driver_dict[driver_opt] # Test <driver><host/><driver> xml options. if iface_driver_host: driver_dict.update(ast.literal_eval(iface_driver_host)) # Test <driver><guest/><driver> xml options. if iface_driver_guest: driver_dict.update(ast.literal_eval(iface_driver_guest)) for driver_opt in list(driver_dict.keys()): if (driver_opt not in cmd_opt or not cmd_opt[driver_opt] == driver_dict[driver_opt]): test.fail("Can't see option '%s=%s' in qemu-kvm " " command line" % (driver_opt, driver_dict[driver_opt])) logging.info("Find %s=%s in qemu-kvm command line" % (driver_opt, driver_dict[driver_opt])) if test_backend: guest_pid = ret.stdout_text.rsplit()[1] cmd = "lsof %s | grep %s" % (backend["tap"], guest_pid) if process.system(cmd, ignore_status=True, shell=True): test.fail("Guest process didn't open backend file" " %s" % backend["tap"]) cmd = "lsof %s | grep %s" % (backend["vhost"], guest_pid) if process.system(cmd, ignore_status=True, shell=True): test.fail("Guest process didn't open backend file" " %s" % backend["vhost"]) def get_guest_ip(session, mac): """ Wrapper function to get guest ip address """ utils_net.restart_guest_network(session, mac) # Wait for IP address is ready utils_misc.wait_for(lambda: utils_net.get_guest_ip_addr(session, mac), 10) return utils_net.get_guest_ip_addr(session, mac) def check_user_network(session): """ Check user network ip address on guest """ vm_ips = [] vm_ips.append(get_guest_ip(session, iface_mac_old)) if attach_device: vm_ips.append(get_guest_ip(session, iface_mac)) logging.debug("IP address on guest: %s", vm_ips) if len(vm_ips) != len(set(vm_ips)): logging.debug( "Duplicated IP address on guest. Check bug: " "https://bugzilla.redhat.com/show_bug.cgi?id=1147238") for vm_ip in vm_ips: if not vm_ip or vm_ip != expect_ip: logging.debug("vm_ip is %s, expect_ip is %s", vm_ip, expect_ip) test.fail("Found wrong IP address" " on guest") # Check gateway address gateway = str(utils_net.get_default_gateway(False, session)) if expect_gw not in gateway: test.fail("The gateway on guest is %s, while expect is %s" % (gateway, expect_gw)) # Check dns server address ns_list = utils_net.get_guest_nameserver(session) if expect_ns not in ns_list: test.fail("The dns found is %s, which expect is %s" % (ns_list, expect_ns)) def check_mcast_network(session, add_session): """ Check multicast ip address on guests :param session: vm session :param add_session: additional vm session """ src_addr = ast.literal_eval(iface_source)['address'] vms_sess_dict = {vm_name: session, additional_vm.name: add_session} # Check mcast address on host cmd = "netstat -g | grep %s" % src_addr if process.run(cmd, ignore_status=True, shell=True).exit_status: test.fail("Can't find multicast ip address" " on host") vms_ip_dict = {} # Get ip address on each guest for vms in list(vms_sess_dict.keys()): vm_mac = vm_xml.VMXML.get_first_mac_by_name(vms) vm_ip = get_guest_ip(vms_sess_dict[vms], vm_mac) if not vm_ip: test.fail("Can't get multicast ip" " address on guest") vms_ip_dict.update({vms: vm_ip}) if len(set(vms_ip_dict.values())) != len(vms_sess_dict): test.fail("Got duplicated multicast ip address") logging.debug("Found ips on guest: %s", vms_ip_dict) # Run omping server on host if not utils_package.package_install(["omping"]): test.error("Failed to install omping" " on host") cmd = ("iptables -F;omping -m %s %s" % (src_addr, "192.168.122.1 %s" % ' '.join(list(vms_ip_dict.values())))) # Run a backgroup job waiting for connection of client bgjob = utils_misc.AsyncJob(cmd) # Run omping client on guests for vms in list(vms_sess_dict.keys()): # omping should be installed first if not utils_package.package_install(["omping"], vms_sess_dict[vms]): test.error("Failed to install omping" " on guest") cmd = ("iptables -F; omping -c 5 -T 5 -m %s %s" % (src_addr, "192.168.122.1 %s" % vms_ip_dict[vms])) ret, output = vms_sess_dict[vms].cmd_status_output(cmd) logging.debug("omping ret: %s, output: %s", ret, output) if (not output.count('multicast, xmt/rcv/%loss = 5/5/0%') or not output.count('unicast, xmt/rcv/%loss = 5/5/0%')): test.fail("omping failed on guest") # Kill the backgroup job bgjob.kill_func() def get_iface_model(iface_model, host_arch): """ Get iface_model. On s390x use default model 'virtio' if non-virtio given :param iface_model: value as by test configuration or default :param host_arch: host architecture, e.g. x86_64 :return: iface_model """ if 's390x' == host_arch and 'virtio' not in iface_model: return "virtio" else: return iface_model def check_vhostuser_guests(session1, session2): """ Check the vhostuser interface in guests param session1: Session of original guest param session2: Session of original additional guest """ logging.debug("iface details is %s" % libvirt.get_interface_details(vm_name)) vm1_mac = str(libvirt.get_interface_details(vm_name)[0]['mac']) vm2_mac = str(libvirt.get_interface_details(add_vm_name)[0]['mac']) utils_net.set_guest_ip_addr(session1, vm1_mac, guest1_ip) utils_net.set_guest_ip_addr(session2, vm2_mac, guest2_ip) ping_status, ping_output = utils_net.ping(dest=guest2_ip, count='3', timeout=5, session=session1) logging.info("output:%s" % ping_output) if ping_status != 0: if ping_expect_fail: logging.info("Can not ping guest2 as expected") else: test.fail("Can not ping guest2 from guest1") else: if ping_expect_fail: test.fail("Ping guest2 successfully not expected") else: logging.info("Can ping guest2 from guest1") def get_ovs_statis(ovs): """ Get ovs-vsctl interface statistics and format in dict param ovs: openvswitch instance """ ovs_statis_dict = {} ovs_iface_info = ovs.ovs_vsctl(["list", "interface"]).stdout_text.strip() ovs_iface_list = re.findall( 'name\s+: (\S+)\n.*?statistics\s+: {(.*?)}\n', ovs_iface_info, re.S) logging.info("ovs iface list is %s", ovs_iface_list) # Dict of iface name and statistics for iface_name in vhostuser_names.split(): for ovs_iface in ovs_iface_list: if iface_name == eval(ovs_iface[0]): format_statis = dict( re.findall(r'(\S*?)=(\d*?),', ovs_iface[1])) ovs_statis_dict[iface_name] = format_statis break return ovs_statis_dict status_error = "yes" == params.get("status_error", "no") start_error = "yes" == params.get("start_error", "no") define_error = "yes" == params.get("define_error", "no") unprivileged_user = params.get("unprivileged_user") # Interface specific attributes. iface_type = params.get("iface_type", "network") iface_source = params.get("iface_source", "{}") iface_driver = params.get("iface_driver") iface_model = get_iface_model(params.get("iface_model", "virtio"), host_arch) iface_target = params.get("iface_target") iface_backend = params.get("iface_backend", "{}") iface_driver_host = params.get("iface_driver_host") iface_driver_guest = params.get("iface_driver_guest") ovs_br_name = params.get("ovs_br_name") vhostuser_names = params.get("vhostuser_names") attach_device = params.get("attach_iface_device") expect_tx_size = params.get("expect_tx_size") guest1_ip = params.get("vhostuser_guest1_ip", "192.168.100.1") guest2_ip = params.get("vhostuser_guest2_ip", "192.168.100.2") change_option = "yes" == params.get("change_iface_options", "no") update_device = "yes" == params.get("update_iface_device", "no") additional_guest = "yes" == params.get("additional_guest", "no") serial_login = "******" == params.get("serial_login", "no") rm_vhost_driver = "yes" == params.get("rm_vhost_driver", "no") test_option_cmd = "yes" == params.get("test_iface_option_cmd", "no") test_option_xml = "yes" == params.get("test_iface_option_xml", "no") test_vhost_net = "yes" == params.get("test_vhost_net", "no") test_option_offloads = "yes" == params.get("test_option_offloads", "no") test_iface_user = "******" == params.get("test_iface_user", "no") test_iface_mcast = "yes" == params.get("test_iface_mcast", "no") test_libvirtd = "yes" == params.get("test_libvirtd", "no") restart_libvirtd = "yes" == params.get("restart_libvirtd", "no") restart_vm = "yes" == params.get("restart_vm", "no") test_guest_ip = "yes" == params.get("test_guest_ip", "no") test_backend = "yes" == params.get("test_backend", "no") check_guest_trans = "yes" == params.get("check_guest_trans", "no") set_ip = "yes" == params.get("set_user_ip", "no") set_ips = params.get("set_ips", "").split() expect_ip = params.get("expect_ip") expect_gw = params.get("expect_gw") expect_ns = params.get("expect_ns") test_target = "yes" == params.get("test_target", "no") target_dev = params.get("target_dev", None) # test params for vhostuser test huge_page = ast.literal_eval(params.get("huge_page", "{}")) numa_cell = ast.literal_eval(params.get("numa_cell", "{}")) additional_iface_source = ast.literal_eval( params.get("additional_iface_source", "{}")) vcpu_num = params.get("vcpu_num") cpu_mode = params.get("cpu_mode") hugepage_num = params.get("hugepage_num") log_pattern = params.get("log_pattern") # judgement params for vhostuer test need_vhostuser_env = "yes" == params.get("need_vhostuser_env", "no") ping_expect_fail = "yes" == params.get("ping_expect_fail", "no") check_libvirtd_log = "yes" == params.get("check_libvirtd_log", "no") check_statistics = "yes" == params.get("check_statistics", "no") enable_multiqueue = "yes" == params.get("enable_multiqueue", "no") queue_size = None if iface_driver: driver_dict = ast.literal_eval(iface_driver) if "queues" in driver_dict: queue_size = int(driver_dict.get("queues")) if iface_driver_host or iface_driver_guest or test_backend: if not libvirt_version.version_compare(1, 2, 8): test.cancel("Offloading/backend options not " "supported in this libvirt version") if iface_driver and "queues" in ast.literal_eval(iface_driver): if not libvirt_version.version_compare(1, 0, 6): test.cancel("Queues options not supported" " in this libvirt version") if unprivileged_user: if not libvirt_version.version_compare(1, 1, 1): test.cancel("qemu-bridge-helper not supported" " on this host") virsh_dargs["unprivileged_user"] = unprivileged_user # Create unprivileged user if needed cmd = ("grep {0} /etc/passwd || " "useradd {0}".format(unprivileged_user)) process.run(cmd, shell=True) # Need another disk image for unprivileged user to access dst_disk = "/tmp/%s.img" % unprivileged_user # Destroy VM first if vm.is_alive(): vm.destroy(gracefully=False) # Back up xml file. vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_mac_old = vm_xml.VMXML.get_first_mac_by_name(vm_name) # iface_mac will update if attach a new interface iface_mac = iface_mac_old # Additional vm for test additional_vm = None libvirtd = utils_libvirtd.Libvirtd() libvirtd_log_path = None libvirtd_conf = None if check_libvirtd_log: libvirtd_log_path = os.path.join(test.tmpdir, "libvirtd.log") libvirtd_conf = utils_config.LibvirtdConfig() libvirtd_conf["log_outputs"] = '"1:file:%s"' % libvirtd_log_path libvirtd.restart() # Prepare vhostuser ovs = None if need_vhostuser_env: # Reserve selinux status selinux_mode = utils_selinux.get_status() # Reserve orig page size orig_size = utils_memory.get_num_huge_pages() ovs_dir = data_dir.get_tmp_dir() ovs = utils_net.setup_ovs_vhostuser(hugepage_num, ovs_dir, ovs_br_name, vhostuser_names, queue_size) try: # Build the xml and run test. try: # Prepare interface backend files if test_backend: if not os.path.exists("/dev/vhost-net"): process.run("modprobe vhost-net", shell=True) backend = ast.literal_eval(iface_backend) backend_tap = "/dev/net/tun" backend_vhost = "/dev/vhost-net" if not backend: backend["tap"] = backend_tap backend["vhost"] = backend_vhost if not start_error: # Create backend files for normal test if not os.path.exists(backend["tap"]): os.rename(backend_tap, backend["tap"]) if not os.path.exists(backend["vhost"]): os.rename(backend_vhost, backend["vhost"]) # Edit the interface xml. if change_option: modify_iface_xml(update=False) if define_error: return if test_target: logging.debug("Setting target device name to %s", target_dev) modify_iface_xml(update=False) if rm_vhost_driver: # remove vhost driver on host and # the character file /dev/vhost-net cmd = ("modprobe -r {0}; " "rm -f /dev/vhost-net".format("vhost_net")) if process.system(cmd, ignore_status=True, shell=True): test.error("Failed to remove vhost_net driver") else: # Load vhost_net driver by default cmd = "modprobe vhost_net" process.system(cmd, shell=True) # Attach a interface when vm is shutoff if attach_device == 'config': iface_mac = utils_net.generate_mac_address_simple() iface_xml_obj = create_iface_xml(iface_mac) iface_xml_obj.xmltreefile.write() ret = virsh.attach_device(vm_name, iface_xml_obj.xml, flagstr="--config", ignore_status=True) libvirt.check_exit_status(ret) # Add hugepage and update cpu for vhostuser testing if huge_page: vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) membacking = vm_xml.VMMemBackingXML() hugepages = vm_xml.VMHugepagesXML() pagexml = hugepages.PageXML() pagexml.update(huge_page) hugepages.pages = [pagexml] membacking.hugepages = hugepages vmxml.mb = membacking vmxml.vcpu = int(vcpu_num) cpu_xml = vm_xml.VMCPUXML() cpu_xml.xml = "<cpu><numa/></cpu>" cpu_xml.numa_cell = cpu_xml.dicts_to_cells([numa_cell]) cpu_xml.mode = cpu_mode if cpu_mode == "custom": vm_capability = capability_xml.CapabilityXML() cpu_xml.model = vm_capability.model vmxml.cpu = cpu_xml vmxml.sync() logging.debug("xmltreefile:%s", vmxml.xmltreefile) # Clone additional vm if additional_guest: add_vm_name = "%s_%s" % (vm_name, '1') # Clone additional guest timeout = params.get("clone_timeout", 360) utils_libguestfs.virt_clone_cmd(vm_name, add_vm_name, True, timeout=timeout) additional_vm = vm.clone(add_vm_name) # Update iface source if needed if additional_iface_source: add_vmxml = vm_xml.VMXML.new_from_dumpxml(add_vm_name) add_xml_devices = add_vmxml.devices add_iface_index = add_xml_devices.index( add_xml_devices.by_device_tag("interface")[0]) add_iface = add_xml_devices[add_iface_index] add_iface.source = additional_iface_source add_vmxml.devices = add_xml_devices add_vmxml.xmltreefile.write() add_vmxml.sync() logging.debug("add vm xmltreefile:%s", add_vmxml.xmltreefile) additional_vm.start() # additional_vm.wait_for_login() username = params.get("username") password = params.get("password") add_session = additional_vm.wait_for_serial_login( username=username, password=password) # Start the VM. if unprivileged_user: virsh.start(vm_name, **virsh_dargs) cmd = ("su - %s -c 'virsh console %s'" % (unprivileged_user, vm_name)) session = aexpect.ShellSession(cmd) session.sendline() remote.handle_prompts(session, params.get("username"), params.get("password"), r"[\#\$]\s*$", 60) # Get ip address on guest if not get_guest_ip(session, iface_mac): test.error("Can't get ip address on guest") else: # Will raise VMStartError exception if start fails vm.start() if serial_login: session = vm.wait_for_serial_login() else: session = vm.wait_for_login() if start_error: test.fail("VM started unexpectedly") # Attach a interface when vm is running if attach_device == 'live': iface_mac = utils_net.generate_mac_address_simple() iface_xml_obj = create_iface_xml(iface_mac) iface_xml_obj.xmltreefile.write() ret = virsh.attach_device(vm_name, iface_xml_obj.xml, flagstr="--live", ignore_status=True, debug=True) libvirt.check_exit_status(ret, status_error) # Need sleep here for attachment take effect time.sleep(5) # Update a interface options if update_device: modify_iface_xml(update=True, status_error=status_error) # Run tests for qemu-kvm command line options if test_option_cmd: run_cmdline_test(iface_mac, host_arch) # Run tests for vm xml if test_option_xml: run_xml_test(iface_mac) # Run tests for offloads options if test_option_offloads: if iface_driver_host: ifname_guest = utils_net.get_linux_ifname( session, iface_mac) check_offloads_option(ifname_guest, ast.literal_eval(iface_driver_host), session) if iface_driver_guest: ifname_host = libvirt.get_ifname_host(vm_name, iface_mac) check_offloads_option(ifname_host, ast.literal_eval(iface_driver_guest)) if test_iface_user: # Test user type network check_user_network(session) if test_iface_mcast: # Test mcast type network check_mcast_network(session, add_session) # Check guest ip address if test_guest_ip: if not get_guest_ip(session, iface_mac): test.fail("Guest can't get a" " valid ip address") # Check guest RX/TX ring if check_guest_trans: ifname_guest = utils_net.get_linux_ifname(session, iface_mac) ret, outp = session.cmd_status_output("ethtool -g %s" % ifname_guest) if ret: test.fail("ethtool return error code") logging.info("ethtool output is %s", outp) driver_dict = ast.literal_eval(iface_driver) if expect_tx_size: driver_dict['tx_queue_size'] = expect_tx_size for outp_p in outp.split("Current hardware"): if 'rx_queue_size' in driver_dict: if re.search( r"RX:\s*%s" % driver_dict['rx_queue_size'], outp_p): logging.info("Find RX setting RX:%s by ethtool", driver_dict['rx_queue_size']) else: test.fail("Cannot find matching rx setting") if 'tx_queue_size' in driver_dict: if re.search( r"TX:\s*%s" % driver_dict['tx_queue_size'], outp_p): logging.info("Find TX settint TX:%s by ethtool", driver_dict['tx_queue_size']) else: test.fail("Cannot find matching tx setting") if test_target: logging.debug("Check if the target dev is set") run_xml_test(iface_mac) # Check vhostuser guest if additional_iface_source: check_vhostuser_guests(session, add_session) # Check libvirtd log if check_libvirtd_log: find = 0 with open(libvirtd_log_path) as f: lines = "".join(f.readlines()) if log_pattern in lines: logging.info("Finding msg<%s> in libvirtd log", log_pattern) else: test.fail("Can not find msg:<%s> in libvirtd.log" % log_pattern) # Check statistics if check_statistics: session.sendline("ping %s" % guest2_ip) add_session.sendline("ping %s" % guest1_ip) time.sleep(5) vhost_name = vhostuser_names.split()[0] ovs_statis_dict = get_ovs_statis(ovs)[vhost_name] domif_info = {} domif_info = libvirt.get_interface_details(vm_name) virsh.domiflist(vm_name, debug=True) domif_stat_result = virsh.domifstat(vm_name, vhost_name) if domif_stat_result.exit_status != 0: test.fail("domifstat cmd fail with msg:%s" % domif_stat_result.stderr) else: domif_stat = domif_stat_result.stdout.strip() logging.debug("vhost_name is %s, domif_stat is %s", vhost_name, domif_stat) domif_stat_dict = dict( re.findall("%s (\S*) (\d*)" % vhost_name, domif_stat)) logging.debug("ovs_statis is %s, domif_stat is %s", ovs_statis_dict, domif_stat_dict) ovs_cmp_dict = { 'tx_bytes': ovs_statis_dict['rx_bytes'], 'tx_drop': ovs_statis_dict['rx_dropped'], 'tx_errs': ovs_statis_dict['rx_errors'], 'tx_packets': ovs_statis_dict['rx_packets'], 'rx_bytes': ovs_statis_dict['tx_bytes'], 'rx_drop': ovs_statis_dict['tx_dropped'] } logging.debug("ovs_cmp_dict is %s", ovs_cmp_dict) for dict_key in ovs_cmp_dict.keys(): if domif_stat_dict[dict_key] != ovs_cmp_dict[dict_key]: test.fail( "Find ovs %s result (%s) different with domifstate result (%s)" % (dict_key, ovs_cmp_dict[dict_key], domif_stat_dict[dict_key])) else: logging.info("ovs %s value %s is same with domifstate", dict_key, domif_stat_dict[dict_key]) # Check multi_queue if enable_multiqueue: ifname_guest = utils_net.get_linux_ifname(session, iface_mac) for comb_size in (queue_size, queue_size - 1): logging.info("Setting multiqueue size to %s" % comb_size) session.cmd_status("ethtool -L %s combined %s" % (ifname_guest, comb_size)) ret, outp = session.cmd_status_output("ethtool -l %s" % ifname_guest) logging.debug("ethtool cmd output:%s" % outp) if not ret: pre_comb = re.search( "Pre-set maximums:[\s\S]*?Combined:.*?(\d+)", outp).group(1) cur_comb = re.search( "Current hardware settings:[\s\S]*?Combined:.*?(\d+)", outp).group(1) if int(pre_comb) != queue_size or int(cur_comb) != int( comb_size): test.fail( "Fail to check the combined size: setting: %s," "Pre-set: %s, Current-set: %s, queue_size: %s" % (comb_size, pre_comb, cur_comb, queue_size)) else: logging.info( "Getting correct Pre-set and Current set value" ) else: test.error("ethtool list fail: %s" % outp) session.close() if additional_guest: add_session.close() # Restart libvirtd and guest, then test again if restart_libvirtd: libvirtd.restart() if restart_vm: vm.destroy(gracefully=True) vm.start() if test_option_xml: run_xml_test(iface_mac) # Detach hot/cold-plugged interface at last if attach_device and not status_error: ret = virsh.detach_device(vm_name, iface_xml_obj.xml, flagstr="", ignore_status=True, debug=True) libvirt.check_exit_status(ret) except virt_vm.VMStartError as e: logging.info(str(e)) if not start_error: test.fail('VM failed to start\n%s' % e) finally: # Recover VM. logging.info("Restoring vm...") # Restore interface backend files if test_backend: if not os.path.exists(backend_tap): os.rename(backend["tap"], backend_tap) if not os.path.exists(backend_vhost): os.rename(backend["vhost"], backend_vhost) if rm_vhost_driver: # Restore vhost_net driver process.system("modprobe vhost_net", shell=True) if unprivileged_user: virsh.remove_domain(vm_name, **virsh_dargs) process.run('rm -f %s' % dst_disk, shell=True) if additional_vm: virsh.remove_domain(additional_vm.name, "--remove-all-storage") # Kill all omping server process on host process.system("pidof omping && killall omping", ignore_status=True, shell=True) if vm.is_alive(): vm.destroy(gracefully=True) vmxml_backup.sync() if need_vhostuser_env: utils_net.clean_ovs_env(selinux_mode=selinux_mode, page_size=orig_size, clean_ovs=True) if libvirtd_conf: libvirtd_conf.restore() libvirtd.restart() if libvirtd_log_path and os.path.exists(libvirtd_log_path): os.unlink(libvirtd_log_path)