def parent_snapshot_check(snap_parent): """ Do parent snapshot check :params: snap_parent: parent snapshot name that need to check """ # get snapshot name which is parent snapshot's child if "--current" in snap_parent_opt: cmd_result = virsh.snapshot_current(vm_name) snap_name = cmd_result.stdout.strip() else: snap_name = snap_parent_opt.split()[-1] # check parent snapshot in snapshot-list output = virsh.command("snapshot-list %s --parent" % vm_name).stdout for i in range(2, snap_num + 3): if output.splitlines()[i].split()[0] == snap_name: expect_name = output.split('\n')[i].split()[-1] break if snap_parent == expect_name: logging.info("Success to check parent snapshot") else: test.fail("Failed to check parent " "snapshot, expect %s, get %s" % (expect_name, snap_parent))
def do_virsh_start(vm_name): """ Start vm by using virsh start command. Throws a StartError if execute virsh start command failed. @param vm_ref: option of virsh start command. """ cmd_result = virsh.command("start %s" % vm_name) if cmd_result.exit_status: raise StartError(vm_name, cmd_result.stdout)
def do_virsh_start(vm_ref): """ Start vm by using virsh start command. Throws a StartError if execute virsh start command failed. :param vm_ref: option of virsh start command. """ cmd_result = virsh.command("start %s" % vm_ref) if cmd_result.exit_status: raise StartError(vm_ref, cmd_result.stderr)
def do_fstrim(test, fstrim_type, vm, status_error=False): """ Execute fstrim in different ways, and check its result. """ # ensure that volume capacity won't change before trimming disk. if not _sync_finished(): utils_misc.wait_for(_sync_finished, timeout=300) if fstrim_type == "fstrim_cmd": session = vm.wait_for_login() output = session.cmd_output("fstrim -v /mnt", timeout=240) session.close() logging.debug(output) if re.search("Operation not supported", output): if status_error: # virtio is not supported in unmap operations logging.debug("Expected failure: virtio do not support fstrim") return else: test.fail("Not supported fstrim on supported " "environment.Bug?") try: trimmed_bytes = re.search("\d+\sbytes", output).group(0).split()[0] trimmed = int(trimmed_bytes) logging.debug("Trimmed size is:%s bytes", trimmed) except (AttributeError, IndexError) as detail: test.fail("Do fstrim failed:%s" % detail) if trimmed == 0: test.fail("Trimmed size is 0.") elif fstrim_type == "mount_with_discard": pass elif fstrim_type == "qemu-guest-agent": cmd = ("qemu-agent-command %s '{\"execute\":\"guest-fstrim\"}'" % vm.name) try: virsh.command(cmd, debug=True, ignore_status=False) except process.CmdError: test.fail("Execute qemu-agent-command failed.")
def get_snap_createtime(vm_name, snap_name): """ Get the snap_name's create time from snap_list :param snap_list: output of snapshot list :param snap_name: name of snapshot you want to get :return: snapshot create time """ result = virsh.command("snapshot-list %s" % vm_name) logging.debug("result is %s", result.stdout) data = re.search(snap_name + r"\s+\d+-\d+-\d+\s+\d+:\d+:\d+", result.stdout).group() return data.split("%s " % snap_name)[1].strip()
def connect_to_server_hypervisor(params_to_connect_dict): """ Connect to hypervisor via virsh. :param params_to_connect_dict. Dictionary with connection parameters like uri :return: True if successful or False otherwise. """ out = virsh.command(params_to_connect_dict['cmd'], uri=params_to_connect_dict['uri'], debug=True, ignore_status=True) # Look for expected output and return True if pass for pass_message in params_to_connect_dict['pass_message_list']: if params_to_connect_dict['expect_error']: if pass_message in out.stderr_text: return True else: if pass_message in out.stdout_text: return True return False
def run(test, params, env): """ Test command: virsh list. 1) Filt parameters according libvirtd's version 2) Prepare domain's exist state:transient,managed-save. 3) Prepare libvirt's status. 4) Execute list command. 5) Result check. """ def list_local_domains_on_remote(options_ref, remote_ip, remote_passwd, local_ip): """ Create a virsh list command and execute it on remote host. It will list local domains on remote host. :param options_ref:options in virsh list command. :param remote_ip:remote host's ip. :param remote_passwd:remote host's password. :param local_ip:local ip, to create uri in virsh list. :return:return status and output of the virsh list command. """ complete_uri = libvirt_vm.complete_uri(local_ip) command_on_remote = "virsh -c %s list %s" % (complete_uri, options_ref) session = remote.remote_login( "ssh", remote_ip, "22", "root", remote_passwd, "#") time.sleep(5) status, output = session.cmd_status_output( command_on_remote, internal_timeout=5) time.sleep(5) session.close() return int(status), output vm_name = params.get("main_vm") vm = env.get_vm(vm_name) options_ref = params.get("list_options_ref", "") list_ref = params.get("list_type_ref", "") vm_ref = params.get("vm_ref", "") # Some parameters are not supported on old libvirt, skip them. help_info = virsh.command("help list").stdout.strip() if vm_ref and not re.search(vm_ref, help_info): raise error.TestNAError("This version do not support vm type:%s" % vm_ref) if list_ref and not re.search(list_ref, help_info): raise error.TestNAError("This version do not support list type:%s" % list_ref) status_error = params.get("status_error", "no") addition_status_error = params.get("addition_status_error", "no") domuuid = vm.get_uuid().strip() # If a transient domain is destroyed, it will disappear. if vm_ref == "transient" and options_ref == "inactive": logging.info("Set addition_status_error to yes") logging.info( "because transient domain will disappear after destroyed.") addition_status_error = "yes" if vm_ref == "transient": tmp_xml = vm.backup_xml() vm.undefine() elif vm_ref == "managed-save": virsh.managedsave(vm_name, ignore_status=True, print_info=True) # Prepare libvirtd status libvirtd = params.get("libvirtd", "on") if libvirtd == "off": utils_libvirtd.libvirtd_stop() # run test case if list_ref == "--uuid": result_expected = domuuid logging.info("%s's uuid is: %s", vm_name, domuuid) else: result_expected = vm_name logging.info("domain's name is: %s", vm_name) if options_ref == "vm_id": domid = vm.get_id().strip() logging.info("%s's running-id is: %s", vm_name, domid) options_ref = "%s %s" % (domid, list_ref) elif options_ref == "vm_uuid": logging.info("%s's uuid is: %s", vm_name, domuuid) options_ref = "%s %s" % (domuuid, list_ref) elif options_ref == "inactive": vm.destroy() options_ref = "--inactive %s" % list_ref elif options_ref == "vm_name": options_ref = "%s %s" % (vm_name, list_ref) elif options_ref == "all": options_ref = "--all %s" % list_ref elif options_ref == "": options_ref = "%s" % list_ref remote_ref = params.get("remote_ref", "local") if remote_ref == "remote": remote_ip = params.get("remote_ip", "REMOTE.EXAMPLE.COM") remote_pwd = params.get("remote_pwd", None) local_ip = params.get("local_ip", "LOCAL.EXAMPLE.COM") if remote_ip.count("EXAMPLE.COM") or local_ip.count("EXAMPLE.COM"): raise error.TestNAError( "Remote test parameters unchanged from default") logging.info("Execute virsh command on remote host %s.", remote_ip) status, output = list_local_domains_on_remote( options_ref, remote_ip, remote_pwd, local_ip) logging.info("Status:%s", status) logging.info("Output:\n%s", output) else: if vm_ref: options_ref = "%s --%s" % (options_ref, vm_ref) result = virsh.dom_list( options_ref, ignore_status=True, print_info=True) status = result.exit_status output = result.stdout.strip() # Recover libvirtd service status if libvirtd == "off": utils_libvirtd.libvirtd_start() # Recover of domain if vm_ref == "transient": vm.define(tmp_xml) elif vm_ref == "managed-save": # Recover saved guest. virsh.managedsave_remove(vm_name, ignore_status=True, print_info=True) # Check result status_error = (status_error == "no") and (addition_status_error == "no") if vm_ref == "managed-save": saved_output = re.search(vm_name + "\s+saved", output) if saved_output: output = saved_output.group(0) else: output = "" if not status_error: if status == 0 and re.search(result_expected, output): raise error.TestFail("Run successful with wrong command!") else: if status != 0: raise error.TestFail("Run failed with right command.") if not re.search(result_expected, output): raise error.TestFail("Run successful but result is not expected.")
def run(test, params, env): """ Test remote access with TCP, TLS connection """ test_dict = dict(params) pattern = test_dict.get("filter_pattern", "") if ('@LIBVIRT' in pattern and distro.detect().name == 'rhel' and int(distro.detect().version) < 8): test.cancel("The test {} is not supported on current OS({}{}<8.0) as " "the keyword @LIBVIRT is not supported by gnutls on this " "OS.".format(test.name, distro.detect().name, distro.detect().version)) vm_name = test_dict.get("main_vm") status_error = test_dict.get("status_error", "no") allowed_dn_str = params.get("tls_allowed_dn_list") if allowed_dn_str: allowed_dn_list = [] if not libvirt_version.version_compare(1, 0, 0): # Reverse the order in the dn list to workaround the # feature changes between RHEL 6 and RHEL 7 dn_list = allowed_dn_str.split(",") dn_list.reverse() allowed_dn_str = ','.join(dn_list) allowed_dn_list.append(allowed_dn_str) test_dict['tls_allowed_dn_list'] = allowed_dn_list transport = test_dict.get("transport") plus = test_dict.get("conn_plus", "+") config_ipv6 = test_dict.get("config_ipv6", "no") tls_port = test_dict.get("tls_port", "") listen_addr = test_dict.get("listen_addr", "0.0.0.0") ssh_port = test_dict.get("ssh_port", "") tcp_port = test_dict.get("tcp_port", "") server_ip = test_dict.get("server_ip") server_user = test_dict.get("server_user") server_pwd = test_dict.get("server_pwd") no_any_config = params.get("no_any_config", "no") sasl_type = test_dict.get("sasl_type", "gssapi") sasl_user_pwd = test_dict.get("sasl_user_pwd") sasl_allowed_users = test_dict.get("sasl_allowed_users") server_cn = test_dict.get("server_cn") custom_pki_path = test_dict.get("custom_pki_path") rm_client_key_cmd = test_dict.get("remove_client_key_cmd") rm_client_cert_cmd = test_dict.get("remove_client_cert_cmd") ca_cn_new = test_dict.get("ca_cn_new") no_verify = test_dict.get("no_verify", "no") ipv6_addr_des = test_dict.get("ipv6_addr_des") tls_sanity_cert = test_dict.get("tls_sanity_cert") restart_libvirtd = test_dict.get("restart_libvirtd", "yes") diff_virt_ver = test_dict.get("diff_virt_ver", "no") driver = test_dict.get("test_driver", "qemu") uri_path = test_dict.get("uri_path", "/system") virsh_cmd = params.get("virsh_cmd", "list") action = test_dict.get("libvirtd_action", "restart") uri_user = test_dict.get("uri_user", "") uri_aliases = test_dict.get("uri_aliases", "") uri_default = test_dict.get("uri_default", "") unix_sock_dir = test_dict.get("unix_sock_dir") mkdir_cmd = test_dict.get("mkdir_cmd") rmdir_cmd = test_dict.get("rmdir_cmd") adduser_cmd = test_dict.get("adduser_cmd") deluser_cmd = test_dict.get("deluser_cmd") auth_conf = test_dict.get("auth_conf") auth_conf_cxt = test_dict.get("auth_conf_cxt") polkit_pkla = test_dict.get("polkit_pkla") polkit_pkla_cxt = test_dict.get("polkit_pkla_cxt") ssh_setup = test_dict.get("ssh_setup", "no") tcp_setup = test_dict.get("tcp_setup", "no") tls_setup = test_dict.get("tls_setup", "no") unix_setup = test_dict.get("unix_setup", "no") ssh_recovery = test_dict.get("ssh_auto_recovery", "yes") tcp_recovery = test_dict.get("tcp_auto_recovery", "yes") tls_recovery = test_dict.get("tls_auto_recovery", "yes") unix_recovery = test_dict.get("unix_auto_recovery", "yes") sasl_allowed_username_list = test_dict.get("sasl_allowed_username_list") auth_unix_rw = test_dict.get("auth_unix_rw") kinit_pwd = test_dict.get("kinit_pwd") test_alias = test_dict.get("test_alias") config_list = [] port = "" # extra URI arguments extra_params = "" # it's used to clean up SSH, TLS, TCP, UNIX and SASL objs later objs_list = [] # redirect LIBVIRT_DEBUG log into test log later test_dict["logfile"] = test.logfile # Make sure all of parameters are assigned a valid value check_parameters(test_dict, test) # Make sure libvirtd on remote is running server_session = remote.wait_for_login('ssh', server_ip, '22', server_user, server_pwd, r"[\#\$]\s*$") remote_libvirtd = Libvirtd(session=server_session) if not remote_libvirtd.is_running(): logging.debug("start libvirt on remote") res = remote_libvirtd.start() if not res: status, output = server_session.cmd_status_output("journalctl -xe") test.error("Failed to start libvirtd on remote. [status]: %s " "[output]: %s." % (status, output)) server_session.close() if distro.detect().name == 'rhel' and int(distro.detect().version) >= 9: # Update crypto policies to legacy for RHEL>=9 per Bug 1931723 or # https://libguestfs.org/virt-v2v-input-xen.1.html#ssh-authentication crypto_policies = process.run("update-crypto-policies --set LEGACY", ignore_status=False) # only simply connect libvirt daemon then return if no_any_config == "yes": test_dict["uri"] = "%s%s%s://%s" % (driver, plus, transport, uri_path) remote_access(test_dict, test) return # append extra 'pkipath' argument to URI if exists if custom_pki_path: extra_params = "?pkipath=%s" % custom_pki_path # append extra 'no_verify' argument to URI if exists if no_verify == "yes": extra_params = "?no_verify=1" # append extra 'socket' argument to URI if exists if unix_sock_dir: extra_params = "?socket=%s/libvirt-sock" % unix_sock_dir # generate auth.conf and default under the '/etc/libvirt' if auth_conf_cxt and auth_conf: cmd = "echo -e '%s' > %s" % (auth_conf_cxt, auth_conf) process.system(cmd, ignore_status=True, shell=True) # generate polkit_pkla and default under the # '/etc/polkit-1/localauthority/50-local.d/' if polkit_pkla_cxt and polkit_pkla: cmd = "echo -e '%s' > %s" % (polkit_pkla_cxt, polkit_pkla) process.system(cmd, ignore_status=True, shell=True) # generate remote IP if config_ipv6 == "yes" and ipv6_addr_des: remote_ip = "[%s]" % ipv6_addr_des elif config_ipv6 != "yes" and server_cn: remote_ip = server_cn elif config_ipv6 != "yes" and ipv6_addr_des: remote_ip = "[%s]" % ipv6_addr_des elif server_ip and transport != "unix": remote_ip = server_ip else: remote_ip = "" # get URI port if tcp_port != "": port = ":" + tcp_port if tls_port != "": port = ":" + tls_port if ssh_port != "" and not ipv6_addr_des: port = ":" + ssh_port # generate URI uri = "%s%s%s://%s%s%s%s%s" % (driver, plus, transport, uri_user, remote_ip, port, uri_path, extra_params) test_dict["uri"] = uri logging.debug("The final test dict:\n<%s>", test_dict) if virsh_cmd == "start" and transport != "unix": session = remote.wait_for_login("ssh", server_ip, "22", "root", server_pwd, "#") cmd = "virsh domstate %s" % vm_name status, output = session.cmd_status_output(cmd) if status: session.close() test.cancel(output) session.close() try: # setup IPv6 if config_ipv6 == "yes": ipv6_obj = IPv6Manager(test_dict) objs_list.append(ipv6_obj) ipv6_obj.setup() # compare libvirt version if needs if diff_virt_ver == "yes": compare_virt_version(server_ip, server_user, server_pwd, test) # setup SSH if (transport == "ssh" or ssh_setup == "yes") and sasl_type != "plain": if not test_dict.get("auth_pwd"): ssh_obj = SSHConnection(test_dict) if ssh_recovery == "yes": objs_list.append(ssh_obj) # setup test environment ssh_obj.conn_setup() else: # To access to server with password, # cleanup authorized_keys on remote ssh_pubkey_file = "/root/.ssh/id_rsa.pub" if (os.path.exists("/root/.ssh/id_rsa") and os.path.exists(ssh_pubkey_file)): remote_file_obj = remote.RemoteFile(address=server_ip, client='scp', username=server_user, password=server_pwd, port='22', remote_path="/root/.ssh/authorized_keys") with open(ssh_pubkey_file, 'r') as fd: line = fd.read().split()[-1].rstrip('\n') line = ".*" + line remote_file_obj.remove([line]) objs_list.append(remote_file_obj) # setup TLS if transport == "tls" or tls_setup == "yes": tls_obj = TLSConnection(test_dict) if tls_recovery == "yes": objs_list.append(tls_obj) # reserve cert path tmp_dir = tls_obj.tmp_dir # setup test environment tls_obj.conn_setup() # setup TCP if transport == "tcp" or tcp_setup == "yes": tcp_obj = TCPConnection(test_dict) if tcp_recovery == "yes": objs_list.append(tcp_obj) # setup test environment tcp_obj.conn_setup() # create a directory if needs if mkdir_cmd: process.system(mkdir_cmd, ignore_status=True, shell=True) # setup UNIX if transport == "unix" or unix_setup == "yes" or sasl_type == "plain": unix_obj = UNIXConnection(test_dict) if unix_recovery == "yes": objs_list.append(unix_obj) # setup test environment unix_obj.conn_setup() # need to restart libvirt service for negative testing if restart_libvirtd == "no": remotely_control_libvirtd(server_ip, server_user, server_pwd, action, status_error) # check TCP/IP listening by service if restart_libvirtd != "no" and transport != "unix": service = 'libvirtd' if transport == "ssh": service = 'ssh' check_listening_port_remote_by_service(server_ip, server_user, server_pwd, service, port, listen_addr) # open the tls/tcp listening port on server if transport in ["tls", "tcp"]: firewalld_port = port[1:] server_session = remote.wait_for_login('ssh', server_ip, '22', server_user, server_pwd, r"[\#\$]\s*$") firewall_cmd = utils_iptables.Firewall_cmd(server_session) firewall_cmd.add_port(firewalld_port, 'tcp', permanent=True) server_session.close() if 'inv_transport' in test_dict: transport = test_dict['inv_transport'] uri = "%s%s%s://%s%s%s%s%s" % (driver, plus, transport, uri_user, remote_ip, port, uri_path, extra_params) test_dict["uri"] = uri config_list = [] if uri_aliases: uri_config = change_libvirtconf_on_client( {'uri_aliases': uri_aliases}) config_list.append(uri_config) test_dict["uri"] = test_alias if uri_default: test_dict["uri"] = "" # Delete the default URI environment variable to prevent overriding del os.environ['LIBVIRT_DEFAULT_URI'] uri_config = change_libvirtconf_on_client( {'uri_default': uri_default}) config_list.append(uri_config) ret = virsh.command('uri', debug=True) if uri_default.strip('"') in ret.stdout_text: logging.debug("Virsh output as expected.") else: test.fail("Expected virsh output: {} not found in:{}".format( uri_default.strip('"'), ret.stdout_text)) # remove client certifications if exist, only for TLS negative testing if rm_client_key_cmd: process.system(rm_client_key_cmd, ignore_status=True, shell=True) if rm_client_cert_cmd: process.system(rm_client_cert_cmd, ignore_status=True, shell=True) # add user to specific group if adduser_cmd: process.system(adduser_cmd, ignore_status=True, shell=True) # change /etc/pki/libvirt/servercert.pem then # restart libvirt service on the remote host if tls_sanity_cert == "no" and ca_cn_new: test_dict['ca_cn'] = ca_cn_new test_dict['scp_new_cacert'] = 'no' tls_obj_new = TLSConnection(test_dict) test_dict['tls_obj_new'] = tls_obj_new # only setup new CA and server tls_obj_new.conn_setup(True, False) # obtain and cache a ticket if kinit_pwd and sasl_type == 'gssapi' and auth_unix_rw == 'sasl': username_list = json.loads(sasl_allowed_username_list) for username in username_list: kinit_cmd = "echo '%s' | kinit %s" % (kinit_pwd, username) process.system(kinit_cmd, ignore_status=True, shell=True) # setup SASL certification # From libvirt-3.2.0, the default sasl change from # DIGEST-MD5 to GSSAPI. "sasl_user" is discarded. # More details: https://libvirt.org/auth.html#ACL_server_kerberos if sasl_user_pwd and sasl_type in ['digest-md5', 'plain']: # covert string tuple and list to python data type sasl_user_pwd = eval(sasl_user_pwd) if sasl_allowed_users: sasl_allowed_users = eval(sasl_allowed_users) # create a sasl user sasl_obj = SASL(test_dict) objs_list.append(sasl_obj) sasl_obj.setup() for sasl_user, sasl_pwd in sasl_user_pwd: # need't authentication if the auth.conf is configured by user if not auth_conf: if sasl_type == 'plain': test_dict["auth_pwd"] = server_pwd pass else: test_dict["auth_user"] = sasl_user test_dict["auth_pwd"] = sasl_pwd logging.debug("sasl_user, sasl_pwd = " "(%s, %s)", sasl_user, sasl_pwd) if sasl_allowed_users and sasl_user not in sasl_allowed_users: test_dict["status_error"] = "yes" patterns_extra_dict = {"authentication name": sasl_user, "enter your password": sasl_pwd} test_dict["patterns_extra_dict"] = patterns_extra_dict remote_access(test_dict, test) else: if not uri_default: remote_access(test_dict, test) finally: # recovery test environment # Destroy the VM after all test are done for config in config_list: restore_libvirtconf_on_client(config) cleanup(objs_list) if vm_name: vm = env.get_vm(vm_name) if vm and vm.is_alive(): vm.destroy(gracefully=False) if transport in ["tcp", "tls"] and 'firewalld_port' in locals(): server_session = remote.wait_for_login('ssh', server_ip, '22', server_user, server_pwd, r"[\#\$]\s*$") firewall_cmd = utils_iptables.Firewall_cmd(server_session) firewall_cmd.remove_port(firewalld_port, 'tcp', permanent=True) server_session.close() if rmdir_cmd: process.system(rmdir_cmd, ignore_status=True, shell=True) if deluser_cmd: process.system(deluser_cmd, ignore_status=True, shell=True) if auth_conf and os.path.isfile(auth_conf): os.unlink(auth_conf) if polkit_pkla and os.path.isfile(polkit_pkla): os.unlink(polkit_pkla)
try: trimmed_bytes = re.search("\d+\sbytes", output).group(0).split()[0] trimmed = int(trimmed_bytes) logging.debug("Trimmed size is:%s bytes", trimmed) except (AttributeError, IndexError), detail: raise error.TestFail("Do fstrim failed:%s" % detail) if trimmed == 0: raise error.TestFail("Trimmed size is 0.") elif fstrim_type == "mount_with_discard": pass elif fstrim_type == "qemu-guest-agent": cmd = ("qemu-agent-command %s '{\"execute\":\"guest-fstrim\"}'" % vm.name) try: virsh.command(cmd, debug=True, ignore_status=False) except error.CmdError: raise error.TestFail("Execute qemu-agent-command failed.") def run(test, params, env): """ DiskXML has an attribute named discard for fstrim operations. (Only supported after special libvirt version.) These are test cases for it: """ vm_name = params.get("main_vm", "virt-tests-vm1") vm = env.get_vm(vm_name) if vm.is_dead(): vm.start() vm.wait_for_login()
raise error.TestFail("Not supported fstrim on supported " "envrionment.Bug?") try: trimmed = int(re.search("\d+", output).group(0)) logging.debug("Trimmed size is:%s", trimmed / 1024 / 1024) except (AttributeError, IndexError), detail: raise error.TestFail("Do fstrim failed:%s" % detail) if trimmed == 0: raise error.TestFail("Trimmed size is 0.") elif fstrim_type == "mount_with_discard": pass elif fstrim_type == "qemu-guest-agent": cmd = ("qemu-agent-command %s '{\"execute\":\"guest-fstrim\"}'" % vm.name) try: virsh.command(cmd, debug=True, ignore_status=False) except error.CmdError: raise error.TestFail("Execute qemu-agent-command failed.") def run(test, params, env): """ DiskXML has an attribute named discard for fstrim operations. (Only supported after special libvirt version.) These are test cases for it: """ vm_name = params.get("main_vm", "virt-tests-vm1") vm = env.get_vm(vm_name) if vm.is_dead(): vm.start() vm.wait_for_login()