def run(test, params, env): """ Test command: virsh managedsave. This command can save and destroy a running domain, so it can be restarted from the same state at a later time. """ vm_name = params.get("main_vm") vm = env.get_vm(vm_name) managed_save_file = "/var/lib/libvirt/qemu/save/%s.save" % vm_name shutdown_timeout = int(params.get('shutdown_timeout', 60)) # define function def vm_recover_check(option, libvirtd, check_shutdown=False): """ Check if the vm can be recovered correctly. :param guest_name : Checked vm's name. :param option : managedsave command option. """ # This time vm not be shut down if vm.is_alive(): test.fail("Guest should be inactive") # Check vm managed save state. ret = virsh.dom_list("--managed-save --inactive", debug=True) vm_state1 = re.findall(r".*%s.*" % vm_name, ret.stdout.strip())[0].split()[2] ret = virsh.dom_list("--managed-save --all", debug=True) vm_state2 = re.findall(r".*%s.*" % vm_name, ret.stdout.strip())[0].split()[2] if vm_state1 != "saved" or vm_state2 != "saved": test.fail("Guest state should be saved") virsh.start(vm_name, debug=True) # This time vm should be in the list if vm.is_dead(): test.fail("Guest should be active") # Restart libvirtd and check vm status again. libvirtd.restart() if vm.is_dead(): test.fail("Guest should be active after" " restarting libvirtd") # Check managed save file: if os.path.exists(managed_save_file): test.fail("Managed save image exist " "after starting the domain") if option: if option.count("running"): if vm.is_dead() or vm.is_paused(): test.fail("Guest state should be" " running after started" " because of '--running' option") elif option.count("paused"): if not vm.is_paused(): test.fail("Guest state should be" " paused after started" " because of '--paused' option") else: if params.get("paused_after_start_vm") == "yes": if not vm.is_paused(): test.fail("Guest state should be" " paused after started" " because of initia guest state") if check_shutdown: # Resume the domain. if vm.is_paused(): vm.resume() vm.wait_for_login() # Shutdown and start the domain, # it should be in runing state and can be login. vm.shutdown() if not vm.wait_for_shutdown(shutdown_timeout): test.fail('VM failed to shutdown') vm.start() vm.wait_for_login() def vm_undefine_check(vm_name): """ Check if vm can be undefined with manage-save option """ #backup xml file xml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) if not os.path.exists(managed_save_file): test.fail("Can't find managed save image") #undefine domain with no options. if not virsh.undefine(vm_name, options=None, ignore_status=True).exit_status: test.fail("Guest shouldn't be undefined" "while domain managed save image exists") #undefine domain with managed-save option. if virsh.undefine(vm_name, options="--managed-save", ignore_status=True).exit_status: test.fail("Guest can't be undefine with " "managed-save option") if os.path.exists(managed_save_file): test.fail("Managed save image exists" " after undefining vm") #restore and start the vm. xml_backup.define() vm.start() def check_flags_parallel(virsh_cmd, bash_cmd, flags): """ Run the commands parallel and check the output. """ cmd = ("%s & %s" % (virsh_cmd, bash_cmd)) ret = process.run(cmd, ignore_status=True, shell=True, ignore_bg_processes=True) output = ret.stdout_text.strip() logging.debug("check flags output: %s" % output) lines = re.findall(r"flags:.(\d+)", output, re.M) logging.debug("Find all fdinfo flags: %s" % lines) lines = [int(i, 8) & flags for i in lines] if flags not in lines: test.fail("Checking flags %s failed" % flags) return ret def check_multi_guests(guests, start_delay, libvirt_guests): """ Check start_delay option for multiple guests. """ # Destroy vm first if vm.is_alive(): vm.destroy(gracefully=False) # Clone given number of guests timeout = params.get("clone_timeout", 360) for i in range(int(guests)): dst_vm = "%s_%s" % (vm_name, i) utils_libguestfs.virt_clone_cmd(vm_name, dst_vm, True, timeout=timeout) virsh.start(dst_vm, debug=True) # Wait 10 seconds for vm to start time.sleep(10) is_systemd = process.run("cat /proc/1/comm", shell=True).stdout_text.count("systemd") if is_systemd: libvirt_guests.restart() pattern = r'(.+ \d\d:\d\d:\d\d).+: Resuming guest.+done' else: ret = process.run("service libvirt-guests restart | \ awk '{ print strftime(\"%b %y %H:%M:%S\"), \ $0; fflush(); }'", shell=True) pattern = r'(.+ \d\d:\d\d:\d\d)+ Resuming guest.+done' # libvirt-guests status command read messages from systemd # journal, in cases of messages are not ready in time, # add a time wait here. def wait_func(): return libvirt_guests.raw_status().stdout.count("Resuming guest") utils_misc.wait_for(wait_func, 5) if is_systemd: ret = libvirt_guests.raw_status() logging.info("status output: %s", ret.stdout_text) resume_time = re.findall(pattern, ret.stdout_text, re.M) if not resume_time: test.fail("Can't see messages of resuming guest") # Convert time string to int resume_seconds = [ time.mktime(time.strptime(tm, "%b %y %H:%M:%S")) for tm in resume_time ] logging.info("Resume time in seconds: %s", resume_seconds) # Check if start_delay take effect for i in range(len(resume_seconds) - 1): if resume_seconds[i + 1] - resume_seconds[i] < int(start_delay): test.fail("Checking start_delay failed") def wait_for_state(vm_state): """ Wait for vm state is ready. """ utils_misc.wait_for(lambda: vm.state() == vm_state, 10) def check_guest_flags(bash_cmd, flags): """ Check bypass_cache option for single guest. """ # Drop caches. drop_caches() # form proper parallel command based on if systemd is used or not is_systemd = process.run("cat /proc/1/comm", shell=True).stdout_text.count("systemd") if is_systemd: virsh_cmd_stop = "systemctl stop libvirt-guests" virsh_cmd_start = "systemctl start libvirt-guests" else: virsh_cmd_stop = "service libvirt-guests stop" virsh_cmd_start = "service libvirt-guests start" ret = check_flags_parallel( virsh_cmd_stop, bash_cmd % (managed_save_file, managed_save_file, "1"), flags) if is_systemd: ret = libvirt_guests.raw_status() logging.info("status output: %s", ret.stdout_text) if all([ "Suspending %s" % vm_name not in ret.stdout_text, "stopped, with saved guests" not in ret.stdout_text ]): test.fail("Can't see messages of suspending vm") # status command should return 3. if not is_systemd: ret = libvirt_guests.raw_status() if ret.exit_status != 3: test.fail("The exit code %s for libvirt-guests" " status is not correct" % ret) # Wait for VM in shut off state wait_for_state("shut off") check_flags_parallel( virsh_cmd_start, bash_cmd % (managed_save_file, managed_save_file, "0"), flags) # Wait for VM in running state wait_for_state("running") def vm_msave_remove_check(vm_name): """ Check managed save remove command. """ if not os.path.exists(managed_save_file): test.fail("Can't find managed save image") virsh.managedsave_remove(vm_name, debug=True) if os.path.exists(managed_save_file): test.fail("Managed save image still exists") virsh.start(vm_name, debug=True) # The domain state should be running if vm.state() != "running": test.fail("Guest state should be" " running after started") def vm_managedsave_loop(vm_name, loop_range, libvirtd): """ Run a loop of managedsave command and check its result. """ if vm.is_dead(): virsh.start(vm_name, debug=True) for i in range(int(loop_range)): logging.debug("Test loop: %s" % i) virsh.managedsave(vm_name, debug=True) virsh.start(vm_name, debug=True) # Check libvirtd status. if not libvirtd.is_running(): test.fail("libvirtd is stopped after cmd") # Check vm status. if vm.state() != "running": test.fail("Guest isn't in running state") def build_vm_xml(vm_name, **dargs): """ Build the new domain xml and define it. """ try: # stop vm before doing any change to xml if vm.is_alive(): vm.destroy(gracefully=False) vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) if dargs.get("cpu_mode"): if "cpu" in vmxml: del vmxml.cpu cpuxml = vm_xml.VMCPUXML() cpuxml.mode = params.get("cpu_mode", "host-model") cpuxml.match = params.get("cpu_match", "exact") cpuxml.fallback = params.get("cpu_fallback", "forbid") cpu_topology = {} cpu_topology_sockets = params.get("cpu_topology_sockets") if cpu_topology_sockets: cpu_topology["sockets"] = cpu_topology_sockets cpu_topology_cores = params.get("cpu_topology_cores") if cpu_topology_cores: cpu_topology["cores"] = cpu_topology_cores cpu_topology_threads = params.get("cpu_topology_threads") if cpu_topology_threads: cpu_topology["threads"] = cpu_topology_threads if cpu_topology: cpuxml.topology = cpu_topology vmxml.cpu = cpuxml vmxml.vcpu = int(params.get("vcpu_nums")) if dargs.get("sec_driver"): seclabel_dict = { "type": "dynamic", "model": "selinux", "relabel": "yes" } vmxml.set_seclabel([seclabel_dict]) vmxml.sync() vm.start() except Exception as e: logging.error(str(e)) test.cancel("Build domain xml failed") status_error = ("yes" == params.get("status_error", "no")) vm_ref = params.get("managedsave_vm_ref", "name") libvirtd_state = params.get("libvirtd", "on") extra_param = params.get("managedsave_extra_param", "") progress = ("yes" == params.get("managedsave_progress", "no")) cpu_mode = "yes" == params.get("managedsave_cpumode", "no") test_undefine = "yes" == params.get("managedsave_undefine", "no") test_bypass_cache = "yes" == params.get("test_bypass_cache", "no") autostart_bypass_cache = params.get("autostart_bypass_cache", "") multi_guests = params.get("multi_guests", "") test_libvirt_guests = params.get("test_libvirt_guests", "") check_flags = "yes" == params.get("check_flags", "no") security_driver = params.get("security_driver", "") remove_after_cmd = "yes" == params.get("remove_after_cmd", "no") option = params.get("managedsave_option", "") check_shutdown = "yes" == params.get("shutdown_after_cmd", "no") pre_vm_state = params.get("pre_vm_state", "") move_saved_file = "yes" == params.get("move_saved_file", "no") test_loop_cmd = "yes" == params.get("test_loop_cmd", "no") if option: if not virsh.has_command_help_match('managedsave', option): # Older libvirt does not have this option test.cancel("Older libvirt does not" " handle arguments consistently") # Backup xml file. vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) # Get the libvirtd service libvirtd = utils_libvirtd.Libvirtd() # Get config files. qemu_config = utils_config.LibvirtQemuConfig() libvirt_guests_config = utils_config.LibvirtGuestsConfig() # Get libvirt-guests service libvirt_guests = Factory.create_service("libvirt-guests") try: # Destroy vm first for setting configuration file if vm.state() == "running": vm.destroy(gracefully=False) # Prepare test environment. if libvirtd_state == "off": libvirtd.stop() if autostart_bypass_cache: ret = virsh.autostart(vm_name, "", ignore_status=True, debug=True) libvirt.check_exit_status(ret) qemu_config.auto_start_bypass_cache = autostart_bypass_cache libvirtd.restart() if security_driver: qemu_config.security_driver = [security_driver] if test_libvirt_guests: if multi_guests: start_delay = params.get("start_delay", "20") libvirt_guests_config.START_DELAY = start_delay if check_flags: libvirt_guests_config.BYPASS_CACHE = "1" # The config file format should be "x=y" instead of "x = y" process.run( "sed -i -e 's/ = /=/g' " "/etc/sysconfig/libvirt-guests", shell=True) libvirt_guests.restart() # Change domain xml. if cpu_mode: build_vm_xml(vm_name, cpu_mode=True) if security_driver: build_vm_xml(vm_name, sec_driver=True) # Turn VM into certain state. if pre_vm_state == "transient": logging.info("Creating %s..." % vm_name) vmxml_for_test = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) if vm.is_alive(): vm.destroy(gracefully=False) # Wait for VM to be in shut off state utils_misc.wait_for(lambda: vm.state() == "shut off", 10) vm.undefine() if virsh.create(vmxml_for_test.xml, ignore_status=True, debug=True).exit_status: vmxml_backup.define() test.cancel("Cann't create the domain") # Wait for vm in stable state if params.get("start_vm") == "yes": if vm.state() == "shut off": vm.start() vm.wait_for_login() # run test case domid = vm.get_id() domuuid = vm.get_uuid() if vm_ref == "id": vm_ref = domid elif vm_ref == "uuid": vm_ref = domuuid elif vm_ref == "hex_id": vm_ref = hex(int(domid)) elif vm_ref.count("invalid"): vm_ref = params.get(vm_ref) elif vm_ref == "name": vm_ref = vm_name # Ignore exception with "ignore_status=True" if progress: option += " --verbose" option += extra_param # For bypass_cache test. Run a shell command to check fd flags while # excuting managedsave command software_mgr = software_manager.SoftwareManager() if not software_mgr.check_installed('lsof'): logging.info('Installing lsof package:') software_mgr.install('lsof') bash_cmd = ( "let i=1; while((i++<400)); do if [ -e %s ]; then (cat /proc" "/$(lsof -w %s|awk '/libvirt_i/{print $2}')/fdinfo/%s |" "grep 'flags:.*') && break; else sleep 0.05; fi; done;") # Flags to check bypass cache take effect flags = os.O_DIRECT if test_bypass_cache: # Drop caches. drop_caches() virsh_cmd = "virsh managedsave %s %s" % (option, vm_name) check_flags_parallel( virsh_cmd, bash_cmd % (managed_save_file, managed_save_file, "1"), flags) # Wait for VM in shut off state wait_for_state("shut off") virsh_cmd = "virsh start %s %s" % (option, vm_name) check_flags_parallel( virsh_cmd, bash_cmd % (managed_save_file, managed_save_file, "0"), flags) # Wait for VM in running state wait_for_state("running") elif test_libvirt_guests: logging.debug("libvirt-guests status: %s", libvirt_guests.status()) if multi_guests: check_multi_guests(multi_guests, start_delay, libvirt_guests) if check_flags: check_guest_flags(bash_cmd, flags) else: # Ensure VM is running utils_misc.wait_for(lambda: vm.state() == "running", 10) ret = virsh.managedsave(vm_ref, options=option, ignore_status=True, debug=True) status = ret.exit_status # The progress information outputed in error message error_msg = ret.stderr.strip() if move_saved_file: cmd = "echo > %s" % managed_save_file process.run(cmd, shell=True) # recover libvirtd service start if libvirtd_state == "off": libvirtd.start() if status_error: if not status: if libvirtd_state == "off" and libvirt_version.version_compare( 5, 6, 0): logging.info( "From libvirt version 5.6.0 libvirtd is restarted " "and command should succeed") else: test.fail("Run successfully with wrong command!") else: if status: test.fail("Run failed with right command") if progress: if not error_msg.count("Managedsave:"): test.fail("Got invalid progress output") if remove_after_cmd: vm_msave_remove_check(vm_name) elif test_undefine: vm_undefine_check(vm_name) elif autostart_bypass_cache: # rhbz#1755303 if libvirt_version.version_compare(5, 6, 0): os.remove("/run/libvirt/qemu/autostarted") libvirtd.stop() virsh_cmd = ("(service libvirtd start)") check_flags_parallel( virsh_cmd, bash_cmd % (managed_save_file, managed_save_file, "0"), flags) elif test_loop_cmd: loop_range = params.get("loop_range", "20") vm_managedsave_loop(vm_name, loop_range, libvirtd) else: vm_recover_check(option, libvirtd, check_shutdown) finally: # Restore test environment. # Restart libvirtd.service qemu_config.restore() libvirt_guests_config.restore() libvirtd.restart() if autostart_bypass_cache: virsh.autostart(vm_name, "--disable", ignore_status=True, debug=True) vm.destroy(gracefully=False) virsh.managedsave_remove(vm_name, debug=True) vmxml_backup.sync() if multi_guests: for i in range(int(multi_guests)): virsh.remove_domain("%s_%s" % (vm_name, i), "--remove-all-storage", debug=True)
def run(test, params, env): """ Configuring /etc/sysconfig/libvirt-guests, then check the domains status after restarting the libvirt-guests.server, 1. Set the values in /etc/sysconfig/libvirt-guests 2. Restart libvirt-guests service 3. Check the domains states, and the guests' save files """ def get_log(): """ Tail output appended data as the file /var/log/messages grows :returns: the appended data tailed from /var/log/messages """ tailed_log_file = os.path.join(data_dir.get_tmp_dir(), 'tail_log') tailed_messages = aexpect.Tail(command='tail -f /var/log/messages', output_func=utils_misc.log_line, output_params=(tailed_log_file)) return tailed_messages def chk_on_shutdown(status_error, on_shutdown, parallel_shutdown, output): """ check domains' state when host shutdown, and if parallel_shutdown is set to non-zero, check whether the guests have been shutdown correctly. :param status_error: positive test if status_error is "no", otherwise negative test :param on_shutdown: action taking on host shutdown :param parallel_shutdown: the number of parallel_shutdown guests would be shutdown concurrently on shutdown :param output: appended message from /var/log/messages """ if on_shutdown == "shutdown" and on_boot == "start": second_boot_time = boot_time() logging.debug("The second boot time is %s", second_boot_time) if any([i >= j for i, j in zip(first_boot_time, second_boot_time)]): test.fail("The second boot time for should be larger" "than its first boot time.") expect_msg = expect_shutdown_msg(status_error, on_shutdown) logging.debug("The expected messages when host shutdown is: %s ", expect_msg) for dom in vms: if not re.search(expect_msg[dom.name], output): logging.debug("expect_mesg is: %s", expect_msg[dom.name]) if status_error == "no": test.fail("guest should be %s on shutdown" % on_shutdown) else: test.fail("Shutdown of guest should be failed to " "complete in time") if (on_shutdown == "shutdown") and int(parallel_shutdown) > 0: chk_parallel_shutdown(output, parallel_shutdown) def chk_on_boot(status_error, on_boot): """ check domains' state when host booted :param status_error: positive test if status_error is "no", otherwise negative test :param on_boot: action taking on host booting """ if status_error == "no": if on_boot == "start": for dom in vms: if not dom.is_alive(): test.fail("Since on_boot is setting to 'start', " "guest should be running after " "restarting libvirt-guests.") else: for dom in vms: if dom.is_alive(): test.fail("Since on_boot is setting to 'ignore', " "unless guests are autostart, " "guest should be shut off after " "restarting libvirt-guests, ") def check_on_shutdown_vm_status(): for dom in vms: result = virsh.domstate(dom.name, "--reason") try: dom.wait_for_shutdown() except Exception as e: test.fail('As on_boot is set to "ignore", but guest %s is ' 'not shutdown. reason: %s ' % (dom.name, e)) def chk_parallel_shutdown(output, parallel_shutdown): """ check whether the guests has been shut down concurrently on host shutdown. """ pattern = r".+ libvirt-guests.sh.*: Starting shutdown on guest: .+" shut_start_line_nums = [] for line_num, line in enumerate(output.splitlines()): if re.search(pattern, line): shut_start_line_nums.append(line_num) logging.debug("the line_numbers contains shutdown messages is: %s ", shut_start_line_nums) pattern = r".+ libvirt-guests.sh.*: Shutdown of guest.+complete" for line_num, line in enumerate(output.splitlines()): if re.search(pattern, line): shut_complete_first_line = line_num break logging.debug( "the first line contains shutdown complete messages is: %s ", shut_complete_first_line) para_shut = int(parallel_shutdown) if shut_start_line_nums[para_shut - 1] > shut_complete_first_line: test.fail("Since parallel_shutdown is setting to non_zero, " "%s guests should be shutdown concurrently." % parallel_shutdown) if shut_start_line_nums[para_shut] < shut_complete_first_line: test.fail("The number of guests shutdown concurrently " "should not be exceeded than %s." % parallel_shutdown) def expect_shutdown_msg(status_error, on_shutdown): """ the expected messages of each guests when host shutdown logged into /var/log/messages """ expect_msg = {} for dom in vms: if status_error == "no": if on_shutdown == "shutdown": expect_msg[dom.name] = ("libvirt-guests.sh.*: " "Shutdown of guest %s " "complete" % dom.name) else: expect_msg[dom.name] = ("libvirt-guests.sh.*: " "Suspending %s: done" % dom.name) else: # Now the negative tests are only about ON_SHUTDOWN=shutdown. if on_shutdown == "shutdown": expect_msg[dom.name] = ("libvirt-guests.sh.*: " "Shutdown of guest %s " "failed to complete in " "time" % dom.name) return expect_msg def chk_save_files(status_error, on_shutdown, on_boot): """ save files should exist when on_shutdown is set to shutdown, and on_boot is set to ignore. In other conditions, there should be no save files. """ save_files = dict() for dom in vms: save_files[dom] = ("/var/lib/libvirt/qemu/save/%s.save" % dom.name) if status_error == "no": if on_shutdown == "shutdown": for dom in vms: if os.path.exists(save_files[dom]): test.fail("There should be no save files since " "guests are shutdown on host shutdown.") else: if on_boot == "start": for dom in vms: if os.path.exists(save_files[dom]): test.fail("There should be no save files since " "guests are restored on host shutdown.") else: for dom in vms: if not os.path.exists(save_files[dom]): test.fail("Guests are suspended on host shutdown, " "and been ignored on host boot, there " "should be save files for the guests.") def boot_time(): booting_time = [] for vm in vms: session = vm.wait_for_login() time = session.cmd_output("uptime --since") booting_time.append(time) session.close() return booting_time def setup_nfs_backend_guest(vmxml_backup): # nfs_server setup nfs_server = libvirt.setup_or_cleanup_nfs(True) nfs_export_dir = nfs_server['export_dir'] logging.debug("nfs dir is %s", nfs_export_dir) # change the original xml and image path for dom in vms: vmxml = vm_xml.VMXML.new_from_dumpxml(dom.name) vmxml_backup.append(vmxml.copy()) disk_xml = vmxml.get_devices(device_type="disk")[0] orig_image_path_name = disk_xml.source.attrs['file'] libvirt.update_vm_disk_source(dom.name, nfs_export_dir) shutil.copy(orig_image_path_name, nfs_export_dir) # set the selinux bool if virt_use_nfs: result = process.run("setsebool virt_use_nfs 1", shell=True, verbose=True) if result.exit_status: logging.error("Failed to set virt_use_nfs on") def cleanup_nfs_backend_guest(vmxml_backup): if virt_use_nfs: result = process.run("setsebool virt_use_nfs 0", shell=True, verbose=True) if result.exit_status: logging.error("Failed to set virt_use_nfs off") # recover the guest xml for xml_backup in vmxml_backup: xml_backup.sync(options="--managed-save") nfs_server = libvirt.setup_or_cleanup_nfs(False) main_vm_name = params.get("main_vm") main_vm = env.get_vm(main_vm_name) on_boot = params.get("on_boot") on_shutdown = params.get("on_shutdown") nfs_vol = params.get("nfs_vol") == "yes" virt_use_nfs = params.get("virt_use_nfs") == "on" parallel_shutdown = params.get("parallel_shutdown") additional_vms = int(params.get("additional_vms", "0")) status_error = params.get("status_error") shutdown_timeout = params.get("shutdown_timeout", "300") config = utils_config.LibvirtGuestsConfig() libvirt_guests_service = service.Factory.create_service("libvirt-guests") if not libvirt_guests_service.status(): libvirt_guests_service.start() vms = [main_vm] if main_vm.is_alive: main_vm.destroy(gracefully=False) if not utils_misc.start_rsyslogd(): test.error("Rsyslogd service start fail") try: utils_path.find_command("virt-clone") except utils_path.CmdNotFoundError: test.cancel("No virt-clone command found.") # Clone additional vms: avocado-vt-vm2, avocado-vt-vm3..... for i in range(additional_vms): guest_name = ("%s" % main_vm_name[:-1]) + ("%s" % str(i + 2)) logging.debug("guest_name : %s", guest_name) utils_libguestfs.virt_clone_cmd(main_vm_name, guest_name, True, timeout=360, ignore_status=False) vms.append(main_vm.clone(guest_name)) logging.debug("Now the vms is: %s", [dom.name for dom in vms]) if nfs_vol: # info collected for clear env finally vmxml_backup = [] setup_nfs_backend_guest(vmxml_backup) for dom in vms: if not dom.is_alive(): dom.start() for dom in vms: dom.wait_for_login() first_boot_time = [] if on_shutdown == "shutdown" and on_boot == "start": first_boot_time = boot_time() logging.debug("The first boot time is %s", first_boot_time) try: # Config the libvirt-guests file config.ON_BOOT = on_boot config.ON_SHUTDOWN = on_shutdown config.PARALLEL_SHUTDOWN = parallel_shutdown config.SHUTDOWN_TIMEOUT = shutdown_timeout process.run("sed -i -e 's/ = /=/g' " "/etc/sysconfig/libvirt-guests", shell=True) tail_messages = get_log() # Even though libvirt-guests was designed to operate guests when # host shutdown. The purpose can also be fulfilled by restart the # libvirt-guests service. libvirt_guests_service.restart() time.sleep(10) output = tail_messages.get_output() logging.debug("Get messages in /var/log/messages: %s" % output) # check the guests state when host shutdown chk_on_shutdown(status_error, on_shutdown, parallel_shutdown, output) # check the guests state when host rebooted chk_on_boot(status_error, on_boot) # check the guests save files chk_save_files(status_error, on_shutdown, on_boot) if on_boot == "ignore" and on_shutdown == "shutdown": check_on_shutdown_vm_status() finally: config.restore() # Undefine additional vms for dom in vms[1:]: if dom.is_alive(): dom.destroy(gracefully=False) virsh.remove_domain(dom.name, "--remove-all-storage") if nfs_vol: cleanup_nfs_backend_guest(vmxml_backup) if libvirt_guests_service.status(): libvirt_guests_service.stop()
pre_vm_state = params.get("pre_vm_state", "") move_saved_file = "yes" == params.get("move_saved_file", "no") test_loop_cmd = "yes" == params.get("test_loop_cmd", "no") if option: if not virsh.has_command_help_match('managedsave', option): # Older libvirt does not have this option raise error.TestNAError("Older libvirt does not" " handle arguments consistently") # Backup xml file. vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) # Get the libvirtd service libvirtd = utils_libvirtd.Libvirtd() # Get config files. qemu_config = utils_config.LibvirtQemuConfig() libvirt_guests_config = utils_config.LibvirtGuestsConfig() # Get libvirt-guests service libvirt_guests = Factory.create_service("libvirt-guests") try: # Destroy vm first for setting configuration file if vm.state() == "running": vm.destroy(gracefully=False) # Prepare test environment. if libvirtd_state == "off": libvirtd.stop() if autostart_bypass_cache: ret = virsh.autostart(vm_name, "", ignore_status=True) libvirt.check_exit_status(ret) qemu_config.auto_start_bypass_cache = autostart_bypass_cache libvirtd.restart()
def run(test, params, env): """ Configuring /etc/sysconfig/libvirt-guests, then check the domains status after restarting the libvirt-guests.server, 1. Set the values in /etc/sysconfig/libvirt-guests 2. Restart libvirt-guests service 3. Check the domains states, and the guests' save files """ def get_log(): """ Tail output appended data as the file /var/log/messages grows :returns: the appended data tailed from /var/log/messages """ tailed_log_file = os.path.join(data_dir.get_tmp_dir(), 'tail_log') tailed_messages = aexpect.Tail(command='tail -f /var/log/messages', output_func=utils_misc.log_line, output_params=(tailed_log_file)) return tailed_messages def chk_on_shutdown(status_error, on_shutdown, parallel_shutdown, output): """ check domains' state when host shutdown, and if parallel_shutdown is set to non-zero, check whether the guests have been shutdown corretly. :param status_error: positive test if status_error is "no", otherwise negative test :param on_shutdown: action taking on host shutdown :param parallel_shutdown: the number of parallel_shutdown guests would be shutdown concurrently on shutdown :param output: apppended message from /var/log/messages """ expect_msg = expect_shutdown_msg(status_error, on_shutdown) logging.debug("The expected messages when host shutdown is: %s ", expect_msg) for dom in vms: if not expect_msg[dom.name] in output: logging.debug("expect_mesg is: %s", expect_msg[dom.name]) if status_error == "no": test.fail("guest should be %s on shutdown" % on_shutdown) else: test.fail("Shutdown of guest should be failed to " "complete in time") if (on_shutdown == "shutdown") and int(parallel_shutdown) > 0: chk_parallel_shutdown(output, parallel_shutdown) def chk_on_boot(status_error, on_boot): """ check domains' state when host booted :param status_error: positive test if status_error is "no", otherwise negative test :param on_boot: action taking on host booting """ if status_error == "no": if on_boot == "start": for dom in vms: if not dom.is_alive(): test.fail("Since on_boot is setting to 'start', " "guest should be running after " "restarting libvirt-guests.") else: for dom in vms: if dom.is_alive(): test.fail("Since on_boot is setting to 'ignore', " "unless guests are autostart, " "guest should be shut off after " "restarting libvirt-guests, ") def check_on_shutdown_vm_status(): for dom in vms: result = virsh.domstate(dom.name, "--reason") try: dom.wait_for_shutdown() except Exception as e: test.fail('As on_boot is set to "ignore", but guest %s is ' 'not shutdown. reason: %s ' % (dom.name, e)) def chk_parallel_shutdown(output, parallel_shutdown): """ check whether the guests has been shut down concurrently on host shutdown. """ pattern = r".+ libvirt-guests.sh: Starting shutdown on guest: .+" shut_start_line_nums = [] for line_num, line in enumerate(output.splitlines()): if re.search(pattern, line): shut_start_line_nums.append(line_num) logging.debug("the line_numbers contains shutdown messages is: %s ", shut_start_line_nums) pattern = r".+ libvirt-guests.sh: Shutdown of guest.+complete" for line_num, line in enumerate(output.splitlines()): if re.search(pattern, line): shut_complete_first_line = line_num break logging.debug("the first line contains shutdown complete messages is: %s ", shut_complete_first_line) para_shut = int(parallel_shutdown) if shut_start_line_nums[para_shut-1] > shut_complete_first_line: test.fail("Since parallel_shutdown is setting to non_zero, " "%s guests should be shutdown concurrently." % parallel_shutdown) if shut_start_line_nums[para_shut] < shut_complete_first_line: test.fail("The number of guests shutdown concurrently " "should not be exceeded than %s." % parallel_shutdown) def expect_shutdown_msg(status_error, on_shutdown): """ the expected messages of each guests when host shutdown logged into /var/log/messages """ expect_msg = {} for dom in vms: if status_error == "no": if on_shutdown == "shutdown": expect_msg[dom.name] = ("libvirt-guests.sh: " "Shutdown of guest %s " "complete" % dom.name) else: expect_msg[dom.name] = ("libvirt-guests.sh: " "Suspending %s: done" % dom.name) else: # Now the negative tests are only about ON_SHUTDOWN=shutdown. if on_shutdown == "shutdown": expect_msg[dom.name] = ("libvirt-guests.sh: " "Shutdown of guest %s " "failed to complete in " "time" % dom.name) return expect_msg def chk_save_files(status_error, on_shutdown, on_boot): """ save files should exist when on_shutdown is set to shutdown, and on_boot is set to ignore. In other conditions, there should be no save files. """ save_files = dict() for dom in vms: save_files[dom] = ("/var/lib/libvirt/qemu/save/%s.save" % dom.name) if status_error == "no": if on_shutdown == "shutdown": for dom in vms: if os.path.exists(save_files[dom]): test.fail("There should be no save files since " "guests are shutdown on host shutdown.") else: if on_boot == "start": for dom in vms: if os.path.exists(save_files[dom]): test.fail("There should be no save files since " "guests are restored on host shutdown.") else: for dom in vms: if not os.path.exists(save_files[dom]): test.fail("Guests are suspended on host shutdown, " "and been ignored on host boot, there " "should be save files for the guests.") main_vm_name = params.get("main_vm") main_vm = env.get_vm(main_vm_name) on_boot = params.get("on_boot") on_shutdown = params.get("on_shutdown") parallel_shutdown = params.get("parallel_shutdown") additional_vms = int(params.get("additional_vms", "0")) status_error = params.get("status_error") shutdown_timeout = params.get("shutdown_timeout", "300") config = utils_config.LibvirtGuestsConfig() libvirt_guests_service = service.Factory.create_service("libvirt-guests") if not libvirt_guests_service.status(): libvirt_guests_service.start() vms = [main_vm] if main_vm.is_alive: main_vm.destroy(gracefully=False) try: utils_path.find_command("virt-clone") except utils_path.CmdNotFoundError: test.cancel("No virt-clone command found.") # Clone additional vms: avocado-vt-vm2, avocado-vt-vm3..... for i in range(additional_vms): guest_name = ("%s" % main_vm_name[:-1])+("%s" % str(i+2)) logging.debug("guest_name : %s", guest_name) utils_libguestfs.virt_clone_cmd(main_vm_name, guest_name, True, timeout=360) vms.append(main_vm.clone(guest_name)) logging.debug("Now the vms is: %s", [dom.name for dom in vms]) for dom in vms: if not dom.is_alive(): dom.start() for dom in vms: dom.wait_for_login() try: # Config the libvirt-guests file config.ON_BOOT = on_boot config.ON_SHUTDOWN = on_shutdown config.PARALLEL_SHUTDOWN = parallel_shutdown config.SHUTDOWN_TIMEOUT = shutdown_timeout process.run("sed -i -e 's/ = /=/g' " "/etc/sysconfig/libvirt-guests", shell=True) tail_messages = get_log() # Even though libvirt-guests was designed to operate guests when # host shutdown. The purpose can also be fullfilled by restart the # libvirt-guests service. libvirt_guests_service.restart() output = tail_messages.get_output() # check the guests state when host shutdown chk_on_shutdown(status_error, on_shutdown, parallel_shutdown, output) # check the guests state when host rebooted chk_on_boot(status_error, on_boot) # check the guests save files chk_save_files(status_error, on_shutdown, on_boot) if on_boot == "ignore" and on_shutdown == "shutdown": check_on_shutdown_vm_status() finally: config.restore() # Undefine additional vms for dom in vms[1:]: if dom.is_alive(): dom.destroy(gracefully=False) virsh.remove_domain(dom.name, "--remove-all-storage") if not libvirt_guests_service.status(): libvirt_guests_service.start()