def check_open_tray_cdrom(vm, params, test): """ Check open tray cdrom device in VM can be updated :param vm: one object representing VM :param params: wrapped parameters in dictionary format :param test: test assert object """ iso_file_path = params.get("virt_disk_device_source") device_target = params.get("target_dev") option = " %s --insert " % iso_file_path virsh.change_media(vm.name, device_target, option, ignore_status=False, debug=True) # Check open tray cdrom has been changed with iso file check_source_in_cdrom_device(vm, iso_file_path, test) option = " --eject " virsh.change_media(vm.name, device_target, option, wait_for_event=True, event_timeout=10, ignore_status=False, debug=True) vm.wait_for_login().close() # Check cdrom has been changed with empty check_source_in_cdrom_device(vm, None, test)
def check_iso_cdrom_device_updated(vm, params, test): """ Check iso cdrom device in VM can be updated :param vm: one object representing VM :param params: wrapped parameters in dictionary format :param test: test assert object """ session = vm.wait_for_login() eject_cdrom_device_cmd = "eject /dev/sr0" status = session.cmd_status(eject_cdrom_device_cmd) if status: test.fail("Failed to eject cdrom device in VM") # Save and restore the guest tmp_save_path = "/tmp/save" virsh.save(vm.name, tmp_save_path, ignore_status=False) virsh.restore(tmp_save_path, ignore_status=False) vm.wait_for_login().close() device_target = params.get("target_dev") another_iso_path = params.get("virt_disk_device_source_second") virsh.change_media(vm.name, device_target, another_iso_path, ignore_status=False) # Check cdrom has been changed with new iso file check_source_in_cdrom_device(vm, another_iso_path, test)
def run(test, params, env): """ Test command: virsh change-media. The command changes the media used by CD or floppy drives. Test steps: 1. Prepare test environment. 2. Perform virsh change-media operation. 3. Recover test environment. 4. Confirm the test result. """ @error.context_aware def env_pre(old_iso, new_iso): """ Prepare ISO image for test :param old_iso: sourse file for insert :param new_iso: sourse file for update """ error.context("Preparing ISO images") utils.run("dd if=/dev/urandom of=%s/old bs=1M count=1" % iso_dir) utils.run("dd if=/dev/urandom of=%s/new bs=1M count=1" % iso_dir) utils.run("mkisofs -o %s %s/old" % (old_iso, iso_dir)) utils.run("mkisofs -o %s %s/new" % (new_iso, iso_dir)) @error.context_aware def check_media(session, target_file, action): """ Check guest cdrom/floppy files :param session: guest session :param target_file: the expected files :param action: test case action """ if action != "--eject ": error.context("Checking guest %s files" % target_device) if target_device == "hdc": mount_cmd = "mount /dev/sr0 /media" else: if session.cmd_status("ls /dev/fd0"): session.cmd("mknod /dev/fd0 b 2 0") mount_cmd = "mount /dev/fd0 /media" session.cmd(mount_cmd) session.cmd("test -f /media/%s" % target_file) session.cmd("umount /media") else: error.context("Ejecting guest cdrom files") if target_device == "hdc": if session.cmd_status("mount /dev/sr0 /media -o loop") == 32: logging.info("Eject succeeded") else: if session.cmd_status("ls /dev/fd0"): session.cmd("mknod /dev/fd0 b 2 0") if session.cmd_status("mount /dev/fd0 /media -o loop") == 32: logging.info("Eject succeeded") def add_device(vm_name, init_source="''"): """ Add device for test vm :param vm_name: guest name :param init_source: source file """ if vm.is_alive(): virsh.destroy(vm_name) virsh.attach_disk(vm_name, init_source, target_device, "--type %s --sourcetype file --config" % device_type, debug=True) def update_device(vm_name, init_iso, options, start_vm): """ Update device iso file for test case :param vm_name: guest name :param init_iso: source file :param options: update-device option :param start_vm: guest start flag """ snippet = """ <disk type='file' device='%s'> <driver name='qemu' type='raw'/> <source file='%s'/> <target dev='%s'/> <readonly/> </disk> """ % (device_type, init_iso, target_device) update_iso_file = open(update_iso_xml, "w") update_iso_file.write(snippet) update_iso_file.close() cmd_options = "--force " if options == "--config" or start_vm == "no": cmd_options += " --config" # Give domain the ISO image file return virsh.update_device(domainarg=vm_name, filearg=update_iso_xml, flagstr=cmd_options, debug=True) vm_name = params.get("main_vm") vm = env.get_vm(vm_name) vm_ref = params.get("change_media_vm_ref") action = params.get("change_media_action") start_vm = params.get("start_vm") options = params.get("change_media_options") device_type = params.get("change_media_device_type", "cdrom") target_device = params.get("change_media_target_device", "hdc") source_name = params.get("change_media_source") status_error = params.get("status_error", "no") check_file = params.get("change_media_check_file") update_iso_xml_name = params.get("change_media_update_iso_xml") init_iso_name = params.get("change_media_init_iso") old_iso_name = params.get("change_media_old_iso") new_iso_name = params.get("change_media_new_iso") source_path = params.get("change_media_source_path", "yes") if device_type not in ['cdrom', 'floppy']: raise error.TestNAError("Got a invalid device type:/n%s" % device_type) try: utils_misc.find_command("mkisofs") except ValueError: raise error.TestNAError("Command 'mkisofs' is missing. You must " "install it (try 'genisoimage' package.") # Backup for recovery. vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) iso_dir = os.path.join(data_dir.get_tmp_dir(), "tmp") old_iso = os.path.join(iso_dir, old_iso_name) new_iso = os.path.join(iso_dir, new_iso_name) update_iso_xml = os.path.join(iso_dir, update_iso_xml_name) if not os.path.exists(iso_dir): os.mkdir(iso_dir) if not init_iso_name: init_iso = "" else: init_iso = os.path.join(iso_dir, init_iso_name) if vm_ref == "name": vm_ref = vm_name env_pre(old_iso, new_iso) # Check domain's disk device disk_blk = vm_xml.VMXML.get_disk_blk(vm_name) logging.info("disk_blk %s", disk_blk) if target_device not in disk_blk: logging.info("Adding device") add_device(vm_name) if vm.is_alive() and start_vm == "no": logging.info("Destroying guest...") vm.destroy() elif vm.is_dead() and start_vm == "yes": logging.info("Starting guest...") vm.start() # If test target is floppy, you need to set selinux to Permissive mode. result = update_device(vm_name, init_iso, options, start_vm) # If the selinux is set to enforcing, if we FAIL, then just SKIP force_SKIP = False if result.exit_status == 1 and utils_misc.selinux_enforcing() and \ result.stderr.count("unable to execute QEMU command 'change':"): force_SKIP = True # Libvirt will ignore --source when action is eject if action == "--eject ": source = "" else: source = os.path.join(iso_dir, source_name) if source_path == "no": source = source_name all_options = action + options + " " + source result = virsh.change_media(vm_ref, target_device, all_options, ignore_status=True, debug=True) if status_error == "yes": if start_vm == "no" and vm.is_dead(): try: vm.start() except virt_vm.VMStartError, detail: result.exit_status = 1 result.stderr = str(detail) if start_vm == "yes" and vm.is_alive(): vm.destroy(gracefully=False) try: vm.start() except virt_vm.VMStartError, detail: result.exit_status = 1 result.stderr = str(detail)
def run(test, params, env): """ Test command: virsh change-media. The command changes the media used by CD or floppy drives. Test steps: 1. Prepare test environment. 2. Perform virsh change-media operation. 3. Recover test environment. 4. Confirm the test result. """ @error.context_aware def env_pre(old_iso, new_iso): """ Prepare ISO image for test :param old_iso: sourse file for insert :param new_iso: sourse file for update """ error.context("Preparing ISO images") utils.run("dd if=/dev/urandom of=%s/old bs=1M count=1" % iso_dir) utils.run("dd if=/dev/urandom of=%s/new bs=1M count=1" % iso_dir) utils.run("mkisofs -o %s %s/old" % (old_iso, iso_dir)) utils.run("mkisofs -o %s %s/new" % (new_iso, iso_dir)) @error.context_aware def check_media(session, target_file, action, rw_test=False): """ Check guest cdrom/floppy files :param session: guest session :param target_file: the expected files :param action: test case action """ if action != "--eject ": error.context("Checking guest %s files" % target_device) if target_device == "hdc" or target_device == "sdc": mount_cmd = "mount /dev/sr0 /media" else: if session.cmd_status("ls /dev/fd0"): session.cmd("mknod /dev/fd0 b 2 0") mount_cmd = "mount /dev/fd0 /media" session.cmd(mount_cmd) if rw_test: target_file = "/media/rw_test.txt" session.cmd("touch %s" % target_file) session.cmd("echo 'Hello World'> %s" % target_file) output = session.get_command_output("cat %s" % target_file) logging.debug("cat %s output: %s", target_file, output) else: session.cmd("test -f /media/%s" % target_file) session.cmd("umount /media") else: error.context("Ejecting guest cdrom files") if target_device == "hdc" or target_device == "sdc": if session.cmd_status("mount /dev/sr0 /media -o loop") == 32: logging.info("Eject succeeded") else: if session.cmd_status("ls /dev/fd0"): session.cmd("mknod /dev/fd0 b 2 0") if session.cmd_status("mount /dev/fd0 /media -o loop") == 32: logging.info("Eject succeeded") def add_device(vm_name, init_source="''"): """ Add device for test vm :param vm_name: guest name :param init_source: source file """ if vm.is_alive(): virsh.destroy(vm_name) virsh.attach_disk(vm_name, init_source, target_device, "--type %s --sourcetype file --config" % device_type, debug=True) def update_device(vm_name, init_iso, options, start_vm): """ Update device iso file for test case :param vm_name: guest name :param init_iso: source file :param options: update-device option :param start_vm: guest start flag """ snippet = """ <disk type='file' device='%s'> <driver name='qemu' type='raw'/> <source file='%s'/> <target dev='%s'/> <readonly/> </disk> """ % (device_type, init_iso, target_device) update_iso_file = open(update_iso_xml, "w") update_iso_file.write(snippet) update_iso_file.close() cmd_options = "--force " if options == "--config" or start_vm == "no": cmd_options += " --config" # Give domain the ISO image file return virsh.update_device(domainarg=vm_name, filearg=update_iso_xml, flagstr=cmd_options, debug=True) vm_name = params.get("main_vm") vm = env.get_vm(vm_name) vm_ref = params.get("change_media_vm_ref") action = params.get("change_media_action") start_vm = params.get("start_vm") options = params.get("change_media_options") device_type = params.get("change_media_device_type", "cdrom") target_device = params.get("change_media_target_device", "hdc") source_name = params.get("change_media_source") status_error = params.get("status_error", "no") check_file = params.get("change_media_check_file") update_iso_xml_name = params.get("change_media_update_iso_xml") init_iso_name = params.get("change_media_init_iso") old_iso_name = params.get("change_media_old_iso") new_iso_name = params.get("change_media_new_iso") source_path = params.get("change_media_source_path", "yes") if device_type not in ['cdrom', 'floppy']: raise error.TestNAError("Got a invalid device type:/n%s" % device_type) try: utils_misc.find_command("mkisofs") except ValueError: raise error.TestNAError("Command 'mkisofs' is missing. You must " "install it (try 'genisoimage' package.") # Backup for recovery. vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) iso_dir = os.path.join(data_dir.get_tmp_dir(), "tmp") old_iso = os.path.join(iso_dir, old_iso_name) new_iso = os.path.join(iso_dir, new_iso_name) update_iso_xml = os.path.join(iso_dir, update_iso_xml_name) if not os.path.exists(iso_dir): os.mkdir(iso_dir) if not init_iso_name: init_iso = "" else: init_iso = os.path.join(iso_dir, init_iso_name) if vm_ref == "name": vm_ref = vm_name env_pre(old_iso, new_iso) # Check domain's disk device disk_blk = vm_xml.VMXML.get_disk_blk(vm_name) logging.info("disk_blk %s", disk_blk) if target_device not in disk_blk: logging.info("Adding device") add_device(vm_name) if vm.is_alive() and start_vm == "no": logging.info("Destroying guest...") vm.destroy() elif vm.is_dead() and start_vm == "yes": logging.info("Starting guest...") vm.start() # If test target is floppy, you need to set selinux to Permissive mode. result = update_device(vm_name, init_iso, options, start_vm) # If the selinux is set to enforcing, if we FAIL, then just SKIP force_SKIP = False if result.exit_status == 1 and utils_misc.selinux_enforcing() and \ result.stderr.count("unable to execute QEMU command 'change':"): force_SKIP = True # Libvirt will ignore --source when action is eject if action == "--eject ": source = "" else: source = os.path.join(iso_dir, source_name) if source_path == "no": source = source_name # For read&write floppy test, the iso media need a writeable fs rw_floppy_test = "yes" == params.get("rw_floppy_test", "no") if rw_floppy_test: utils.run("mkfs.ext3 -F %s" % source) all_options = action + options + " " + source result = virsh.change_media(vm_ref, target_device, all_options, ignore_status=True, debug=True) if status_error == "yes": if start_vm == "no" and vm.is_dead(): try: vm.start() except virt_vm.VMStartError, detail: result.exit_status = 1 result.stderr = str(detail) if start_vm == "yes" and vm.is_alive(): vm.destroy(gracefully=False) try: vm.start() except virt_vm.VMStartError, detail: result.exit_status = 1 result.stderr = str(detail)
def run_virsh_change_media(test, params, env): """ Test command: virsh change-media. The command changes the media used by CD or floppy drives. Test steps: 1. Prepare test environment. 2. Perform virsh change-media operation. 3. Recover test environment. 4. Confirm the test result. """ @error.context_aware def env_pre(old_iso, new_iso): """ Prepare ISO image for test @param: old_iso: sourse file for insert @param: new_iso: sourse file for update """ error.context("Preparing ISO images") utils.run("dd if=/dev/urandom of=%s/old bs=10M count=1" % cdrom_dir) utils.run("dd if=/dev/urandom of=%s/new bs=10M count=1" % cdrom_dir) utils.run("mkisofs -o %s %s/old" % (old_iso, cdrom_dir)) utils.run("mkisofs -o %s %s/new" % (new_iso, cdrom_dir)) @error.context_aware def check_media(session, target_file, action): """ Check guest cdrom files @param: session: guest session @param: target_file: the expected files @action: action: test case action """ if action != "--eject ": error.context("Checking guest cdrom files") session.cmd("mount /dev/cdrom /media || mount /dev/cdrom /media") session.cmd("test -f /media/%s" % target_file) session.cmd("umount /dev/cdrom") else: error.context("Ejecting guest cdrom files") if session.cmd_status("mount /dev/cdrom /media -o loop") == 32: logging.info("Eject succeeded") def add_cdrom_device(vm_name, init_cdrom): """ Add cdrom device for test vm @param: vm_name: guest name @param: init_cdrom: source file """ if vm.is_alive(): virsh.destroy(vm_name) virsh.attach_disk(vm_name, init_cdrom, disk_device, " --type cdrom --sourcetype file --config", debug=True) def update_cdrom(vm_name, init_iso, options, start_vm): """ Update cdrom iso file for test case @param: vm_name: guest name @param: init_iso: source file @param: options: update-device option @param: start_vm: guest start flag """ snippet = """ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='%s'/> <target dev='%s' bus='ide'/> <readonly/> </disk> """ % (init_iso, disk_device) update_iso_file = open(update_iso_xml, "w") update_iso_file.write(snippet) update_iso_file.close() cmd_options = "--force " if options == "--config" or start_vm == "no": cmd_options += " --config" # Give domain the ISO image file virsh.update_device(domainarg=vm_name, filearg=update_iso_xml, flagstr=cmd_options, debug=True) vm_name = params.get("main_vm") vm = env.get_vm(vm_name) vm_ref = params.get("change_media_vm_ref") action = params.get("change_media_action") start_vm = params.get("start_vm") options = params.get("change_media_options") disk_device = params.get("change_media_disk_device") libvirtd = params.get("libvirtd", "on") source_name = params.get("change_media_source") status_error = params.get("status_error", "no") check_file = params.get("change_media_check_file") init_cdrom = params.get("change_media_init_cdrom") update_iso_xml_name = params.get("change_media_update_iso_xml") init_iso_name = params.get("change_media_init_iso") old_iso_name = params.get("change_media_old_iso") new_iso_name = params.get("change_media_new_iso") cdrom_dir = os.path.join(test.tmpdir, "tmp") old_iso = os.path.join(cdrom_dir, old_iso_name) new_iso = os.path.join(cdrom_dir, new_iso_name) update_iso_xml = os.path.join(cdrom_dir, update_iso_xml_name) if not os.path.exists(cdrom_dir): os.mkdir(cdrom_dir) if not init_iso_name : init_iso = "" else: init_iso = os.path.join(cdrom_dir, init_iso_name) if vm_ref == "name": vm_ref = vm_name env_pre(old_iso, new_iso) # Check domain's disk device disk_blk = vm_xml.VMXML.get_disk_blk(vm_name) logging.info("disk_blk %s" % disk_blk) if disk_device not in disk_blk: logging.info("Adding cdrom device") add_cdrom_device(vm_name, init_cdrom) if vm.is_alive() and start_vm == "no": logging.info("Destroying guest...") vm.destroy() elif vm.is_dead() and start_vm == "yes": logging.info("Starting guest...") vm.start() update_cdrom(vm_name, init_iso, options, start_vm) if libvirtd == "off": utils_libvirtd.libvirtd_stop() # Libvirt will ignore --source when action is eject if action == "--eject ": source = "" else: source = os.path.join(cdrom_dir, source_name) all_options = action + options + " " + source result = virsh.change_media(vm_ref, disk_device, all_options, ignore_status=True, debug=True) status = result.exit_status if status_error == "no": if options == "--config" and vm.is_alive(): vm.destroy() if vm.is_dead(): vm.start() session = vm.wait_for_login() check_media(session, check_file, action) session.close() # Recover libvirtd service start if libvirtd == "off": utils_libvirtd.libvirtd_start() # Clean the cdrom dir and clean the cdrom device update_cdrom(vm_name, "", options, start_vm) # Check status_error # Negative testing if status_error == "yes": if status: logging.info("Expected error (negative testing). Output: %s", result.stderr.strip()) else: raise error.TestFail("Unexpected return code %d " "(negative testing)" % status) # Positive testing elif status_error == "no": if status: raise error.TestFail("Unexpected error (positive testing). " "Output: %s" % result.stderr.strip()) else: logging.info("Expected success. Output: %s", result.stdout.strip()) else: raise error.TestError("Invalid value for status_error '%s' " "(must be 'yes' or 'no')" % status_error)
def run(test, params, env): """ Test command: virsh change-media. The command changes the media used by CD or floppy drives. Test steps: 1. Prepare test environment. 2. Perform virsh change-media operation. 3. Recover test environment. 4. Confirm the test result. """ def is_attached(vmxml_devices, disk_type, source_file, target_dev): """ Check attached device and disk exist or not. :param vmxml_devices: VMXMLDevices instance :param disk_type: disk's device type: cdrom or floppy :param source_file : disk's source file to check :param target_dev : target device name :return: True/False if backing file and device found """ disks = vmxml_devices.by_device_tag('disk') for disk in disks: if disk.device != disk_type: continue if disk.target['dev'] != target_dev: continue if disk.xmltreefile.find('source') is not None: if disk.source.attrs['file'] != source_file: continue else: continue # All three conditions met logging.debug("Find %s in given disk XML", source_file) return True logging.debug("Not find %s in gievn disk XML", source_file) return False def check_result(vm_name, disk_source, disk_type, disk_target, flags, vm_state, attach=True): """ Check the test result of attach/detach-device command. """ active_vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) active_attached = is_attached(active_vmxml.devices, disk_type, disk_source, disk_target) if vm_state != "transient": inactive_vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name, options="--inactive") inactive_attached = is_attached(inactive_vmxml.devices, disk_type, disk_source, disk_target) if flags.count("config") and not flags.count("live"): if vm_state != "transient": if attach: if not inactive_attached: raise exceptions.TestFail("Inactive domain XML not updated" " when --config options used for" " attachment") if vm_state != "shutoff": if active_attached: raise exceptions.TestFail("Active domain XML updated" " when --config options used" " for attachment") else: if inactive_attached: raise exceptions.TestFail("Inactive domain XML not updated" " when --config options used for" " detachment") if vm_state != "shutoff": if not active_attached: raise exceptions.TestFail("Active domain XML updated" " when --config options used" " for detachment") elif flags.count("live") and not flags.count("config"): if attach: if vm_state in ["paused", "running", "transient"]: if not active_attached: raise exceptions.TestFail("Active domain XML not updated" " when --live options used for" " attachment") if vm_state in ["paused", "running"]: if inactive_attached: raise exceptions.TestFail("Inactive domain XML updated" " when --live options used for" " attachment") else: if vm_state in ["paused", "running", "transient"]: if active_attached: raise exceptions.TestFail("Active domain XML not updated" " when --live options used for" " detachment") if vm_state in ["paused", "running"]: if not inactive_attached: raise exceptions.TestFail("Inactive domain XML updated" " when --live options used for" " detachment") elif flags.count("live") and flags.count("config"): if attach: if vm_state in ["paused", "running"]: if not active_attached: raise exceptions.TestFail("Active domain XML not updated" " when --live --config options" " used for attachment") if not inactive_attached: raise exceptions.TestFail("Inactive domain XML not updated" " when --live --config options " "used for attachment") else: if vm_state in ["paused", "running"]: if active_attached: raise exceptions.TestFail("Active domain XML not updated " "when --live --config options " "used for detachment") if inactive_attached: raise exceptions.TestFail("Inactive domain XML not updated" " when --live --config options " "used for detachment") elif flags.count("current") or flags == "": if attach: if vm_state in ["paused", "running", "transient"]: if not active_attached: raise exceptions.TestFail("Active domain XML not updated" " when --current options used " "for attachment") if vm_state in ["paused", "running"]: if inactive_attached: raise exceptions.TestFail("Inactive domain XML updated " "when --current options used " "for live attachment") if vm_state == "shutoff" and not inactive_attached: raise exceptions.TestFail("Inactive domain XML not updated " "when --current options used for " "attachment") else: if vm_state in ["paused", "running", "transient"]: if active_attached: raise exceptions.TestFail("Active domain XML not updated" " when --current options used " "for detachment") if vm_state in ["paused", "running"]: if not inactive_attached: raise exceptions.TestFail("Inactive domain XML updated " "when --current options used " "for live detachment") if vm_state == "shutoff" and inactive_attached: raise exceptions.TestFail("Inactive domain XML not updated " "when --current options used for " "detachment") vm_name = params.get("main_vm") vm = env.get_vm(vm_name) vm_ref = params.get("change_media_vm_ref") action = params.get("change_media_action") action_twice = params.get("change_media_action_twice", "") pre_vm_state = params.get("pre_vm_state") options = params.get("change_media_options") options_twice = params.get("change_media_options_twice", "") device_type = params.get("change_media_device_type", "cdrom") target_device = params.get("change_media_target_device", "hdc") init_iso_name = params.get("change_media_init_iso") old_iso_name = params.get("change_media_old_iso") new_iso_name = params.get("change_media_new_iso") virsh_dargs = {"debug": True, "ignore_status": True} if device_type not in ['cdrom', 'floppy']: raise exceptions.TestSkipError("Got a invalid device type:/n%s" % device_type) # Backup for recovery. vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) old_iso = os.path.join(data_dir.get_tmp_dir(), old_iso_name) new_iso = os.path.join(data_dir.get_tmp_dir(), new_iso_name) if vm_ref == "name": vm_ref = vm_name if vm.is_alive(): vm.destroy(gracefully=False) try: if not init_iso_name: init_iso = "" else: init_iso = os.path.join(data_dir.get_tmp_dir(), init_iso_name) # Prepare test files. libvirt.create_local_disk("iso", old_iso) libvirt.create_local_disk("iso", new_iso) # Check domain's disk device disk_blk = vm_xml.VMXML.get_disk_blk(vm_name) logging.info("disk_blk %s", disk_blk) if target_device not in disk_blk: if vm.is_alive(): virsh.destroy(vm_name) logging.info("Adding device") libvirt.create_local_disk("iso", init_iso) disk_params = {"disk_type": "file", "device_type": device_type, "driver_name": "qemu", "driver_type": "raw", "target_bus": "ide", "readonly": "yes"} libvirt.attach_additional_device(vm_name, target_device, init_iso, disk_params) vmxml_for_test = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) # Turn VM into certain state. if pre_vm_state == "running": logging.info("Starting %s..." % vm_name) if vm.is_dead(): vm.start() vm.wait_for_login().close() elif pre_vm_state == "shutoff": logging.info("Shuting down %s..." % vm_name) if vm.is_alive(): vm.destroy(gracefully=False) elif pre_vm_state == "paused": logging.info("Pausing %s..." % vm_name) if vm.is_dead(): vm.start() vm.wait_for_login().close() if not vm.pause(): raise exceptions.TestSkipError("Cann't pause the domain") time.sleep(5) elif pre_vm_state == "transient": logging.info("Creating %s..." % vm_name) vm.undefine() if virsh.create(vmxml_for_test.xml, **virsh_dargs).exit_status: vmxml_backup.define() raise exceptions.TestSkipError("Cann't create the domain") # Libvirt will ignore --source when action is eject attach = True device_source = old_iso if action == "--eject ": source = "" attach = False else: source = device_source all_options = action + options + " " + source ret = virsh.change_media(vm_ref, target_device, all_options, ignore_status=True, debug=True) status_error = False if pre_vm_state == "shutoff": if options.count("live"): status_error = True elif pre_vm_state == "transient": if options.count("config"): status_error = True if vm.is_paused(): vm.resume() vm.wait_for_login().close() # For paused vm, change_media for eject/update operation # should be executed again for it takes effect if ret.exit_status: if not action.count("insert") and not options.count("force"): ret = virsh.change_media(vm_ref, target_device, all_options, ignore_status=True, debug=True) if not status_error and ret.exit_status: raise exceptions.TestFail("Please check: Bug 1289069 - Ejecting " "locked cdrom tray using update-device" " fails but next try succeeds") libvirt.check_exit_status(ret, status_error) if not ret.exit_status: check_result(vm_name, device_source, device_type, target_device, options, pre_vm_state, attach) if action_twice: if pre_vm_state == "paused": if not vm.pause(): raise exceptions.TestFail("Cann't pause the domain") time.sleep(5) attach = True device_source = new_iso if action_twice == "--eject ": #options_twice += " --force " source = "" attach = False else: source = device_source all_options = action_twice + options_twice + " " + source time.sleep(5) ret = virsh.change_media(vm_ref, target_device, all_options, ignore_status=True, debug=True) status_error = False if pre_vm_state == "shutoff": if options_twice.count("live"): status_error = True elif pre_vm_state == "transient": if options_twice.count("config"): status_error = True if action_twice == "--insert ": if pre_vm_state in ["running", "paused"]: if options in ["--force", "--current", "", "--live"]: if options_twice.count("config"): status_error = True elif options == "--config": if options_twice in ["--force", "--current", ""]: status_error = True elif options_twice.count("live"): status_error = True elif pre_vm_state == "transient": if ret.exit_status: status_error = True elif pre_vm_state == "shutoff": if options.count("live"): status_error = True if vm.is_paused(): vm.resume() vm.wait_for_login().close() # For paused vm, change_media for eject/update operation # should be executed again for it takes effect if ret.exit_status and not action_twice.count("insert"): ret = virsh.change_media(vm_ref, target_device, all_options, ignore_status=True, debug=True) if not status_error and ret.exit_status: raise exceptions.TestFail("Please check: Bug 1289069 - Ejecting " "locked cdrom tray using update-device" " fails but next try succeeds") libvirt.check_exit_status(ret, status_error) if not ret.exit_status: check_result(vm_name, device_source, device_type, target_device, options_twice, pre_vm_state, attach) # Try to start vm. if vm.is_dead(): vm.start() vm.wait_for_login().close() finally: if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() # Remove disks if os.path.exists(init_iso): os.remove(init_iso) if os.path.exists(old_iso): os.remove(old_iso) if os.path.exists(init_iso): os.remove(new_iso)
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 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 command: virsh change-media. The command changes the media used by CD or floppy drives. Test steps: 1. Prepare test environment. 2. Perform virsh change-media operation. 3. Recover test environment. 4. Confirm the test result. """ @error_context.context_aware def env_pre(old_iso, new_iso): """ Prepare ISO image for test :param old_iso: sourse file for insert :param new_iso: sourse file for update """ error_context.context("Preparing ISO images") process.run("dd if=/dev/urandom of=%s/old bs=1M count=1" % iso_dir, shell=True) process.run("dd if=/dev/urandom of=%s/new bs=1M count=1" % iso_dir, shell=True) process.run("mkisofs -o %s %s/old" % (old_iso, iso_dir), shell=True) process.run("mkisofs -o %s %s/new" % (new_iso, iso_dir), shell=True) @error_context.context_aware def check_media(session, target_file, action, rw_test=False): """ Check guest cdrom/floppy files :param session: guest session :param target_file: the expected files :param action: test case action """ if target_device == "hdc" or target_device == "sdc": drive_name = session.cmd( "cat /proc/sys/dev/cdrom/info | grep -i 'drive name'", ignore_all_errors=True).split()[2] if action != "--eject ": error_context.context("Checking guest %s files" % target_device) if target_device == "hdc" or target_device == "sdc": mount_cmd = "mount /dev/%s /media" % drive_name else: if session.cmd_status("ls /dev/fd0"): session.cmd("mknod /dev/fd0 b 2 0") mount_cmd = "mount /dev/fd0 /media" session.cmd(mount_cmd) if rw_test: target_file = "/media/rw_test.txt" session.cmd("touch %s" % target_file) session.cmd("echo 'Hello World'> %s" % target_file) output = session.get_command_output("cat %s" % target_file) logging.debug("cat %s output: %s", target_file, output) else: session.cmd("test -f /media/%s" % target_file) session.cmd("umount /media") else: error_context.context("Ejecting guest cdrom files") if target_device == "hdc" or target_device == "sdc": if session.cmd_status("mount /dev/%s /media -o loop" % drive_name) == 32: logging.info("Eject succeeded") else: if session.cmd_status("ls /dev/fd0"): session.cmd("mknod /dev/fd0 b 2 0") if session.cmd_status("mount /dev/fd0 /media -o loop") == 32: logging.info("Eject succeeded") def add_device(vm_name, init_source="''"): """ Add device for test vm :param vm_name: guest name :param init_source: source file """ if vm.is_alive(): virsh.destroy(vm_name) device_target_bus = params.get("device_target_bus", "ide") virsh.attach_disk( vm_name, init_source, target_device, "--type %s --sourcetype file --targetbus %s --config" % (device_type, device_target_bus), debug=True) def update_device(vm_name, init_iso, options, start_vm): """ Update device iso file for test case :param vm_name: guest name :param init_iso: source file :param options: update-device option :param start_vm: guest start flag """ if 'disk_alias' not in locals() or disk_alias is None: disk_alias_update = "" else: disk_alias_update = disk_alias device_target_bus = params.get("device_target_bus", "ide") snippet = """ <disk type='file' device='%s'> <driver name='qemu' type='raw'/> <source file='%s'/> <target dev='%s' bus='%s'/> <readonly/> <alias name='%s'/> </disk> """ % (device_type, init_iso, target_device, device_target_bus, disk_alias_update) logging.info("Update xml is %s", snippet) with open(update_iso_xml, "w") as update_iso_file: update_iso_file.write(snippet) cmd_options = "--force " if options == "--config" or start_vm == "no": cmd_options += " --config" # Give domain the ISO image file return virsh.update_device(domainarg=vm_name, filearg=update_iso_xml, flagstr=cmd_options, debug=True) vm_name = params.get("main_vm") vm = env.get_vm(vm_name) vm_ref = params.get("change_media_vm_ref") action = params.get("change_media_action") start_vm = params.get("start_vm") options = params.get("change_media_options") device_type = params.get("change_media_device_type", "cdrom") target_device = params.get("change_media_target_device", "hdc") source_name = params.get("change_media_source") status_error = "yes" == params.get("status_error", "no") check_file = params.get("change_media_check_file") update_iso_xml_name = params.get("change_media_update_iso_xml") init_iso_name = params.get("change_media_init_iso") old_iso_name = params.get("change_media_old_iso") new_iso_name = params.get("change_media_new_iso") source_path = params.get("change_media_source_path", "yes") if device_type not in ['cdrom', 'floppy']: test.cancel("Got a invalid device type:/n%s" % device_type) try: utils_path.find_command("mkisofs") except utils_path.CmdNotFoundError: test.cancel("Command 'mkisofs' is missing. You must " "install it (try 'genisoimage' package.") # Check virsh command option if options and not status_error: libvirt.virsh_cmd_has_option('change-media', options) # Backup for recovery. vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) try: iso_dir = os.path.join(data_dir.get_tmp_dir(), "tmp") old_iso = os.path.join(iso_dir, old_iso_name) new_iso = os.path.join(iso_dir, new_iso_name) update_iso_xml = os.path.join(iso_dir, update_iso_xml_name) if not os.path.exists(iso_dir): os.mkdir(iso_dir) if not init_iso_name: init_iso = "" else: init_iso = os.path.join(iso_dir, init_iso_name) if vm_ref == "name": vm_ref = vm_name env_pre(old_iso, new_iso) # Check domain's disk device disk_blk = vm_xml.VMXML.get_disk_blk(vm_name) logging.info("disk_blk %s", disk_blk) if target_device not in disk_blk: logging.info("Adding device") add_device(vm_name) if vm.is_alive() and start_vm == "no": logging.info("Destroying guest...") vm.destroy() elif vm.is_dead() and start_vm == "yes": logging.info("Starting guest...") vm.start() disk_alias = libvirt.get_disk_alias(vm) logging.debug("disk_alias is %s", disk_alias) # If test target is floppy, you need to set selinux to Permissive mode. result = update_device(vm_name, init_iso, options, start_vm) # If the selinux is set to enforcing, if we FAIL, then just SKIP force_SKIP = False if result.exit_status == 1 and utils_misc.selinux_enforcing() and \ result.stderr.count("unable to execute QEMU command 'change':"): force_SKIP = True # Libvirt will ignore --source when action is eject if action == "--eject ": source = "" else: source = os.path.join(iso_dir, source_name) if source_path == "no": source = source_name # For read&write floppy test, the iso media need a writeable fs rw_floppy_test = "yes" == params.get("rw_floppy_test", "no") if rw_floppy_test: process.run("mkfs.ext3 -F %s" % source, shell=True) all_options = action + options + " " + source result = virsh.change_media(vm_ref, target_device, all_options, ignore_status=True, debug=True) if status_error: if start_vm == "no" and vm.is_dead(): try: vm.start() except virt_vm.VMStartError as detail: result.exit_status = 1 result.stderr = str(detail) if start_vm == "yes" and vm.is_alive(): vm.destroy(gracefully=False) try: vm.start() except virt_vm.VMStartError as detail: result.exit_status = 1 result.stderr = str(detail) status = result.exit_status if not status_error: if 'print-xml' in options: vmxml_new = vm_xml.VMXML.new_from_dumpxml(vm_name) if source in vmxml_new: test.fail("Run command with 'print-xml'" " option, unexpected device was" " found in domain xml") else: if options == "--config" and vm.is_alive(): vm.destroy() if vm.is_dead(): vm.start() if 'block' in options and 'eject' not in action: vmxml_new = vm_xml.VMXML.new_from_dumpxml(vm_name) logging.debug("vmxml: %s", vmxml_new) if not vm_xml.VMXML.check_disk_type( vm_name, source, "block"): test.fail("Disk isn't a 'block' device") session = vm.wait_for_login() check_media(session, check_file, action, rw_floppy_test) session.close() # Negative testing if status_error: if status: logging.info("Expected error (negative testing). Output: %s", result.stderr.strip()) else: test.fail("Unexpected return code %d " "(negative testing)" % status) # Positive testing else: if status: if force_SKIP: test.cancel("SELinux is set to enforcing and has " "resulted in this test failing to open " "the iso file for a floppy.") test.fail("Unexpected error (positive testing). " "Output: %s" % result.stderr.strip()) else: logging.info("Expected success. Output: %s", result.stdout.strip()) finally: # Clean the iso dir and clean the device update_device(vm_name, "", options, start_vm) vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() utils_misc.safe_rmdir(iso_dir)
def run_virsh_change_media(test, params, env): """ Test command: virsh change-media. The command changes the media used by CD or floppy drives. Test steps: 1. Prepare test environment. 2. Perform virsh change-media operation. 3. Recover test environment. 4. Confirm the test result. """ @error.context_aware def env_pre(old_iso, new_iso): """ Prepare ISO image for test """ error.context("Preparing ISO images") utils.run("dd if=/dev/urandom of=%s/old bs=10M count=1" % cdrom_dir) utils.run("dd if=/dev/urandom of=%s/new bs=10M count=1" % cdrom_dir) utils.run("mkisofs -o %s %s/old" % (old_iso, cdrom_dir)) utils.run("mkisofs -o %s %s/new" % (new_iso, cdrom_dir)) @error.context_aware def check_media(session, target_file, action): """ Check guest cdrom files 1. guest session 2. the expected files 3. test case action """ if action != "--eject ": error.context("Checking guest cdrom files") session.cmd("mount /dev/cdrom /media || mount /dev/cdrom /media") session.cmd("test -f /media/%s" % target_file) session.cmd("umount /dev/cdrom") else: error.context("Ejecting guest cdrom files") if session.cmd_status("mount /dev/cdrom /media -o loop") == 32: logging.info("Eject succeeded") def add_cdrom_device(vm_name, init_cdrom): """ Add cdrom device for test vm """ if vm.is_alive(): virsh.destroy(vm_name) virsh.attach_disk(vm_name, init_cdrom, " hdc", " --type cdrom --sourcetype file --config", debug=True) def update_cdrom(vm_name, init_iso, options, start_vm): """ Update cdrom iso file for test case """ snippet = """ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='%s'/> <target dev='hdc' bus='ide'/> <readonly/> </disk> """ % (init_iso) update_iso_file = open(update_iso_xml, "w") update_iso_file.write(snippet) update_iso_file.close() cmd_options = "--force " if options == "--config" or start_vm == "no": cmd_options += " --config" # Give domain the ISO image file virsh.update_device(domainarg=vm_name, filearg=update_iso_xml, flagstr=cmd_options, debug=True) vm_name = params.get("main_vm") vm = env.get_vm(vm_name) vm_ref = params.get("vm_ref") action = params.get("action") start_vm = params.get("start_vm") options = params.get("options") cdrom_dir = os.path.join(test.tmpdir, "tmp") if not os.path.exists(cdrom_dir): os.mkdir(cdrom_dir) old_iso_name = params.get("old_iso") new_iso_name = params.get("new_iso") old_iso = cdrom_dir + old_iso_name new_iso = cdrom_dir + new_iso_name init_cdrom = params.get("init_cdrom") update_iso_xml_name = params.get("update_iso_xml") update_iso_xml = cdrom_dir + update_iso_xml_name init_iso_name = params.get("init_iso") if not init_iso_name: init_iso = "" else: init_iso = cdrom_dir + init_iso_name if vm_ref == "name": vm_ref = vm_name env_pre(old_iso, new_iso) # Check domain's disk device disk_blk = vm_xml.VMXML.get_disk_blk(vm_name) logging.info("disk_blk %s" % disk_blk) if "hdc" not in disk_blk: logging.info("Adding cdrom device") add_cdrom_device(vm_name, init_cdrom) if vm.is_alive() and start_vm == "no": logging.info("Destroying guest...") vm.destroy() elif vm.is_dead() and start_vm == "yes": logging.info("Starting guest...") vm.start() update_cdrom(vm_name, init_iso, options, start_vm) disk_device = params.get("disk_device") libvirtd = params.get("libvirtd", "on") if libvirtd == "off": libvirt_vm.libvirtd_stop() source_name = params.get("change_media_source") # Libvirt will ignore --source when action is eject if action == "--eject ": source = "" else: source = cdrom_dir + source_name all_options = action + options + " " + source result = virsh.change_media(vm_ref, disk_device, all_options, ignore_status=True, debug=True) status = result.exit_status status_error = params.get("status_error", "no") if status_error == "no": if options == "--config" and vm.is_alive(): vm.destroy() vm.start() session = vm.wait_for_login() check_file = params.get("check_file") check_media(session, check_file, action) session.close() # Recover libvirtd service start if libvirtd == "off": libvirt_vm.libvirtd_start() # Clean the cdrom dir and clean the cdrom device update_cdrom(vm_name, "", options, start_vm) shutil.rmtree(cdrom_dir) # Check status_error # Negative testing if status_error == "yes": if status: logging.info("Expected error (negative testing). Output: %s", result.stderr.strip()) else: raise error.TestFail("Unexpected return code %d " "(negative testing)" % status) # Positive testing elif status_error == "no": if status: raise error.TestFail("Unexpected error (positive testing). " "Output: %s" % result.stderr.strip()) else: logging.info("Expected success. Output: %s", result.stdout.strip()) else: raise error.TestError("Invalid value for status_error '%s' " "(must be 'yes' or 'no')" % status_error)
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: if event in [ 'start', 'restore', 'create', '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") 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 == "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") 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 command: virsh change-media. The command changes the media used by CD or floppy drives. Test steps: 1. Prepare test environment. 2. Perform virsh change-media operation. 3. Recover test environment. 4. Confirm the test result. """ def is_attached(vmxml_devices, disk_type, source_file, target_dev): """ Check attached device and disk exist or not. :param vmxml_devices: VMXMLDevices instance :param disk_type: disk's device type: cdrom or floppy :param source_file : disk's source file to check :param target_dev : target device name :return: True/False if backing file and device found """ disks = vmxml_devices.by_device_tag('disk') for disk in disks: if disk.device != disk_type: continue if disk.target['dev'] != target_dev: continue if disk.xmltreefile.find('source') is not None: if disk.source.attrs['file'] != source_file: continue else: continue # All three conditions met logging.debug("Find %s in given disk XML", source_file) return True logging.debug("Not find %s in gievn disk XML", source_file) return False def check_result(vm_name, disk_source, disk_type, disk_target, flags, vm_state, attach=True): """ Check the test result of attach/detach-device command. """ active_vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) active_attached = is_attached(active_vmxml.devices, disk_type, disk_source, disk_target) if vm_state != "transient": inactive_vmxml = vm_xml.VMXML.new_from_dumpxml( vm_name, options="--inactive") inactive_attached = is_attached(inactive_vmxml.devices, disk_type, disk_source, disk_target) if flags.count("config") and not flags.count("live"): if vm_state != "transient": if attach: if not inactive_attached: test.fail("Inactive domain XML not updated" " when --config options used for" " attachment") if vm_state != "shutoff": if active_attached: test.fail("Active domain XML updated" " when --config options used" " for attachment") else: if inactive_attached: test.fail("Inactive domain XML not updated" " when --config options used for" " detachment") if vm_state != "shutoff": if not active_attached: test.fail("Active domain XML updated" " when --config options used" " for detachment") elif flags.count("live") and not flags.count("config"): if attach: if vm_state in ["paused", "running", "transient"]: if not active_attached: test.fail("Active domain XML not updated" " when --live options used for" " attachment") if vm_state in ["paused", "running"]: if inactive_attached: test.fail("Inactive domain XML updated" " when --live options used for" " attachment") else: if vm_state in ["paused", "running", "transient"]: if active_attached: test.fail("Active domain XML not updated" " when --live options used for" " detachment") if vm_state in ["paused", "running"]: if not inactive_attached: test.fail("Inactive domain XML updated" " when --live options used for" " detachment") elif flags.count("live") and flags.count("config"): if attach: if vm_state in ["paused", "running"]: if not active_attached: test.fail("Active domain XML not updated" " when --live --config options" " used for attachment") if not inactive_attached: test.fail("Inactive domain XML not updated" " when --live --config options " "used for attachment") else: if vm_state in ["paused", "running"]: if active_attached: test.fail("Active domain XML not updated " "when --live --config options " "used for detachment") if inactive_attached: test.fail("Inactive domain XML not updated" " when --live --config options " "used for detachment") elif flags.count("current") or flags == "": if attach: if vm_state in ["paused", "running", "transient"]: if not active_attached: test.fail("Active domain XML not updated" " when --current options used " "for attachment") if vm_state in ["paused", "running"]: if inactive_attached: test.fail("Inactive domain XML updated " "when --current options used " "for live attachment") if vm_state == "shutoff" and not inactive_attached: test.fail("Inactive domain XML not updated " "when --current options used for " "attachment") else: if vm_state in ["paused", "running", "transient"]: if active_attached: test.fail("Active domain XML not updated" " when --current options used " "for detachment") if vm_state in ["paused", "running"]: if not inactive_attached: test.fail("Inactive domain XML updated " "when --current options used " "for live detachment") if vm_state == "shutoff" and inactive_attached: test.fail("Inactive domain XML not updated " "when --current options used for " "detachment") vm_name = params.get("main_vm") vm = env.get_vm(vm_name) vm_ref = params.get("change_media_vm_ref") action = params.get("change_media_action") action_twice = params.get("change_media_action_twice", "") pre_vm_state = params.get("pre_vm_state") options = params.get("change_media_options") options_twice = params.get("change_media_options_twice", "") device_type = params.get("change_media_device_type", "cdrom") target_device = params.get("change_media_target_device", "hdc") init_iso_name = params.get("change_media_init_iso") old_iso_name = params.get("change_media_old_iso") new_iso_name = params.get("change_media_new_iso") virsh_dargs = {"debug": True, "ignore_status": True} if device_type not in ['cdrom', 'floppy']: test.cancel("Got a invalid device type:/n%s" % device_type) # Backup for recovery. vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) old_iso = os.path.join(data_dir.get_tmp_dir(), old_iso_name) new_iso = os.path.join(data_dir.get_tmp_dir(), new_iso_name) if vm_ref == "name": vm_ref = vm_name if vm.is_alive(): vm.destroy(gracefully=False) try: if not init_iso_name: init_iso = "" else: init_iso = os.path.join(data_dir.get_tmp_dir(), init_iso_name) # Prepare test files. libvirt.create_local_disk("iso", old_iso) libvirt.create_local_disk("iso", new_iso) # Check domain's disk device disk_blk = vm_xml.VMXML.get_disk_blk(vm_name) logging.info("disk_blk %s", disk_blk) if target_device not in disk_blk: if vm.is_alive(): virsh.destroy(vm_name) logging.info("Adding device") libvirt.create_local_disk("iso", init_iso) disk_params = { "disk_type": "file", "device_type": device_type, "driver_name": "qemu", "driver_type": "raw", "target_bus": "ide", "readonly": "yes" } libvirt.attach_additional_device(vm_name, target_device, init_iso, disk_params) vmxml_for_test = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) # Turn VM into certain state. if pre_vm_state == "running": logging.info("Starting %s..." % vm_name) if vm.is_dead(): vm.start() vm.wait_for_login().close() elif pre_vm_state == "shutoff": logging.info("Shuting down %s..." % vm_name) if vm.is_alive(): vm.destroy(gracefully=False) elif pre_vm_state == "paused": logging.info("Pausing %s..." % vm_name) if vm.is_dead(): vm.start() vm.wait_for_login().close() if not vm.pause(): test.cancel("Cann't pause the domain") time.sleep(5) elif pre_vm_state == "transient": logging.info("Creating %s..." % vm_name) vm.undefine() if virsh.create(vmxml_for_test.xml, **virsh_dargs).exit_status: vmxml_backup.define() test.cancel("Cann't create the domain") # Libvirt will ignore --source when action is eject attach = True device_source = old_iso if action == "--eject ": source = "" attach = False else: source = device_source all_options = action + options + " " + source ret = virsh.change_media(vm_ref, target_device, all_options, ignore_status=True, debug=True) status_error = False if pre_vm_state == "shutoff": if options.count("live"): status_error = True elif pre_vm_state == "transient": if options.count("config"): status_error = True if vm.is_paused(): vm.resume() vm.wait_for_login().close() # For paused vm, change_media for eject/update operation # should be executed again for it takes effect if ret.exit_status: if not action.count("insert") and not options.count("force"): ret = virsh.change_media(vm_ref, target_device, all_options, ignore_status=True, debug=True) if not status_error and ret.exit_status: test.fail("Change media failed: %s" % ret.stderr.strip()) libvirt.check_exit_status(ret, status_error) if not ret.exit_status: check_result(vm_name, device_source, device_type, target_device, options, pre_vm_state, attach) if action_twice: if pre_vm_state == "paused": if not vm.pause(): test.fail("Cann't pause the domain") time.sleep(5) attach = True device_source = new_iso if action_twice == "--eject ": #options_twice += " --force " source = "" attach = False else: source = device_source all_options = action_twice + options_twice + " " + source time.sleep(5) ret = virsh.change_media(vm_ref, target_device, all_options, ignore_status=True, debug=True) status_error = False if pre_vm_state == "shutoff": if options_twice.count("live"): status_error = True elif pre_vm_state == "transient": if options_twice.count("config"): status_error = True if action_twice == "--insert ": if pre_vm_state in ["running", "paused"]: if options in ["--force", "--current", "", "--live"]: if options_twice.count("config"): status_error = True elif options == "--config": if options_twice in ["--force", "--current", ""]: status_error = True elif options_twice.count("live"): status_error = True elif pre_vm_state == "transient": if ret.exit_status: status_error = True elif pre_vm_state == "shutoff": if options.count("live"): status_error = True if vm.is_paused(): vm.resume() vm.wait_for_login().close() # For paused vm, change_media for eject/update operation # should be executed again for it takes effect if ret.exit_status and not action_twice.count("insert"): ret = virsh.change_media(vm_ref, target_device, all_options, ignore_status=True, debug=True) if not status_error and ret.exit_status: test.fail("Change media failed: %s" % ret.stderr.strip()) libvirt.check_exit_status(ret, status_error) if not ret.exit_status: check_result(vm_name, device_source, device_type, target_device, options_twice, pre_vm_state, attach) # Try to start vm. if vm.is_dead(): vm.start() vm.wait_for_login().close() finally: if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() # Remove disks if os.path.exists(init_iso): os.remove(init_iso) if os.path.exists(old_iso): os.remove(old_iso) if os.path.exists(init_iso): os.remove(new_iso)
def run_virsh_change_media(test, params, env): """ Test command: virsh change-media. The command changes the media used by CD or floppy drives. Test steps: 1. Prepare test environment. 2. Perform virsh change-media operation. 3. Recover test environment. 4. Confirm the test result. """ @error.context_aware def env_pre(old_iso, new_iso): """ Prepare ISO image for test :param old_iso: sourse file for insert :param new_iso: sourse file for update """ error.context("Preparing ISO images") utils.run("dd if=/dev/urandom of=%s/old bs=1M count=1" % iso_dir) utils.run("dd if=/dev/urandom of=%s/new bs=1M count=1" % iso_dir) utils.run("mkisofs -o %s %s/old" % (old_iso, iso_dir)) utils.run("mkisofs -o %s %s/new" % (new_iso, iso_dir)) @error.context_aware def check_media(session, target_file, action): """ Check guest cdrom/floppy files :param session: guest session :param target_file: the expected files :param action: test case action """ if action != "--eject ": error.context("Checking guest %s files" % target_device) if target_device == "hdc": mount_cmd = "mount /dev/cdrom /media" else: session.cmd("mknod /dev/fd0 b 2 0") mount_cmd = "mount /dev/fd0 /media" session.cmd(mount_cmd) session.cmd("test -f /media/%s" % target_file) session.cmd("umount /media") else: error.context("Ejecting guest cdrom files") if target_device == "hdc": if session.cmd_status("mount /dev/cdrom /media -o loop") == 32: logging.info("Eject succeeded") else: session.cmd("mknod /dev/fd0 b 2 0") if session.cmd_status("mount /dev/fd0 /media -o loop") == 32: logging.info("Eject succeeded") def add_device(vm_name, init_source="''"): """ Add device for test vm :param vm_name: guest name :param init_source: source file """ if vm.is_alive(): virsh.destroy(vm_name) virsh.attach_disk(vm_name, init_source, target_device, " --type %s --sourcetype file --config" % device_type, debug=True) def update_device(vm_name, init_iso, options, start_vm): """ Update device iso file for test case :param vm_name: guest name :param init_iso: source file :param options: update-device option :param start_vm: guest start flag """ snippet = """ <disk type='file' device='%s'> <driver name='qemu' type='raw'/> <source file='%s'/> <target dev='%s'/> <readonly/> </disk> """ % (device_type, init_iso, target_device) update_iso_file = open(update_iso_xml, "w") update_iso_file.write(snippet) update_iso_file.close() cmd_options = "--force " if options == "--config" or start_vm == "no": cmd_options += " --config" # Give domain the ISO image file virsh.update_device(domainarg=vm_name, filearg=update_iso_xml, flagstr=cmd_options, debug=True) vm_name = params.get("main_vm") vm = env.get_vm(vm_name) vm_ref = params.get("change_media_vm_ref") action = params.get("change_media_action") start_vm = params.get("start_vm") options = params.get("change_media_options") device_type = params.get("change_media_device_type", "cdrom") target_device = params.get("change_media_target_device", "hdc") source_name = params.get("change_media_source") status_error = params.get("status_error", "no") check_file = params.get("change_media_check_file") update_iso_xml_name = params.get("change_media_update_iso_xml") init_iso_name = params.get("change_media_init_iso") old_iso_name = params.get("change_media_old_iso") new_iso_name = params.get("change_media_new_iso") source_path = params.get("change_media_source_path", "yes") if device_type not in ['cdrom', 'floppy']: raise error.TestNAError("Got a invalid device type:/n%s") % device_type iso_dir = os.path.join(data_dir.get_tmp_dir(), "tmp") old_iso = os.path.join(iso_dir, old_iso_name) new_iso = os.path.join(iso_dir, new_iso_name) update_iso_xml = os.path.join(iso_dir, update_iso_xml_name) if not os.path.exists(iso_dir): os.mkdir(iso_dir) if not init_iso_name: init_iso = "" else: init_iso = os.path.join(iso_dir, init_iso_name) if vm_ref == "name": vm_ref = vm_name env_pre(old_iso, new_iso) # Check domain's disk device disk_blk = vm_xml.VMXML.get_disk_blk(vm_name) logging.info("disk_blk %s" % disk_blk) if target_device not in disk_blk: logging.info("Adding device") add_device(vm_name) if vm.is_alive() and start_vm == "no": logging.info("Destroying guest...") vm.destroy() elif vm.is_dead() and start_vm == "yes": logging.info("Starting guest...") vm.start() # If test target is floppy, you need to set selinux to Permissive mode. update_device(vm_name, init_iso, options, start_vm) # Libvirt will ignore --source when action is eject if action == "--eject ": source = "" else: source = os.path.join(iso_dir, source_name) if source_path == "no": source = source_name all_options = action + options + " " + source result = virsh.change_media(vm_ref, target_device, all_options, ignore_status=True, debug=True) if status_error == "yes": if start_vm == "no" and vm.is_dead(): try: vm.start() except virt_vm.VMStartError, detail: result.exit_status = 1 result.stderr = str(detail) if start_vm == "yes" and vm.is_alive(): vm.destroy(gracefully=False) try: vm.start() except virt_vm.VMStartError, detail: result.exit_status = 1 result.stderr = str(detail)
def run(test, params, env): """ Test command: virsh change-media. The command changes the media used by CD or floppy drives. Test steps: 1. Prepare test environment. 2. Perform virsh change-media operation. 3. Recover test environment. 4. Confirm the test result. """ @error_context.context_aware def env_pre(old_iso, new_iso): """ Prepare ISO image for test :param old_iso: sourse file for insert :param new_iso: sourse file for update """ error_context.context("Preparing ISO images") process.run("dd if=/dev/urandom of=%s/old bs=1M count=1" % iso_dir, shell=True) process.run("dd if=/dev/urandom of=%s/new bs=1M count=1" % iso_dir, shell=True) process.run("mkisofs -o %s %s/old" % (old_iso, iso_dir), shell=True) process.run("mkisofs -o %s %s/new" % (new_iso, iso_dir), shell=True) @error_context.context_aware def check_media(session, target_file, action, rw_test=False): """ Check guest cdrom/floppy files :param session: guest session :param target_file: the expected files :param action: test case action """ if target_device == "hdc" or target_device == "sdc": drive_name = session.cmd("cat /proc/sys/dev/cdrom/info | grep -i 'drive name'", ignore_all_errors=True).split()[2] if action != "--eject ": error_context.context("Checking guest %s files" % target_device) if target_device == "hdc" or target_device == "sdc": mount_cmd = "mount /dev/%s /media" % drive_name else: if session.cmd_status("ls /dev/fd0"): session.cmd("mknod /dev/fd0 b 2 0") mount_cmd = "mount /dev/fd0 /media" session.cmd(mount_cmd) if rw_test: target_file = "/media/rw_test.txt" session.cmd("touch %s" % target_file) session.cmd("echo 'Hello World'> %s" % target_file) output = session.get_command_output("cat %s" % target_file) logging.debug("cat %s output: %s", target_file, output) else: session.cmd("test -f /media/%s" % target_file) session.cmd("umount /media") else: error_context.context("Ejecting guest cdrom files") if target_device == "hdc" or target_device == "sdc": if session.cmd_status("mount /dev/%s /media -o loop" % drive_name) == 32: logging.info("Eject succeeded") else: if session.cmd_status("ls /dev/fd0"): session.cmd("mknod /dev/fd0 b 2 0") if session.cmd_status("mount /dev/fd0 /media -o loop") == 32: logging.info("Eject succeeded") def add_device(vm_name, init_source="''"): """ Add device for test vm :param vm_name: guest name :param init_source: source file """ if vm.is_alive(): virsh.destroy(vm_name) device_target_bus = params.get("device_target_bus", "ide") virsh.attach_disk(vm_name, init_source, target_device, "--type %s --sourcetype file --targetbus %s --config" % (device_type, device_target_bus), debug=True) def update_device(vm_name, init_iso, options, start_vm): """ Update device iso file for test case :param vm_name: guest name :param init_iso: source file :param options: update-device option :param start_vm: guest start flag """ if 'disk_alias' not in locals() or disk_alias is None: disk_alias_update = "" else: disk_alias_update = disk_alias device_target_bus = params.get("device_target_bus", "ide") snippet = """ <disk type='file' device='%s'> <driver name='qemu' type='raw'/> <source file='%s'/> <target dev='%s' bus='%s'/> <readonly/> <alias name='%s'/> </disk> """ % (device_type, init_iso, target_device, device_target_bus, disk_alias_update) logging.info("Update xml is %s", snippet) with open(update_iso_xml, "w") as update_iso_file: update_iso_file.write(snippet) cmd_options = "--force " if options == "--config" or start_vm == "no": cmd_options += " --config" # Give domain the ISO image file return virsh.update_device(domainarg=vm_name, filearg=update_iso_xml, flagstr=cmd_options, debug=True) vm_name = params.get("main_vm") vm = env.get_vm(vm_name) vm_ref = params.get("change_media_vm_ref") action = params.get("change_media_action") start_vm = params.get("start_vm") options = params.get("change_media_options") device_type = params.get("change_media_device_type", "cdrom") target_device = params.get("change_media_target_device", "hdc") source_name = params.get("change_media_source") status_error = "yes" == params.get("status_error", "no") check_file = params.get("change_media_check_file") update_iso_xml_name = params.get("change_media_update_iso_xml") init_iso_name = params.get("change_media_init_iso") old_iso_name = params.get("change_media_old_iso") new_iso_name = params.get("change_media_new_iso") source_path = params.get("change_media_source_path", "yes") if device_type not in ['cdrom', 'floppy']: test.cancel("Got a invalid device type:/n%s" % device_type) try: utils_path.find_command("mkisofs") except utils_path.CmdNotFoundError: test.cancel("Command 'mkisofs' is missing. You must " "install it (try 'genisoimage' package.") # Check virsh command option if options and not status_error: libvirt.virsh_cmd_has_option('change-media', options) # Backup for recovery. vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) try: iso_dir = os.path.join(data_dir.get_tmp_dir(), "tmp") old_iso = os.path.join(iso_dir, old_iso_name) new_iso = os.path.join(iso_dir, new_iso_name) update_iso_xml = os.path.join(iso_dir, update_iso_xml_name) if not os.path.exists(iso_dir): os.mkdir(iso_dir) if not init_iso_name: init_iso = "" else: init_iso = os.path.join(iso_dir, init_iso_name) if vm_ref == "name": vm_ref = vm_name env_pre(old_iso, new_iso) # Check domain's disk device disk_blk = vm_xml.VMXML.get_disk_blk(vm_name) logging.info("disk_blk %s", disk_blk) if target_device not in disk_blk: logging.info("Adding device") add_device(vm_name) if vm.is_alive() and start_vm == "no": logging.info("Destroying guest...") vm.destroy() elif vm.is_dead() and start_vm == "yes": logging.info("Starting guest...") vm.start() disk_alias = libvirt.get_disk_alias(vm) logging.debug("disk_alias is %s", disk_alias) # If test target is floppy, you need to set selinux to Permissive mode. result = update_device(vm_name, init_iso, options, start_vm) # If the selinux is set to enforcing, if we FAIL, then just SKIP force_SKIP = False if result.exit_status == 1 and utils_misc.selinux_enforcing() and \ result.stderr.count("unable to execute QEMU command 'change':"): force_SKIP = True # Libvirt will ignore --source when action is eject if action == "--eject ": source = "" else: source = os.path.join(iso_dir, source_name) if source_path == "no": source = source_name # For read&write floppy test, the iso media need a writeable fs rw_floppy_test = "yes" == params.get("rw_floppy_test", "no") if rw_floppy_test: process.run("mkfs.ext3 -F %s" % source, shell=True) all_options = action + options + " " + source result = virsh.change_media(vm_ref, target_device, all_options, ignore_status=True, debug=True) if status_error: if start_vm == "no" and vm.is_dead(): try: vm.start() except virt_vm.VMStartError as detail: result.exit_status = 1 result.stderr = str(detail) if start_vm == "yes" and vm.is_alive(): vm.destroy(gracefully=False) try: vm.start() except virt_vm.VMStartError as detail: result.exit_status = 1 result.stderr = str(detail) status = result.exit_status if not status_error: if 'print-xml' in options: vmxml_new = vm_xml.VMXML.new_from_dumpxml(vm_name) if source in vmxml_new: test.fail("Run command with 'print-xml'" " option, unexpected device was" " found in domain xml") else: if options == "--config" and vm.is_alive(): vm.destroy() if vm.is_dead(): vm.start() if 'block' in options and 'eject' not in action: vmxml_new = vm_xml.VMXML.new_from_dumpxml(vm_name) logging.debug("vmxml: %s", vmxml_new) if not vm_xml.VMXML.check_disk_type(vm_name, source, "block"): test.fail("Disk isn't a 'block' device") session = vm.wait_for_login() check_media(session, check_file, action, rw_floppy_test) session.close() # Negative testing if status_error: if status: logging.info("Expected error (negative testing). Output: %s", result.stderr.strip()) else: test.fail("Unexpected return code %d " "(negative testing)" % status) # Positive testing else: if status: if force_SKIP: test.cancel("SELinux is set to enforcing and has " "resulted in this test failing to open " "the iso file for a floppy.") test.fail("Unexpected error (positive testing). " "Output: %s" % result.stderr.strip()) else: logging.info("Expected success. Output: %s", result.stdout.strip()) finally: # Clean the iso dir and clean the device update_device(vm_name, "", options, start_vm) vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() utils_misc.safe_rmdir(iso_dir)
def run_virsh_change_media(test, params, env): """ Test command: virsh change-media. The command changes the media used by CD or floppy drives. Test steps: 1. Prepare test environment. 2. Perform virsh change-media operation. 3. Recover test environment. 4. Confirm the test result. """ @error.context_aware def env_pre(old_iso, new_iso): """ Prepare ISO image for test :param old_iso: sourse file for insert :param new_iso: sourse file for update """ error.context("Preparing ISO images") utils.run("dd if=/dev/urandom of=%s/old bs=10M count=1" % cdrom_dir) utils.run("dd if=/dev/urandom of=%s/new bs=10M count=1" % cdrom_dir) utils.run("mkisofs -o %s %s/old" % (old_iso, cdrom_dir)) utils.run("mkisofs -o %s %s/new" % (new_iso, cdrom_dir)) @error.context_aware def check_media(session, target_file, action): """ Check guest cdrom files :param session: guest session :param target_file: the expected files @action: action: test case action """ if action != "--eject ": error.context("Checking guest cdrom files") session.cmd("mount /dev/cdrom /media || mount /dev/cdrom /media") session.cmd("test -f /media/%s" % target_file) session.cmd("umount /dev/cdrom") else: error.context("Ejecting guest cdrom files") if session.cmd_status("mount /dev/cdrom /media -o loop") == 32: logging.info("Eject succeeded") def add_cdrom_device(vm_name, init_cdrom): """ Add cdrom device for test vm :param vm_name: guest name :param init_cdrom: source file """ if vm.is_alive(): virsh.destroy(vm_name) virsh.attach_disk(vm_name, init_cdrom, disk_device, " --type cdrom --sourcetype file --config", debug=True) def update_cdrom(vm_name, init_iso, options, start_vm): """ Update cdrom iso file for test case :param vm_name: guest name :param init_iso: source file :param options: update-device option :param start_vm: guest start flag """ snippet = """ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='%s'/> <target dev='%s' bus='ide'/> <readonly/> </disk> """ % (init_iso, disk_device) update_iso_file = open(update_iso_xml, "w") update_iso_file.write(snippet) update_iso_file.close() cmd_options = "--force " if options == "--config" or start_vm == "no": cmd_options += " --config" # Give domain the ISO image file virsh.update_device(domainarg=vm_name, filearg=update_iso_xml, flagstr=cmd_options, debug=True) vm_name = params.get("main_vm") vm = env.get_vm(vm_name) vm_ref = params.get("change_media_vm_ref") action = params.get("change_media_action") start_vm = params.get("start_vm") options = params.get("change_media_options") disk_device = params.get("change_media_disk_device") libvirtd = params.get("libvirtd", "on") source_name = params.get("change_media_source") status_error = params.get("status_error", "no") check_file = params.get("change_media_check_file") init_cdrom = params.get("change_media_init_cdrom") update_iso_xml_name = params.get("change_media_update_iso_xml") init_iso_name = params.get("change_media_init_iso") old_iso_name = params.get("change_media_old_iso") new_iso_name = params.get("change_media_new_iso") source_path = params.get("change_media_source_path", "yes") cdrom_dir = os.path.join(test.tmpdir, "tmp") old_iso = os.path.join(cdrom_dir, old_iso_name) new_iso = os.path.join(cdrom_dir, new_iso_name) update_iso_xml = os.path.join(cdrom_dir, update_iso_xml_name) if not os.path.exists(cdrom_dir): os.mkdir(cdrom_dir) if not init_iso_name: init_iso = "" else: init_iso = os.path.join(cdrom_dir, init_iso_name) if vm_ref == "name": vm_ref = vm_name env_pre(old_iso, new_iso) # Check domain's disk device disk_blk = vm_xml.VMXML.get_disk_blk(vm_name) logging.info("disk_blk %s" % disk_blk) if disk_device not in disk_blk: logging.info("Adding cdrom device") add_cdrom_device(vm_name, init_cdrom) if vm.is_alive() and start_vm == "no": logging.info("Destroying guest...") vm.destroy() elif vm.is_dead() and start_vm == "yes": logging.info("Starting guest...") vm.start() update_cdrom(vm_name, init_iso, options, start_vm) if libvirtd == "off": utils_libvirtd.libvirtd_stop() # Libvirt will ignore --source when action is eject if action == "--eject ": source = "" else: source = os.path.join(cdrom_dir, source_name) if source_path == "no": source = source_name all_options = action + options + " " + source result = virsh.change_media(vm_ref, disk_device, all_options, ignore_status=True, debug=True) if status_error == "yes": if start_vm == "no" and vm.is_dead(): try: vm.start() except Exception, detail: result.exit_status = 1 result.stderr = str(detail)
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: if event in ['start', 'restore', 'create', 'define', 'undefine']: 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") 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) expected_events_list.append("'lifecycle' for %s:" " Shutdown Finished after guest request") expected_events_list.append("'lifecycle' for %s:" " Stopped Shutdown") else: os.kill(dom.get_pid(), getattr(signal, signal_name)) expected_events_list.append("'lifecycle' for %s:" " Shutdown Finished after host request") expected_events_list.append("'lifecycle' for %s:" " Stopped Shutdown") 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 == "change-media": target_device = "hdc" 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 --config") dom.start() all_options = new_disk + " --insert" virsh.change_media(dom.name, target_device, all_options, ignore_status=True, debug=True) expected_events_list.append("'tray-change' for %s disk ide0-1-0:" " opened") expected_events_list.append("'tray-change' for %s disk ide0-1-0:" " closed") all_options = new_disk + " --eject" virsh.change_media(dom.name, target_device, all_options, ignore_status=True, debug=True) expected_events_list.append("'tray-change' for %s disk ide0-1-0:" " opened") 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]