def run(test, params, env): """ Test the virsh pool commands (1) Define a given type pool (2) List pool with '--inactive --type' options (3) Dumpxml for the pool (4) Undefine the pool (5) Define pool by using the XML file in step (3) (6) Build the pool(except 'disk' type pool For 'fs' type pool, cover --overwrite and --no-overwrite options (7) Start the pool (8) List pool with '--persistent --type' options (9) Mark pool autostart (10) List pool with '--autostart --type' options (11) Restart libvirtd and list pool with '--autostart --persistent' options (12) Destroy the pool (13) Unmark pool autostart (14) Repeat step (11) (15) Start the pool (16) Get pool info (17) Get pool uuid by name (18) Get pool name by uuid (19) Refresh the pool For 'dir' type pool, touch a file under target path and refresh again to make the new file show in vol-list. (20) Check pool 'Capacity', 'Allocation' and 'Available' Create a over size vol in pool(expect fail), then check these values (21) Undefine the pool, and this should fail as pool is still active (22) Destroy the pool (23) Delete pool for 'dir' type pool. After the command, the pool object will still exist but target path will be deleted (24) Undefine the pool """ # Initialize the variables pool_name = params.get("pool_name", "temp_pool_1") pool_type = params.get("pool_type", "dir") pool_target = params.get("pool_target", "") source_format = params.get("source_format", "") source_name = params.get("pool_source_name", "gluster-vol1") source_path = params.get("pool_source_path", "/") new_pool_name = params.get("new_pool_name", "") build_option = params.get("build_option", "") iscsi_initiator = params.get("iscsi_initiator", "") same_source_test = "yes" == params.get("same_source_test", "no") customize_initiator_iqn = "yes" == params.get("customize_initiator_iqn", "no") # The file for dumped pool xml poolxml = os.path.join(data_dir.get_tmp_dir(), "pool.xml.tmp") if os.path.dirname(pool_target) is "": pool_target = os.path.join(data_dir.get_tmp_dir(), pool_target) vol_name = params.get("volume_name", "temp_vol_1") # Use pool name as VG name status_error = "yes" == params.get("status_error", "no") vol_path = os.path.join(pool_target, vol_name) ip_protocal = params.get('ip_protocal', 'ipv4') if not libvirt_version.version_compare(1, 0, 0): if pool_type == "gluster": test.cancel("Gluster pool is not supported in current" " libvirt version.") if not libvirt_version.version_compare(4, 7, 0): if pool_type == "iscsi-direct": test.cancel("iSCSI-direct pool is not supported in current" "libvirt version.") def check_pool_list(pool_name, option="--all", expect_error=False): """ Check pool by running pool-list command with given option. :param pool_name: Name of the pool :param option: option for pool-list command :param expect_error: Boolean value, expect command success or fail """ found = False # Get the list stored in a variable result = virsh.pool_list(option, ignore_status=True) utlv.check_exit_status(result, False) output = re.findall(r"(\S+)\ +(\S+)\ +(\S+)", str(result.stdout.strip())) for item in output: if pool_name in item[0]: found = True break if found: logging.debug("Find pool '%s' in pool list.", pool_name) else: logging.debug("Not find pool %s in pool list.", pool_name) if expect_error and found: test.fail("Unexpect pool '%s' exist." % pool_name) if not expect_error and not found: test.fail("Expect pool '%s' doesn't exist." % pool_name) def check_vol_list(vol_name, pool_name): """ Check volume from the list :param vol_name: Name of the volume :param pool_name: Name of the pool """ found = False # Get the volume list stored in a variable result = virsh.vol_list(pool_name, ignore_status=True) utlv.check_exit_status(result) output = re.findall(r"(\S+)\ +(\S+)", str(result.stdout.strip())) for item in output: if vol_name in item[0]: found = True break if found: logging.debug("Find volume '%s' in pool '%s'.", vol_name, pool_name) else: test.fail("Not find volume '%s' in pool '%s'." % (vol_name, pool_name)) def is_in_range(actual, expected, error_percent): deviation = 100 - (100 * (float(actual) / float(expected))) logging.debug("Deviation: %0.2f%%", float(deviation)) return float(deviation) <= float(error_percent) def check_pool_info(pool_info, check_point, value): """ Check the pool name, uuid, etc. :param pool_info: A dict include pool's information :param key: Key of pool info dict, available value: Name, UUID, State Persistent, Autostart, Capacity, Allocation, Available :param value: Expect value of pool_info[key] """ if pool_info is None: test.fail("Pool info dictionary is needed.") val_tup = ('Capacity', 'Allocation', 'Available') if check_point in val_tup and float(value.split()[0]): # As from bytes to GiB, could cause deviation, and it should not # exceed 1 percent. if is_in_range(float(pool_info[check_point].split()[0]), float(value.split()[0]), 1): logging.debug("Pool '%s' is '%s'.", check_point, value) else: test.fail("Pool '%s' isn't '%s'." % (check_point, value)) else: if pool_info[check_point] == value: logging.debug("Pool '%s' is '%s'.", check_point, value) else: test.fail("Pool '%s' isn't '%s'." % (check_point, value)) # Stop multipathd to avoid start pool fail(For fs like pool, the new add # disk may in use by device-mapper, so start pool will report disk already # mounted error). multipathd = service.Factory.create_service("multipathd") multipathd_status = multipathd.status() if multipathd_status: multipathd.stop() # Run Testcase pvt = utlv.PoolVolumeTest(test, params) kwargs = { 'image_size': '1G', 'pre_disk_vol': ['100M'], 'source_name': source_name, 'source_path': source_path, 'source_format': source_format, 'persistent': True, 'ip_protocal': ip_protocal, 'emulated_image': "emulated-image", 'pool_target': pool_target, 'iscsi_initiator': iscsi_initiator } params.update(kwargs) try: _pool = libvirt_storage.StoragePool() # Step (1) # Pool define pvt.pre_pool(**params) # Step (2) # Pool list option = "--inactive --type %s" % pool_type check_pool_list(pool_name, option) # Step (3) # Pool dumpxml xml = virsh.pool_dumpxml(pool_name, to_file=poolxml) logging.debug("Pool '%s' XML:\n%s", pool_name, xml) # Update pool name if new_pool_name: if "/" in new_pool_name: new_pool_name = new_pool_name.replace("/", "\/") logging.debug(new_pool_name) p_xml = pool_xml.PoolXML.new_from_dumpxml(pool_name) p_xml.name = new_pool_name del p_xml.uuid poolxml = p_xml.xml logging.debug("XML after update pool name:\n%s" % p_xml) # Update host name if same_source_test: s_xml = p_xml.get_source() s_xml.host_name = "192.168.1.1" p_xml.set_source(s_xml) poolxml = p_xml.xml logging.debug("XML after update host name:\n%s" % p_xml) if customize_initiator_iqn: initiator_iqn = params.get("initiator_iqn", "iqn.2018-07.com.virttest:pool.target") p_xml = pool_xml.PoolXML.new_from_dumpxml(pool_name) s_node = p_xml.xmltreefile.find('/source') i_node = ET.SubElement(s_node, 'initiator') ET.SubElement(i_node, 'iqn', {'name': initiator_iqn}) p_xml.xmltreefile.write() poolxml = p_xml.xml logging.debug('XML after add Multi-IQN:\n%s' % p_xml) # Step (4) # Undefine pool if not same_source_test: result = virsh.pool_undefine(pool_name) utlv.check_exit_status(result) check_pool_list(pool_name, "--all", True) # Step (5) # Define pool from XML file result = virsh.pool_define(poolxml, debug=True) # Give error msg when exit status is not expected if "/" in new_pool_name and not result.exit_status: error_msg = "https://bugzilla.redhat.com/show_bug.cgi?id=639923 " error_msg += "is helpful for tracing this bug." logging.error(error_msg) if "." in new_pool_name and result.exit_status: error_msg = "https://bugzilla.redhat.com/show_bug.cgi?id=1333248 " error_msg += "is helpful for tracing this bug." logging.error(error_msg) if same_source_test and not result.exit_status: error_msg = "https://bugzilla.redhat.com/show_bug.cgi?id=1171984 " error_msg += "is helpful for tracing this bug." logging.error(error_msg) utlv.check_exit_status(result, status_error) if not result.exit_status: # Step (6) # Buid pool # '--overwrite/--no-overwrite' just for fs/disk/logiacl type pool # disk/fs pool: as prepare step already make label and create filesystem # for the disk, use '--overwrite' is necessary # logical_pool: build pool will fail if VG already exist, BZ#1373711 if new_pool_name: pool_name = new_pool_name if pool_type != "logical": result = virsh.pool_build(pool_name, build_option, ignore_status=True) utlv.check_exit_status(result) # Step (7) # Pool start result = virsh.pool_start(pool_name, debug=True, ignore_status=True) utlv.check_exit_status(result) # Step (8) # Pool list option = "--persistent --type %s" % pool_type check_pool_list(pool_name, option) # Step (9) # Pool autostart result = virsh.pool_autostart(pool_name, ignore_status=True) utlv.check_exit_status(result) # Step (10) # Pool list option = "--autostart --type %s" % pool_type check_pool_list(pool_name, option) # Step (11) # Restart libvirtd and check the autostart pool utils_libvirtd.libvirtd_restart() option = "--autostart --persistent" check_pool_list(pool_name, option) # Step (12) # Pool destroy if virsh.pool_destroy(pool_name): logging.debug("Pool %s destroyed.", pool_name) else: test.fail("Destroy pool % failed." % pool_name) # Step (13) # Pool autostart disable result = virsh.pool_autostart(pool_name, "--disable", ignore_status=True) utlv.check_exit_status(result) # Step (14) # Repeat step (11) utils_libvirtd.libvirtd_restart() option = "--autostart" check_pool_list(pool_name, option, True) # Step (15) # Pool start # When libvirtd starts up, it'll check to see if any of the storage # pools have been activated externally. If so, then it'll mark the # pool as active. This is independent of autostart. # So a directory based storage pool is thus pretty much always active, # and so as the SCSI pool. if pool_type not in ["dir", 'scsi']: result = virsh.pool_start(pool_name, ignore_status=True) utlv.check_exit_status(result) # Step (16) # Pool info pool_info = _pool.pool_info(pool_name) logging.debug("Pool '%s' info:\n%s", pool_name, pool_info) # Step (17) # Pool UUID result = virsh.pool_uuid(pool_info["Name"], ignore_status=True) utlv.check_exit_status(result) check_pool_info(pool_info, "UUID", result.stdout.strip()) # Step (18) # Pool Name result = virsh.pool_name(pool_info["UUID"], ignore_status=True) utlv.check_exit_status(result) check_pool_info(pool_info, "Name", result.stdout.strip()) # Step (19) # Pool refresh for 'dir' type pool if pool_type == "dir": os.mknod(vol_path) result = virsh.pool_refresh(pool_name) utlv.check_exit_status(result) check_vol_list(vol_name, pool_name) # Step (20) # Create an over size vol in pool(expect fail), then check pool: # 'Capacity', 'Allocation' and 'Available' # For NFS type pool, there's a bug(BZ#1077068) about allocate volume, # and glusterfs pool not support create volume, so not test them if pool_type != "netfs": vol_capacity = "10000G" vol_allocation = "10000G" result = virsh.vol_create_as("oversize_vol", pool_name, vol_capacity, vol_allocation, "raw") utlv.check_exit_status(result, True) new_info = _pool.pool_info(pool_name) check_items = ["Capacity", "Allocation", "Available"] for i in check_items: check_pool_info(pool_info, i, new_info[i]) # Step (21) # Undefine pool, this should fail as the pool is active result = virsh.pool_undefine(pool_name, ignore_status=True) utlv.check_exit_status(result, expect_error=True) check_pool_list(pool_name, "", False) # Step (22) # Pool destroy if virsh.pool_destroy(pool_name): logging.debug("Pool %s destroyed.", pool_name) else: test.fail("Destroy pool % failed." % pool_name) # Step (23) # Pool delete for 'dir' type pool if pool_type == "dir": for f in os.listdir(pool_target): os.remove(os.path.join(pool_target, f)) result = virsh.pool_delete(pool_name, ignore_status=True) utlv.check_exit_status(result) option = "--inactive --type %s" % pool_type check_pool_list(pool_name, option) if os.path.exists(pool_target): test.fail("The target path '%s' still exist." % pool_target) result = virsh.pool_start(pool_name, ignore_status=True) utlv.check_exit_status(result, True) # Step (24) # Pool undefine result = virsh.pool_undefine(pool_name, ignore_status=True) utlv.check_exit_status(result) check_pool_list(pool_name, "--all", True) finally: # Clean up try: pvt.cleanup_pool(**params) utlv.setup_or_cleanup_iscsi(False) except exceptions.TestFail as detail: logging.error(str(detail)) if multipathd_status: multipathd.start() if os.path.exists(poolxml): os.remove(poolxml)
def create_pool(): """ Define and start a pool. """ sp = libvirt_storage.StoragePool() if create_by_xml: p_xml = pool_xml.PoolXML(pool_type=pool_type) p_xml.name = pool_name s_xml = pool_xml.SourceXML() s_xml.vg_name = disk_src_pool source_host = [] for (host_name, host_port) in zip(disk_src_host.split(), disk_src_port.split()): source_host.append({'name': host_name, 'port': host_port}) s_xml.hosts = source_host if auth_type: s_xml.auth_type = auth_type if auth_user: s_xml.auth_username = auth_user if auth_usage: s_xml.secret_usage = auth_usage p_xml.source = s_xml logging.debug("Pool xml: %s", p_xml) p_xml.xmltreefile.write() ret = virsh.pool_define(p_xml.xml, **virsh_dargs) libvirt.check_exit_status(ret) ret = virsh.pool_build(pool_name, **virsh_dargs) libvirt.check_exit_status(ret) ret = virsh.pool_start(pool_name, **virsh_dargs) libvirt.check_exit_status(ret) else: auth_opt = "" if client_name and client_key: auth_opt = ( "--auth-type %s --auth-username %s --secret-usage '%s'" % (auth_type, auth_user, auth_usage)) if not sp.define_rbd_pool( pool_name, mon_host, disk_src_pool, extra=auth_opt): test.fail("Failed to define storage pool") if not sp.build_pool(pool_name): test.fail("Failed to build storage pool") if not sp.start_pool(pool_name): test.fail("Failed to start storage pool") # Check pool operation ret = virsh.pool_refresh(pool_name, **virsh_dargs) libvirt.check_exit_status(ret) ret = virsh.pool_uuid(pool_name, **virsh_dargs) libvirt.check_exit_status(ret) # pool-info pool_info = sp.pool_info(pool_name) if pool_info["Autostart"] != 'no': test.fail("Failed to check pool information") # pool-autostart if not sp.set_pool_autostart(pool_name): test.fail("Failed to set pool autostart") pool_info = sp.pool_info(pool_name) if pool_info["Autostart"] != 'yes': test.fail("Failed to check pool information") # pool-autostart --disable if not sp.set_pool_autostart(pool_name, "--disable"): test.fail("Failed to set pool autostart") # If port is not pre-configured, port value should not be hardcoded in pool information. if "yes" == params.get("rbd_port", "no"): if 'port' in virsh.pool_dumpxml(pool_name): test.fail("port attribute should not be in pool information") # find-storage-pool-sources-as if "yes" == params.get("find_storage_pool_sources_as", "no"): ret = virsh.find_storage_pool_sources_as("rbd", mon_host) libvirt.check_result(ret, skip_if=unsupported_err)
def run(test, params, env): """ Test the virsh pool commands (1) Define a given type pool (2) List pool with '--inactive --type' options (3) Dumpxml for the pool (4) Undefine the pool (5) Define pool by using the XML file in step (3) (6) Build the pool(except 'disk' type pool For 'fs' type pool, cover --overwrite and --no-overwrite options (7) Start the pool (8) List pool with '--persistent --type' options (9) Mark pool autostart (10) List pool with '--autostart --type' options (11) Restart libvirtd and list pool with '--autostart --persistent' options (12) Destroy the pool (13) Unmark pool autostart (14) Repeat step (11) (15) Start the pool (16) Get pool info (17) Get pool uuid by name (18) Get pool name by uuid (19) Refresh the pool For 'dir' type pool, touch a file under target path and refresh again to make the new file show in vol-list. (20) Check pool 'Capacity', 'Allocation' and 'Available' Create a over size vol in pool(expect fail), then check these values (21) Undefine the pool, and this should fail as pool is still active (22) Destroy the pool (23) Delete pool for 'dir' type pool. After the command, the pool object will still exist but target path will be deleted (24) Undefine the pool """ # Initialize the variables pool_name = params.get("pool_name", "temp_pool_1") pool_type = params.get("pool_type", "dir") pool_target = params.get("pool_target", "") source_format = params.get("source_format", "") source_name = params.get("pool_source_name", "gluster-vol1") source_path = params.get("pool_source_path", "/") # The file for dumped pool xml pool_xml = os.path.join(test.tmpdir, "pool.xml.tmp") if os.path.dirname(pool_target) is "": pool_target = os.path.join(test.tmpdir, pool_target) vol_name = params.get("vol_name", "temp_vol_1") # Use pool name as VG name status_error = "yes" == params.get("status_error", "no") vol_path = os.path.join(pool_target, vol_name) ip_protocal = params.get('ip_protocal', 'ipv4') if not libvirt_version.version_compare(1, 0, 0): if pool_type == "gluster": raise error.TestNAError("Gluster pool is not supported in current" " libvirt version.") def check_pool_list(pool_name, option="--all", expect_error=False): """ Check pool by running pool-list command with given option. :param pool_name: Name of the pool :param option: option for pool-list command :param expect_error: Boolean value, expect command success or fail """ found = False # Get the list stored in a variable result = virsh.pool_list(option, ignore_status=True) utlv.check_exit_status(result, False) output = re.findall(r"(\S+)\ +(\S+)\ +(\S+)[\ +\n]", str(result.stdout)) for item in output: if pool_name in item[0]: found = True break if found: logging.debug("Find pool '%s' in pool list.", pool_name) else: logging.debug("Not find pool %s in pool list.", pool_name) if expect_error and found: raise error.TestFail("Unexpect pool '%s' exist." % pool_name) if not expect_error and not found: raise error.TestFail("Expect pool '%s' doesn't exist." % pool_name) def check_vol_list(vol_name, pool_name): """ Check volume from the list :param vol_name: Name of the volume :param pool_name: Name of the pool """ found = False # Get the volume list stored in a variable result = virsh.vol_list(pool_name, ignore_status=True) utlv.check_exit_status(result) output = re.findall(r"(\S+)\ +(\S+)[\ +\n]", str(result.stdout)) for item in output: if vol_name in item[0]: found = True break if found: logging.debug("Find volume '%s' in pool '%s'.", vol_name, pool_name) else: raise error.TestFail("Not find volume '%s' in pool '%s'." % (vol_name, pool_name)) def is_in_range(actual, expected, error_percent): deviation = 100 - (100 * (float(actual) / float(expected))) logging.debug("Deviation: %0.2f%%", float(deviation)) return float(deviation) <= float(error_percent) def check_pool_info(pool_info, check_point, value): """ Check the pool name, uuid, etc. :param pool_info: A dict include pool's information :param key: Key of pool info dict, available value: Name, UUID, State Persistent, Autostart, Capacity, Allocation, Available :param value: Expect value of pool_info[key] """ if pool_info is None: raise error.TestFail("Pool info dictionary is needed.") val_tup = ('Capacity', 'Allocation', 'Available') if check_point in val_tup and float(value.split()[0]): # As from bytes to GiB, could cause deviation, and it should not # exceed 1 percent. if is_in_range(float(pool_info[check_point].split()[0]), float(value.split()[0]), 1): logging.debug("Pool '%s' is '%s'.", check_point, value) else: raise error.TestFail("Pool '%s' isn't '%s'." % (check_point, value)) else: if pool_info[check_point] == value: logging.debug("Pool '%s' is '%s'.", check_point, value) else: raise error.TestFail("Pool '%s' isn't '%s'." % (check_point, value)) # Stop multipathd to avoid start pool fail(For fs like pool, the new add # disk may in use by device-mapper, so start pool will report disk already # mounted error). multipathd = service.Factory.create_service("multipathd") multipathd_status = multipathd.status() if multipathd_status: multipathd.stop() # Run Testcase pvt = utlv.PoolVolumeTest(test, params) emulated_image = "emulated-image" kwargs = { 'image_size': '1G', 'pre_disk_vol': ['1M'], 'source_name': source_name, 'source_path': source_path, 'source_format': source_format, 'persistent': True, 'ip_protocal': ip_protocal } try: _pool = libvirt_storage.StoragePool() # Step (1) # Pool define pvt.pre_pool(pool_name, pool_type, pool_target, emulated_image, **kwargs) # Step (2) # Pool list option = "--inactive --type %s" % pool_type check_pool_list(pool_name, option) # Step (3) # Pool dumpxml xml = virsh.pool_dumpxml(pool_name, to_file=pool_xml) logging.debug("Pool '%s' XML:\n%s", pool_name, xml) # Step (4) # Undefine pool result = virsh.pool_undefine(pool_name, ignore_status=True) utlv.check_exit_status(result) check_pool_list(pool_name, "--all", True) # Step (5) # Define pool from XML file result = virsh.pool_define(pool_xml) utlv.check_exit_status(result, status_error) # Step (6) # Buid pool, this step may fail for 'disk' and 'logical' types pool if pool_type not in ["disk", "logical"]: option = "" # Options --overwrite and --no-overwrite can only be used to # build a filesystem pool, but it will fail for now # if pool_type == "fs": # option = '--overwrite' result = virsh.pool_build(pool_name, option, ignore_status=True) utlv.check_exit_status(result) # Step (7) # Pool start result = virsh.pool_start(pool_name, ignore_status=True) utlv.check_exit_status(result) # Step (8) # Pool list option = "--persistent --type %s" % pool_type check_pool_list(pool_name, option) # Step (9) # Pool autostart result = virsh.pool_autostart(pool_name, ignore_status=True) utlv.check_exit_status(result) # Step (10) # Pool list option = "--autostart --type %s" % pool_type check_pool_list(pool_name, option) # Step (11) # Restart libvirtd and check the autostart pool utils_libvirtd.libvirtd_restart() option = "--autostart --persistent" check_pool_list(pool_name, option) # Step (12) # Pool destroy if virsh.pool_destroy(pool_name): logging.debug("Pool %s destroyed.", pool_name) else: raise error.TestFail("Destroy pool % failed." % pool_name) # Step (13) # Pool autostart disable result = virsh.pool_autostart(pool_name, "--disable", ignore_status=True) utlv.check_exit_status(result) # Step (14) # Repeat step (11) utils_libvirtd.libvirtd_restart() option = "--autostart" check_pool_list(pool_name, option, True) # Step (15) # Pool start # When libvirtd starts up, it'll check to see if any of the storage # pools have been activated externally. If so, then it'll mark the # pool as active. This is independent of autostart. # So a directory based storage pool is thus pretty much always active, # and so as the SCSI pool. if pool_type not in ["dir", 'scsi']: result = virsh.pool_start(pool_name, ignore_status=True) utlv.check_exit_status(result) # Step (16) # Pool info pool_info = _pool.pool_info(pool_name) logging.debug("Pool '%s' info:\n%s", pool_name, pool_info) # Step (17) # Pool UUID result = virsh.pool_uuid(pool_info["Name"], ignore_status=True) utlv.check_exit_status(result) check_pool_info(pool_info, "UUID", result.stdout.strip()) # Step (18) # Pool Name result = virsh.pool_name(pool_info["UUID"], ignore_status=True) utlv.check_exit_status(result) check_pool_info(pool_info, "Name", result.stdout.strip()) # Step (19) # Pool refresh for 'dir' type pool if pool_type == "dir": os.mknod(vol_path) result = virsh.pool_refresh(pool_name) utlv.check_exit_status(result) check_vol_list(vol_name, pool_name) # Step (20) # Create an over size vol in pool(expect fail), then check pool: # 'Capacity', 'Allocation' and 'Available' # For NFS type pool, there's a bug(BZ#1077068) about allocate volume, # and glusterfs pool not support create volume, so not test them if pool_type != "netfs": vol_capacity = "10000G" vol_allocation = "10000G" result = virsh.vol_create_as("oversize_vol", pool_name, vol_capacity, vol_allocation, "raw") utlv.check_exit_status(result, True) new_info = _pool.pool_info(pool_name) check_pool_info(pool_info, "Capacity", new_info['Capacity']) check_pool_info(pool_info, "Allocation", new_info['Allocation']) check_pool_info(pool_info, "Available", new_info['Available']) # Step (21) # Undefine pool, this should fail as the pool is active result = virsh.pool_undefine(pool_name, ignore_status=True) utlv.check_exit_status(result, expect_error=True) check_pool_list(pool_name, "", False) # Step (22) # Pool destroy if virsh.pool_destroy(pool_name): logging.debug("Pool %s destroyed.", pool_name) else: raise error.TestFail("Destroy pool % failed." % pool_name) # Step (23) # Pool delete for 'dir' type pool if pool_type == "dir": for f in os.listdir(pool_target): os.remove(os.path.join(pool_target, f)) result = virsh.pool_delete(pool_name, ignore_status=True) utlv.check_exit_status(result) option = "--inactive --type %s" % pool_type check_pool_list(pool_name, option) if os.path.exists(pool_target): raise error.TestFail("The target path '%s' still exist." % pool_target) result = virsh.pool_start(pool_name, ignore_status=True) utlv.check_exit_status(result, True) # Step (24) # Pool undefine result = virsh.pool_undefine(pool_name, ignore_status=True) utlv.check_exit_status(result) check_pool_list(pool_name, "--all", True) finally: # Clean up try: pvt.cleanup_pool(pool_name, pool_type, pool_target, emulated_image, **kwargs) except error.TestFail, detail: logging.error(str(detail)) if multipathd_status: multipathd.start() if os.path.exists(pool_xml): os.remove(pool_xml)
def run(test, params, env): """ Convert specific xen guest """ for v in list(params.values()): if "V2V_EXAMPLE" in v: test.cancel("Please set real value for %s" % v) if utils_v2v.V2V_EXEC is None: test.cancel('Missing command: virt-v2v') vm_name = params.get('main_vm') new_vm_name = params.get('new_vm_name') xen_host = params.get('xen_hostname') xen_host_user = params.get('xen_host_user', 'root') xen_host_passwd = params.get('xen_host_passwd', 'redhat') output_mode = params.get('output_mode') v2v_timeout = int(params.get('v2v_timeout', 1200)) status_error = 'yes' == params.get('status_error', 'no') skip_vm_check = params.get('skip_vm_check', 'no') skip_reason = params.get('skip_reason') pool_name = params.get('pool_name', 'v2v_test') pool_type = params.get('pool_type', 'dir') pool_target = params.get('pool_target_path', 'v2v_pool') pvt = libvirt.PoolVolumeTest(test, params) address_cache = env.get('address_cache') checkpoint = params.get('checkpoint', '') bk_list = ['vnc_autoport', 'vnc_encrypt', 'vnc_encrypt_warning'] error_list = [] # For construct rhv-upload option in v2v cmd output_method = params.get("output_method") rhv_upload_opts = params.get("rhv_upload_opts") storage_name = params.get('storage_name') # for get ca.crt file from ovirt engine rhv_passwd = params.get("rhv_upload_passwd") rhv_passwd_file = params.get("rhv_upload_passwd_file") ovirt_engine_passwd = params.get("ovirt_engine_password") ovirt_hostname = params.get("ovirt_engine_url").split( '/')[2] if params.get("ovirt_engine_url") else None ovirt_ca_file_path = params.get("ovirt_ca_file_path") local_ca_file_path = params.get("local_ca_file_path") def log_fail(msg): """ Log error and update error list """ logging.error(msg) error_list.append(msg) def set_graphics(virsh_instance, param): """ Set graphics attributes of vm xml """ vmxml = vm_xml.VMXML.new_from_inactive_dumpxml( vm_name, virsh_instance=virsh_instance) graphic = vmxml.xmltreefile.find('devices').find('graphics') for key in param: logging.debug('Set %s=\'%s\'' % (key, param[key])) graphic.set(key, param[key]) vmxml.sync(virsh_instance=virsh_instance) def check_grub_file(vmcheck, check): """ Check grub file content """ logging.info('Checking grub file') grub_file = utils_misc.get_bootloader_cfg(session=vmcheck.session) if not grub_file: test.error('Not found grub file') content = vmcheck.session.cmd('cat %s' % grub_file) if check == 'console_xvc0': if 'console=xvc0' in content: log_fail('"console=xvc0" still exists') def check_kernel(vmcheck): """ Check content of /etc/sysconfig/kernel """ logging.info('Checking /etc/sysconfig/kernel file') content = vmcheck.session.cmd('cat /etc/sysconfig/kernel') logging.debug(content) if 'DEFAULTKERNEL=kernel' not in content: log_fail('Not find "DEFAULTKERNEL=kernel"') elif 'DEFAULTKERNEL=kernel-xen' in content: log_fail('DEFAULTKERNEL is "kernel-xen"') def check_sound_card(vmcheck, check): """ Check sound status of vm from xml """ xml = virsh.dumpxml(vm_name, session_id=vmcheck.virsh_session_id).stdout logging.debug(xml) if check == 'sound' and '<sound model' in xml: log_fail('Sound card should be removed') if check == 'pcspk' and output_mode == 'libvirt' and "<sound model='pcspk'" not in xml: log_fail('Sound card should be "pcspk"') def check_rhsrvany_md5(vmcheck): """ Check if MD5 and SHA1 of rhsrvany.exe are correct """ logging.info('Check md5 and sha1 of rhsrvany.exe') val_md5, val_sha1 = params.get('val_md5'), params.get('val_sha1') logging.info('Expect MD5=%s, SHA1=%s', val_md5, val_sha1) if not val_md5 or not val_sha1: test.error('No MD5 or SHA1 value provided') cmd_sha1 = params.get('cmd_sha1') cmd_md5 = cmd_sha1 + ' MD5' sha1 = vmcheck.session.cmd_output( cmd_sha1, safe=True).strip().split('\n')[1].replace(' ', '') md5 = vmcheck.session.cmd_output( cmd_md5, safe=True).strip().split('\n')[1].replace(' ', '') logging.info('Actual MD5=%s, SHA1=%s', md5, sha1) if sha1 == val_sha1 and md5 == val_md5: logging.info('MD5 and SHA1 are correct') else: log_fail('MD5 or SHA1 of rhsrvany.exe not correct') def check_disk(vmcheck, count): """ Check if number of disks meets expectation """ logging.info('Expect number of disks: %d', count) actual = vmcheck.session.cmd('lsblk |grep disk |wc -l').strip() logging.info('Actual number of disks: %s', actual) if int(actual) != count: log_fail('Number of disks is wrong') def check_result(result, status_error): """ Check virt-v2v command result """ libvirt.check_exit_status(result, status_error) output = result.stdout + result.stderr if not status_error and checkpoint != 'vdsm': if output_mode == 'rhev': if not utils_v2v.import_vm_to_ovirt( params, address_cache, timeout=v2v_timeout): test.fail('Import VM failed') elif output_mode == 'libvirt': try: virsh.start(vm_name, debug=True, ignore_status=False) except Exception as e: test.fail('Start vm failed: %s', str(e)) # Check guest following the checkpoint document after convertion logging.info('Checking common checkpoints for v2v') vmchecker = VMChecker(test, params, env) params['vmchecker'] = vmchecker if params.get('skip_vm_check') != 'yes': ret = vmchecker.run() if len(ret) == 0: logging.info("All common checkpoints passed") else: logging.info('Skip checking vm after conversion: %s' % skip_reason) # Check specific checkpoints if checkpoint == 'console_xvc0': check_grub_file(vmchecker.checker, 'console_xvc0') if checkpoint in ('vnc_autoport', 'vnc_encrypt'): vmchecker.check_graphics(params[checkpoint]) if checkpoint == 'sdl': if output_mode == 'libvirt': vmchecker.check_graphics({'type': 'vnc'}) elif output_mode == 'rhev': vmchecker.check_graphics({'type': 'spice'}) if checkpoint == 'pv_with_regular_kernel': check_kernel(vmchecker.checker) if checkpoint in ['sound', 'pcspk']: check_sound_card(vmchecker.checker, checkpoint) if checkpoint == 'rhsrvany_md5': check_rhsrvany_md5(vmchecker.checker) if checkpoint == 'multidisk': check_disk(vmchecker.checker, params['disk_count']) log_check = utils_v2v.check_log(params, output) if log_check: log_fail(log_check) # Merge 2 error lists if params.get('vmchecker'): error_list.extend(params['vmchecker'].errors) # Virtio drivers will not be installed without virtio-win setup if checkpoint == 'virtio_win_unset': missing_list = params.get('missing').split(',') expect_errors = ['Not find driver: ' + x for x in missing_list] logging.debug('Expect errors: %s' % expect_errors) logging.debug('Actual errors: %s' % error_list) if set(error_list) == set(expect_errors): error_list[:] = [] else: logging.error('Virtio drivers not meet expectation') if len(error_list): test.fail('%d checkpoints failed: %s' % (len(error_list), error_list)) try: v2v_params = { 'hostname': xen_host, 'hypervisor': 'xen', 'main_vm': vm_name, 'v2v_opts': '-v -x', 'input_mode': 'libvirt', 'new_name': new_vm_name, 'password': xen_host_passwd, 'storage': params.get('output_storage', 'default'), 'network': params.get('network'), 'bridge': params.get('bridge'), 'target': params.get('target'), 'output_method': output_method, 'storage_name': storage_name, 'rhv_upload_opts': rhv_upload_opts } bk_xml = None os.environ['LIBGUESTFS_BACKEND'] = 'direct' # Setup ssh-agent access to xen hypervisor logging.info('set up ssh-agent access ') ssh_key.setup_ssh_key(xen_host, user=xen_host_user, port=22, password=xen_host_passwd) utils_misc.add_identities_into_ssh_agent() if params.get('output_format'): v2v_params.update({'output_format': params.get('output_format')}) # Build rhev related options if output_mode == 'rhev': # To RHV doesn't support 'qcow2' right now v2v_params['output_format'] = 'raw' # create different sasl_user name for different job params.update({ 'sasl_user': params.get("sasl_user") + utils_misc.generate_random_string(3) }) logging.info('sals user name is %s' % params.get("sasl_user")) # Create SASL user on the ovirt host user_pwd = "[['%s', '%s']]" % (params.get("sasl_user"), params.get("sasl_pwd")) v2v_sasl = utils_sasl.SASL(sasl_user_pwd=user_pwd) v2v_sasl.server_ip = params.get("remote_ip") v2v_sasl.server_user = params.get('remote_user') v2v_sasl.server_pwd = params.get('remote_pwd') v2v_sasl.setup(remote=True) if output_method == 'rhv_upload': # Create password file for '-o rhv_upload' to connect to ovirt with open(rhv_passwd_file, 'w') as f: f.write(rhv_passwd) # Copy ca file from ovirt to local remote.scp_from_remote(ovirt_hostname, 22, 'root', ovirt_engine_passwd, ovirt_ca_file_path, local_ca_file_path) # Create libvirt dir pool if output_mode == 'libvirt': pvt.pre_pool(pool_name, pool_type, pool_target, '') uri = utils_v2v.Uri('xen').get_uri(xen_host) # Check if xen guest exists if not virsh.domain_exists(vm_name, uri=uri): logging.error('VM %s not exists', vm_name) virsh_instance = virsh.VirshPersistent() virsh_instance.set_uri(uri) if checkpoint in bk_list: bk_xml = vm_xml.VMXML.new_from_inactive_dumpxml( vm_name, virsh_instance=virsh_instance) if checkpoint == 'guest_uuid': uuid = virsh.domuuid(vm_name, uri=uri).stdout.strip() v2v_params['main_vm'] = uuid if checkpoint in ['format_convert', 'xvda_disk']: # Get remote disk image path blklist = virsh.domblklist(vm_name, uri=uri).stdout.split('\n') logging.debug('domblklist %s:\n%s', vm_name, blklist) for line in blklist: if line.strip().startswith(('hda', 'vda', 'sda', 'xvda')): params['remote_disk_image'] = line.split()[-1] break # Local path of disk image params['img_path'] = data_dir.get_tmp_dir() + '/%s.img' % vm_name if checkpoint == 'xvda_disk': v2v_params['input_mode'] = 'disk' v2v_params['hypervisor'] = 'kvm' v2v_params.update({'input_file': params['img_path']}) # Copy remote image to local with scp remote.scp_from_remote(xen_host, 22, xen_host_user, xen_host_passwd, params['remote_disk_image'], params['img_path']) if checkpoint == 'pool_uuid': virsh.pool_start(pool_name) pooluuid = virsh.pool_uuid(pool_name).stdout.strip() v2v_params['storage'] = pooluuid if checkpoint.startswith('vnc'): vm_xml.VMXML.set_graphics_attr(vm_name, {'type': 'vnc'}, virsh_instance=virsh_instance) if checkpoint == 'vnc_autoport': params[checkpoint] = {'autoport': 'yes'} vm_xml.VMXML.set_graphics_attr(vm_name, params[checkpoint], virsh_instance=virsh_instance) elif checkpoint in ['vnc_encrypt', 'vnc_encrypt_warning']: params[checkpoint] = { 'passwd': params.get('vnc_passwd', 'redhat') } vmxml = vm_xml.VMXML.new_from_inactive_dumpxml( vm_name, virsh_instance=virsh_instance) vm_xml.VMXML.add_security_info(vmxml, params[checkpoint]['passwd'], virsh_instance=virsh_instance) logging.debug( virsh_instance.dumpxml(vm_name, extra='--security-info')) if checkpoint.startswith('libguestfs_backend'): value = checkpoint[19:] if value == 'empty': value = '' logging.info('Set LIBGUESTFS_BACKEND to "%s"', value) os.environ['LIBGUESTFS_BACKEND'] = value if checkpoint == 'same_name': logging.info('Convert guest and rename to %s', new_vm_name) v2v_params.update({'new_name': new_vm_name}) if checkpoint == 'no_passwordless_SSH': logging.info('Unset $SSH_AUTH_SOCK') os.unsetenv('SSH_AUTH_SOCK') if checkpoint in ['xml_without_image', 'format_convert']: xml_file = os.path.join(data_dir.get_tmp_dir(), '%s.xml' % vm_name) virsh.dumpxml(vm_name, to_file=xml_file, uri=uri) v2v_params['hypervisor'] = 'kvm' v2v_params['input_mode'] = 'libvirtxml' v2v_params.update({'input_file': xml_file}) if params.get('img_path'): cmd = "sed -i 's|%s|%s|' %s" % (params['remote_disk_image'], params['img_path'], xml_file) process.run(cmd) logging.debug(process.run('cat %s' % xml_file).stdout_text) if checkpoint == 'ssh_banner': session = remote.remote_login("ssh", xen_host, "22", "root", xen_host_passwd, "#") ssh_banner_content = r'"# no default banner path\n' \ r'#Banner /path/banner file\n' \ r'Banner /etc/ssh/ssh_banner"' logging.info('Create ssh_banner file') session.cmd('echo -e %s > /etc/ssh/ssh_banner' % ssh_banner_content) logging.info('Content of ssh_banner file:') logging.info(session.cmd_output('cat /etc/ssh/ssh_banner')) logging.info('Restart sshd service on xen host') session.cmd('service sshd restart') if checkpoint.startswith('virtio_win'): src_dir = params.get('virtio_win_dir') dest_dir = os.path.join(data_dir.get_tmp_dir(), 'virtio-win') iso_path = os.path.join(dest_dir, 'virtio-win.iso') if not os.path.exists(dest_dir): shutil.copytree(src_dir, dest_dir) virtio_win_env = params.get('virtio_win_env', 'VIRTIO_WIN') process.run('rpm -e virtio-win') if process.run('rpm -q virtio-win', ignore_status=True).exit_status == 0: test.error('not removed') if checkpoint.endswith('unset'): logging.info('Unset env %s' % virtio_win_env) os.unsetenv(virtio_win_env) if checkpoint.endswith('custom'): logging.info('Set env %s=%s' % (virtio_win_env, dest_dir)) os.environ[virtio_win_env] = dest_dir if checkpoint.endswith('iso_mount'): logging.info('Mount iso to /opt') process.run('mount %s /opt' % iso_path) os.environ[virtio_win_env] = '/opt' if checkpoint.endswith('iso_file'): logging.info('Set env %s=%s' % (virtio_win_env, iso_path)) os.environ[virtio_win_env] = iso_path if checkpoint == 'cdrom': xml = vm_xml.VMXML.new_from_inactive_dumpxml( vm_name, virsh_instance=virsh_instance) logging.debug(xml.xmltreefile) disks = xml.get_disk_all() logging.debug('Disks: %r', disks) for disk in list(disks.values()): # Check if vm has cdrom attached if disk.get( 'device') == 'cdrom' and disk.find('source') is None: test.error('No CDROM image attached') if checkpoint == 'vdsm': extra_pkg = params.get('extra_pkg') logging.info('Install %s', extra_pkg) utils_package.package_install(extra_pkg.split(',')) # Backup conf file for recovery for conf in params['bk_conf'].strip().split(','): logging.debug('Back up %s', conf) shutil.copyfile(conf, conf + '.bk') logging.info('Configure libvirt for vdsm') process.run('vdsm-tool configure --force') logging.info('Start vdsm service') service_manager = service.Factory.create_generic_service() service_manager.start('vdsmd') # Setup user and password user_pwd = "[['%s', '%s']]" % (params.get("sasl_user"), params.get("sasl_pwd")) v2v_sasl = utils_sasl.SASL(sasl_user_pwd=user_pwd) v2v_sasl.server_ip = 'localhost' v2v_sasl.server_user = params.get('sasl_server_user', 'root') v2v_sasl.server_pwd = params.get('sasl_server_passwd') v2v_sasl.setup() v2v_params['sasl_user'] = params.get("sasl_user") v2v_params['sasl_pwd'] = params.get("sasl_pwd") if checkpoint == 'multidisk': params['disk_count'] = 0 blklist = virsh.domblklist(vm_name, uri=uri).stdout.split('\n') logging.info(blklist) for line in blklist: if '/' in line: params['disk_count'] += 1 logging.info('Total disks: %d', params['disk_count']) # Check if xen guest exists again if not virsh.domain_exists(vm_name, uri=uri): logging.error('VM %s not exists', vm_name) # Execute virt-v2v v2v_result = utils_v2v.v2v_cmd(v2v_params) if new_vm_name: vm_name = new_vm_name params['main_vm'] = new_vm_name check_result(v2v_result, status_error) finally: # Cleanup constant files utils_v2v.cleanup_constant_files(params) process.run('ssh-agent -k') if checkpoint == 'vdsm': logging.info('Stop vdsmd') service_manager = service.Factory.create_generic_service() service_manager.stop('vdsmd') if params.get('extra_pkg'): utils_package.package_remove(params['extra_pkg'].split(',')) for conf in params['bk_conf'].strip().split(','): if os.path.exists(conf + '.bk'): logging.debug('Recover %s', conf) os.remove(conf) shutil.move(conf + '.bk', conf) logging.info('Restart libvirtd') libvirtd = utils_libvirtd.Libvirtd() libvirtd.restart() logging.info('Start network "default"') virsh.net_start('default') virsh.undefine(vm_name) if params.get('vmchecker'): params['vmchecker'].cleanup() if output_mode == 'libvirt': pvt.cleanup_pool(pool_name, pool_type, pool_target, '') if bk_xml: bk_xml.sync(virsh_instance=virsh_instance) virsh_instance.close_session() if checkpoint == 'ssh_banner': logging.info('Remove ssh_banner file') session = remote.remote_login("ssh", xen_host, "22", "root", xen_host_passwd, "#") session.cmd('rm -f /etc/ssh/ssh_banner') session.cmd('service sshd restart') if checkpoint.startswith('virtio_win'): utils_package.package_install(['virtio-win'])
blklist = virsh.domblklist(vm_name, uri=uri).stdout.split('\n') logging.debug('domblklist %s:\n%s', vm_name, blklist) for line in blklist: if line.startswith(('hda', 'vda', 'sda')): remote_disk_image = line.split()[-1] break # Local path of disk image input_file = data_dir.get_tmp_dir() + '/%s.img' % vm_name v2v_params.update({'input_file': input_file}) # Copy remote image to local with scp remote.scp_from_remote(xen_host, 22, xen_host_user, xen_host_passwd, remote_disk_image, input_file) elif checkpoint == 'pool_uuid': virsh.pool_start(pool_name) pooluuid = virsh.pool_uuid(pool_name).stdout.strip() v2v_params['storage'] = pooluuid elif checkpoint.startswith('vnc'): vm_xml.VMXML.set_graphics_attr(vm_name, {'type': 'vnc'}, virsh_instance=virsh_instance) if checkpoint == 'vnc_autoport': params[checkpoint] = {'autoport': 'yes'} vm_xml.VMXML.set_graphics_attr(vm_name, params[checkpoint], virsh_instance=virsh_instance) elif checkpoint == 'vnc_encrypt': params[checkpoint] = {'passwd': params.get('vnc_passwd', 'redhat')} vmxml = vm_xml.VMXML.new_from_inactive_dumpxml( vm_name, virsh_instance=virsh_instance) vm_xml.VMXML.add_security_info( vmxml, params[checkpoint]['passwd'], virsh_instance=virsh_instance)
def run(test, params, env): """ Test the virsh pool commands (1) Define a given type pool (2) List pool with '--inactive --type' options (3) Dumpxml for the pool (4) Undefine the pool (5) Define pool by using the XML file in step (3) (6) Build the pool(except 'disk' type pool For 'fs' type pool, cover --overwrite and --no-overwrite options (7) Start the pool (8) List pool with '--persistent --type' options (9) Mark pool autostart (10) List pool with '--autostart --type' options (11) Restart libvirtd and list pool with '--autostart --persistent' options (12) Destroy the pool (13) Unmark pool autostart (14) Repeat step (11) (15) Start the pool (16) Get pool info (17) Get pool uuid by name (18) Get pool name by uuid (19) Refresh the pool For 'dir' type pool, touch a file under target path and refresh again to make the new file show in vol-list. (20) Check pool 'Capacity', 'Allocation' and 'Available' Create a over size vol in pool(expect fail), then check these values (21) Undefine the pool, and this should fail as pool is still active (22) Destroy the pool (23) Delete pool for 'dir' type pool. After the command, the pool object will still exist but target path will be deleted (24) Undefine the pool """ # Initialize the variables pool_name = params.get("pool_name", "temp_pool_1") pool_type = params.get("pool_type", "dir") pool_target = params.get("pool_target", "") source_format = params.get("source_format", "") source_name = params.get("pool_source_name", "gluster-vol1") source_path = params.get("pool_source_path", "/") # The file for dumped pool xml pool_xml = os.path.join(test.tmpdir, "pool.xml.tmp") if os.path.dirname(pool_target) is "": pool_target = os.path.join(test.tmpdir, pool_target) vol_name = params.get("vol_name", "temp_vol_1") # Use pool name as VG name status_error = "yes" == params.get("status_error", "no") vol_path = os.path.join(pool_target, vol_name) ip_protocal = params.get("ip_protocal", "ipv4") if not libvirt_version.version_compare(1, 0, 0): if pool_type == "gluster": raise error.TestNAError("Gluster pool is not supported in current" " libvirt version.") def check_exit_status(result, expect_error=False): """ Check the exit status of virsh commands. :param result: Virsh command result object :param expect_error: Boolean value, expect command success or fail """ if not expect_error: if result.exit_status != 0: raise error.TestFail(result.stderr) else: logging.debug("Command output:\n%s", result.stdout.strip()) elif expect_error and result.exit_status == 0: raise error.TestFail("Expect fail, but run successfully.") def check_pool_list(pool_name, option="--all", expect_error=False): """ Check pool by running pool-list command with given option. :param pool_name: Name of the pool :param option: option for pool-list command :param expect_error: Boolean value, expect command success or fail """ found = False # Get the list stored in a variable result = virsh.pool_list(option, ignore_status=True) check_exit_status(result, False) output = re.findall(r"(\S+)\ +(\S+)\ +(\S+)[\ +\n]", str(result.stdout)) for item in output: if pool_name in item[0]: found = True break if found: logging.debug("Find pool '%s' in pool list.", pool_name) else: logging.debug("Not find pool %s in pool list.", pool_name) if expect_error and found: raise error.TestFail("Unexpect pool '%s' exist." % pool_name) if not expect_error and not found: raise error.TestFail("Expect pool '%s' doesn't exist." % pool_name) def check_vol_list(vol_name, pool_name): """ Check volume from the list :param vol_name: Name of the volume :param pool_name: Name of the pool """ found = False # Get the volume list stored in a variable result = virsh.vol_list(pool_name, ignore_status=True) check_exit_status(result) output = re.findall(r"(\S+)\ +(\S+)[\ +\n]", str(result.stdout)) for item in output: if vol_name in item[0]: found = True break if found: logging.debug("Find volume '%s' in pool '%s'.", vol_name, pool_name) else: raise error.TestFail("Not find volume '%s' in pool '%s'." % (vol_name, pool_name)) def check_pool_info(pool_info, check_point, value): """ Check the pool name, uuid, etc. :param pool_info: A dict include pool's information :param key: Key of pool info dict, available value: Name, UUID, State Persistent, Autostart, Capacity, Allocation, Available :param value: Expect value of pool_info[key] """ if pool_info is None: raise error.TestFail("Pool info dictionary is needed.") if pool_info[check_point] == value: logging.debug("Pool '%s' is '%s'.", check_point, value) else: raise error.TestFail("Pool '%s' isn't '%s'." % (check_point, value)) # Stop multipathd to avoid start pool fail(For fs like pool, the new add # disk may in use by device-mapper, so start pool will report disk already # mounted error). multipathd = service.Factory.create_service("multipathd") multipathd_status = multipathd.status() if multipathd_status: multipathd.stop() # Run Testcase pvt = utlv.PoolVolumeTest(test, params) emulated_image = "emulated-image" kwargs = { "image_size": "1G", "pre_disk_vol": ["1M"], "source_name": source_name, "source_path": source_path, "source_format": source_format, "persistent": True, "ip_protocal": ip_protocal, } try: _pool = libvirt_storage.StoragePool() # Step (1) # Pool define pvt.pre_pool(pool_name, pool_type, pool_target, emulated_image, **kwargs) # Step (2) # Pool list option = "--inactive --type %s" % pool_type check_pool_list(pool_name, option) # Step (3) # Pool dumpxml xml = virsh.pool_dumpxml(pool_name, to_file=pool_xml) logging.debug("Pool '%s' XML:\n%s", pool_name, xml) # Step (4) # Undefine pool result = virsh.pool_undefine(pool_name, ignore_status=True) check_exit_status(result) check_pool_list(pool_name, "--all", True) # Step (5) # Define pool from XML file result = virsh.pool_define(pool_xml) check_exit_status(result, status_error) # Step (6) # Buid pool, this step may fail for 'disk' and 'logical' types pool if pool_type not in ["disk", "logical"]: option = "" # Options --overwrite and --no-overwrite can only be used to # build a filesystem pool, but it will fail for now # if pool_type == "fs": # option = '--overwrite' result = virsh.pool_build(pool_name, option, ignore_status=True) check_exit_status(result) # Step (7) # Pool start result = virsh.pool_start(pool_name, ignore_status=True) check_exit_status(result) # Step (8) # Pool list option = "--persistent --type %s" % pool_type check_pool_list(pool_name, option) # Step (9) # Pool autostart result = virsh.pool_autostart(pool_name, ignore_status=True) check_exit_status(result) # Step (10) # Pool list option = "--autostart --type %s" % pool_type check_pool_list(pool_name, option) # Step (11) # Restart libvirtd and check the autostart pool utils_libvirtd.libvirtd_restart() option = "--autostart --persistent" check_pool_list(pool_name, option) # Step (12) # Pool destroy if virsh.pool_destroy(pool_name): logging.debug("Pool %s destroyed.", pool_name) else: raise error.TestFail("Destroy pool % failed." % pool_name) # Step (13) # Pool autostart disable result = virsh.pool_autostart(pool_name, "--disable", ignore_status=True) check_exit_status(result) # Step (14) # Repeat step (11) utils_libvirtd.libvirtd_restart() option = "--autostart" check_pool_list(pool_name, option, True) # Step (15) # Pool start # When libvirtd starts up, it'll check to see if any of the storage # pools have been activated externally. If so, then it'll mark the # pool as active. This is independent of autostart. # So a directory based storage pool is thus pretty much always active, # and so as the SCSI pool. if pool_type != "scsi" and (pool_type != "dir" or libvirt_version.version_compare(1, 2, 15)): result = virsh.pool_start(pool_name, ignore_status=True) check_exit_status(result) # Step (16) # Pool info pool_info = _pool.pool_info(pool_name) logging.debug("Pool '%s' info:\n%s", pool_name, pool_info) # Step (17) # Pool UUID result = virsh.pool_uuid(pool_info["Name"], ignore_status=True) check_exit_status(result) check_pool_info(pool_info, "UUID", result.stdout.strip()) # Step (18) # Pool Name result = virsh.pool_name(pool_info["UUID"], ignore_status=True) check_exit_status(result) check_pool_info(pool_info, "Name", result.stdout.strip()) # Step (19) # Pool refresh for 'dir' type pool if pool_type == "dir": os.mknod(vol_path) result = virsh.pool_refresh(pool_name) check_exit_status(result) check_vol_list(vol_name, pool_name) # Step (20) # Create an over size vol in pool(expect fail), then check pool: # 'Capacity', 'Allocation' and 'Available' # For NFS type pool, there's a bug(BZ#1077068) about allocate volume, # and glusterfs pool not support create volume, so not test them if pool_type != "netfs": vol_capacity = "10000G" vol_allocation = "10000G" result = virsh.vol_create_as("oversize_vol", pool_name, vol_capacity, vol_allocation, "raw") check_exit_status(result, True) new_info = _pool.pool_info(pool_name) check_pool_info(pool_info, "Capacity", new_info["Capacity"]) check_pool_info(pool_info, "Allocation", new_info["Allocation"]) check_pool_info(pool_info, "Available", new_info["Available"]) # Step (21) # Undefine pool, this should fail as the pool is active result = virsh.pool_undefine(pool_name, ignore_status=True) check_exit_status(result, expect_error=True) check_pool_list(pool_name, "", False) # Step (22) # Pool destroy if virsh.pool_destroy(pool_name): logging.debug("Pool %s destroyed.", pool_name) else: raise error.TestFail("Destroy pool % failed." % pool_name) # Step (23) # Pool delete for 'dir' type pool if pool_type == "dir": for f in os.listdir(pool_target): os.remove(os.path.join(pool_target, f)) result = virsh.pool_delete(pool_name, ignore_status=True) check_exit_status(result) option = "--inactive --type %s" % pool_type check_pool_list(pool_name, option) if os.path.exists(pool_target): raise error.TestFail("The target path '%s' still exist." % pool_target) result = virsh.pool_start(pool_name, ignore_status=True) check_exit_status(result, True) # Step (24) # Pool undefine result = virsh.pool_undefine(pool_name, ignore_status=True) check_exit_status(result) check_pool_list(pool_name, "--all", True) finally: # Clean up try: pvt.cleanup_pool(pool_name, pool_type, pool_target, emulated_image, **kwargs) except error.TestFail, detail: logging.error(str(detail)) if multipathd_status: multipathd.start() if os.path.exists(pool_xml): os.remove(pool_xml)
def run(test, params, env): """ Test the virsh pool commands (1) Define a given type pool (2) List pool with '--inactive --type' options (3) Dumpxml for the pool (4) Undefine the pool (5) Define pool by using the XML file in step (3) (6) Build the pool(except 'disk' type pool For 'fs' type pool, cover --overwrite and --no-overwrite options (7) Start the pool (8) List pool with '--persistent --type' options (9) Mark pool autostart (10) List pool with '--autostart --type' options (11) Restart libvirtd and list pool with '--autostart --persistent' options (12) Destroy the pool (13) Unmark pool autostart (14) Repeat step (11) (15) Start the pool (16) Get pool info (17) Get pool uuid by name (18) Get pool name by uuid (19) Refresh the pool For 'dir' type pool, touch a file under target path and refresh again to make the new file show in vol-list. (20) Destroy the pool (21) Delete pool for 'dir' type pool. After the command, the pool object will still exist but target path will be deleted (22) Undefine the pool """ # Initialize the variables pool_name = params.get("pool_name", "temp_pool_1") pool_type = params.get("pool_type", "dir") pool_target = params.get("pool_target", "") # The file for dumped pool xml pool_xml = os.path.join(test.tmpdir, "pool.xml.tmp") if os.path.dirname(pool_target) is "": pool_target = os.path.join(test.tmpdir, pool_target) vol_name = params.get("vol_name", "temp_vol_1") # Use pool name as VG name vg_name = pool_name status_error = "yes" == params.get("status_error", "no") vol_path = os.path.join(pool_target, vol_name) # Clean up flags: # cleanup_env[0] for nfs, cleanup_env[1] for iscsi, cleanup_env[2] for lvm cleanup_env = [False, False, False] def check_exit_status(result, expect_error=False): """ Check the exit status of virsh commands. :param result: Virsh command result object :param expect_error: Boolean value, expect command success or fail """ if not expect_error: if result.exit_status != 0: raise error.TestFail(result.stderr) else: logging.debug("Command output:\n%s", result.stdout.strip()) elif expect_error and result.exit_status == 0: raise error.TestFail("Expect fail, but run successfully.") def check_pool_list(pool_name, option="--all", expect_error=False): """ Check pool by running pool-list command with given option. :param pool_name: Name of the pool :param option: option for pool-list command :param expect_error: Boolean value, expect command success or fail """ found = False # Get the list stored in a variable result = virsh.pool_list(option, ignore_status=True) check_exit_status(result, False) output = re.findall(r"(\S+)\ +(\S+)\ +(\S+)[\ +\n]", str(result.stdout)) for item in output: if pool_name in item[0]: found = True break if found: logging.debug("Find pool '%s' in pool list.", pool_name) else: logging.debug("Not find pool %s in pool list.", pool_name) if expect_error and found: raise error.TestFail("Unexpect pool '%s' exist." % pool_name) if not expect_error and not found: raise error.TestFail("Expect pool '%s' doesn't exist." % pool_name) def check_vol_list(vol_name, pool_name): """ Check volume from the list :param vol_name: Name of the volume :param pool_name: Name of the pool """ found = False # Get the volume list stored in a variable result = virsh.vol_list(pool_name, ignore_status=True) check_exit_status(result) output = re.findall(r"(\S+)\ +(\S+)[\ +\n]", str(result.stdout)) for item in output: if vol_name in item[0]: found = True break if found: logging.debug( "Find volume '%s' in pool '%s'.", vol_name, pool_name) else: raise error.TestFail( "Not find volume '%s' in pool '%s'." % (vol_name, pool_name)) def check_pool_info(pool_info, check_point, value): """ Check the pool name, uuid, etc. :param pool_info: A dict include pool's information :param key: Key of pool info dict, available value: Name, UUID, State Persistent, Autostart, Capacity, Allocation, Available :param value: Expect value of pool_info[key] """ if pool_info is None: raise error.TestFail("Pool info dictionary is needed.") if pool_info[check_point] == value: logging.debug("Pool '%s' is '%s'.", check_point, value) else: raise error.TestFail("Pool '%s' isn't '%s'." % (check_point, value)) # Run Testcase try: _pool = libvirt_storage.StoragePool() # Step (1) # Pool define result = utils_test.libvirt.define_pool(pool_name, pool_type, pool_target, cleanup_env) check_exit_status(result, status_error) # Step (2) # Pool list option = "--inactive --type %s" % pool_type check_pool_list(pool_name, option) # Step (3) # Pool dumpxml xml = virsh.pool_dumpxml(pool_name, to_file=pool_xml) logging.debug("Pool '%s' XML:\n%s", pool_name, xml) # Step (4) # Undefine pool result = virsh.pool_undefine(pool_name, ignore_status=True) check_exit_status(result) check_pool_list(pool_name, "--all", True) # Step (5) # Define pool from XML file result = virsh.pool_define(pool_xml) check_exit_status(result, status_error) # Step (6) # Buid pool, this step may fail for 'disk' and 'logical' types pool if pool_type not in ["disk", "logical"]: option = "" # Options --overwrite and --no-overwrite can only be used to # build a filesystem pool, but it will fail for now # if pool_type == "fs": # option = '--overwrite' result = virsh.pool_build(pool_name, option, ignore_status=True) check_exit_status(result) # Step (7) # Pool start result = virsh.pool_start(pool_name, ignore_status=True) check_exit_status(result) # Step (8) # Pool list option = "--persistent --type %s" % pool_type check_pool_list(pool_name, option) # Step (9) # Pool autostart result = virsh.pool_autostart(pool_name, ignore_status=True) check_exit_status(result) # Step (10) # Pool list option = "--autostart --type %s" % pool_type check_pool_list(pool_name, option) # Step (11) # Restart libvirtd and check the autostart pool utils_libvirtd.libvirtd_restart() option = "--autostart --persistent" check_pool_list(pool_name, option) # Step (12) # Pool destroy if virsh.pool_destroy(pool_name): logging.debug("Pool %s destroyed.", pool_name) else: raise error.TestFail("Destroy pool % failed." % pool_name) # Step (13) # Pool autostart disable result = virsh.pool_autostart(pool_name, "--disable", ignore_status=True) check_exit_status(result) # Step (14) # Repeat step (11) utils_libvirtd.libvirtd_restart() option = "--autostart" check_pool_list(pool_name, option, True) # Step (15) # Pool start # If the filesystem cntaining the directory is mounted, then the # directory will show as running, which means the local 'dir' pool # don't need start after restart libvirtd if pool_type != "dir": result = virsh.pool_start(pool_name, ignore_status=True) check_exit_status(result) # Step (16) # Pool info pool_info = _pool.pool_info(pool_name) logging.debug("Pool '%s' info:\n%s", pool_name, pool_info) # Step (17) # Pool UUID result = virsh.pool_uuid(pool_info["Name"], ignore_status=True) check_exit_status(result) check_pool_info(pool_info, "UUID", result.stdout.strip()) # Step (18) # Pool Name result = virsh.pool_name(pool_info["UUID"], ignore_status=True) check_exit_status(result) check_pool_info(pool_info, "Name", result.stdout.strip()) # Step (19) # Pool refresh for 'dir' type pool if pool_type == "dir": os.mknod(vol_path) result = virsh.pool_refresh(pool_name) check_exit_status(result) check_vol_list(vol_name, pool_name) # Step(20) # Pool destroy if virsh.pool_destroy(pool_name): logging.debug("Pool %s destroyed.", pool_name) else: raise error.TestFail("Destroy pool % failed." % pool_name) # Step (21) # Pool delete for 'dir' type pool if pool_type == "dir": if os.path.exists(vol_path): os.remove(vol_path) result = virsh.pool_delete(pool_name, ignore_status=True) check_exit_status(result) option = "--inactive --type %s" % pool_type check_pool_list(pool_name, option) if os.path.exists(pool_target): raise error.TestFail("The target path '%s' still exist." % pool_target) result = virsh.pool_start(pool_name, ignore_status=True) check_exit_status(result, True) # Step (22) # Pool undefine result = virsh.pool_undefine(pool_name, ignore_status=True) check_exit_status(result) check_pool_list(pool_name, "--all", True) finally: # Clean up if os.path.exists(pool_xml): os.remove(pool_xml) if not _pool.delete_pool(pool_name): logging.error("Can't delete pool: %s", pool_name) if cleanup_env[2]: cmd = "pvs |grep %s |awk '{print $1}'" % vg_name pv_name = utils.system_output(cmd) lv_utils.vg_remove(vg_name) utils.run("pvremove %s" % pv_name) if cleanup_env[1]: utils_test.libvirt.setup_or_cleanup_iscsi(False) if cleanup_env[0]: utils_test.libvirt.setup_or_cleanup_nfs(False)
if line.startswith(('hda', 'vda', 'sda')): params['remote_disk_image'] = line.split()[-1] break # Local path of disk image params['img_path'] = data_dir.get_tmp_dir() + '/%s.img' % vm_name if checkpoint == 'xvda_disk': v2v_params['input_mode'] = 'disk' v2v_params.update({'input_file': params['img_path']}) # Copy remote image to local with scp remote.scp_from_remote(xen_host, 22, xen_host_user, xen_host_passwd, params['remote_disk_image'], params['img_path']) if checkpoint == 'pool_uuid': virsh.pool_start(pool_name) pooluuid = virsh.pool_uuid(pool_name).stdout.strip() v2v_params['storage'] = pooluuid if checkpoint.startswith('vnc'): vm_xml.VMXML.set_graphics_attr(vm_name, {'type': 'vnc'}, virsh_instance=virsh_instance) if checkpoint == 'vnc_autoport': params[checkpoint] = {'autoport': 'yes'} vm_xml.VMXML.set_graphics_attr(vm_name, params[checkpoint], virsh_instance=virsh_instance) elif checkpoint == 'vnc_encrypt': params[checkpoint] = {'passwd': params.get('vnc_passwd', 'redhat')} vmxml = vm_xml.VMXML.new_from_inactive_dumpxml( vm_name, virsh_instance=virsh_instance) vm_xml.VMXML.add_security_info( vmxml, params[checkpoint]['passwd'], virsh_instance=virsh_instance)
def run(test, params, env): """ Test command: virsh pool-create. Create a libvirt pool from an XML file. The file could be given by tester or generated by dumpxml a pre-defined pool. """ pool_xml_f = params.get("pool_create_xml_file", "/PATH/TO/POOL.XML") pool_name = params.get("pool_create_name", "virt_test_pool_tmp") option = params.get("pool_create_extra_option", "") readonly_mode = "yes" == params.get("pool_create_readonly_mode", "no") status_error = "yes" == params.get("status_error", "no") pre_def_pool = "yes" == params.get("pre_def_pool", "no") pool_type = params.get("pool_type", "dir") source_format = params.get("pool_src_format", "") source_name = params.get("pool_source_name", "") source_path = params.get("pool_source_path", "/") pool_target = params.get("pool_target", "pool_target") duplicate_element = params.get("pool_create_duplicate_element", "") new_pool_name = params.get("new_pool_create_name") no_disk_label = "yes" == params.get("no_disk_label", "no") if not libvirt_version.version_compare(1, 0, 0): if pool_type == "gluster": test.cancel("Gluster pool is not supported in current" " libvirt version.") if "/PATH/TO/POOL.XML" in pool_xml_f: test.cancel("Please replace %s with valid pool xml file" % pool_xml_f) pool_ins = libvirt_storage.StoragePool() if pre_def_pool and pool_ins.pool_exists(pool_name): test.fail("Pool %s already exist" % pool_name) emulated_image = "emulated-image" kwargs = {'image_size': '1G', 'source_path': source_path, 'source_name': source_name, 'source_format': source_format} pvt = utlv.PoolVolumeTest(test, params) old_uuid = None new_device_name = None if pre_def_pool: try: pvt.pre_pool(pool_name, pool_type, pool_target, emulated_image, **kwargs) virsh.pool_dumpxml(pool_name, to_file=pool_xml_f) old_uuid = virsh.pool_uuid(pool_name).stdout.strip() if no_disk_label: # Update <device_path> logging.debug("Try to update device path") new_device_name = utlv.setup_or_cleanup_iscsi(True) p_xml = pool_xml.PoolXML.new_from_dumpxml(pool_name) s_xml = pool_xml.SourceXML() s_xml.device_path = new_device_name p_xml.set_source(s_xml) pool_xml_f = p_xml.xml if duplicate_element == "name": pass elif duplicate_element == "uuid": pass elif duplicate_element == "source": # Remove <uuid> and update <name> cmd = "sed -i '/<uuid>/d' %s" % pool_xml_f process.run(cmd, shell=True) cmd = "sed -i 's/<name>.*<\/name>/<name>%s<\/name>/g' %s" % (new_pool_name, pool_xml_f) process.run(cmd, shell=True) else: # The transient pool will gone after destroyed virsh.pool_destroy(pool_name) new_source_format = params.get("new_pool_src_format") if new_source_format: cmd = "sed -i s/type=\\\'%s\\\'/type=\\\'%s\\\'/g %s" % ( source_format, new_source_format, pool_xml_f) process.run(cmd, shell=True) # Remove uuid cmd = "sed -i '/<uuid>/d' %s" % pool_xml_f process.run(cmd, shell=True) except Exception as details: pvt.cleanup_pool(pool_name, pool_type, pool_target, emulated_image, **kwargs) if new_device_name: utlv.setup_or_cleanup_iscsi(False) test.error("Error occurred when prepare pool xml:\n %s" % details) # Create an invalid pool xml file if pool_xml_f == "invalid-pool-xml": tmp_xml_f = xml_utils.TempXMLFile() tmp_xml_f.write('"<pool><<<BAD>>><\'XML</name\>' '!@#$%^&*)>(}>}{CORRUPTE|>!</pool>') tmp_xml_f.flush() pool_xml_f = tmp_xml_f.name # Readonly mode ro_flag = False if readonly_mode: logging.debug("Readonly mode test") ro_flag = True # Run virsh test if os.path.exists(pool_xml_f): with open(pool_xml_f, 'r') as f: logging.debug("Create pool from file:\n %s", f.read()) try: cmd_result = virsh.pool_create(pool_xml_f, option, ignore_status=True, debug=True, readonly=ro_flag) err = cmd_result.stderr.strip() status = cmd_result.exit_status if not status_error: if status: test.fail(err) utlv.check_actived_pool(pool_name) pool_detail = libvirt_xml.PoolXML.get_pool_details(pool_name) logging.debug("Pool detail: %s", pool_detail) if pool_detail['uuid'] == old_uuid: test.fail("New created pool still use the old UUID %s" % old_uuid) else: if status == 0: test.fail("Expect fail, but run successfully.") else: logging.debug("Command fail as expected") finally: pvt.cleanup_pool(pool_name, pool_type, pool_target, emulated_image, **kwargs) if new_device_name: utlv.setup_or_cleanup_iscsi(False) if os.path.exists(pool_xml_f): os.remove(pool_xml_f)
def run(test, params, env): """ Test command: virsh pool-create. Create a libvirt pool from an XML file. The file could be given by tester or generated by dumpxml a pre-defined pool. """ pool_xml_f = params.get("pool_create_xml_file", "/PATH/TO/POOL.XML") pool_name = params.get("pool_create_name", "virt_test_pool_tmp") option = params.get("pool_create_extra_option", "") readonly_mode = "yes" == params.get("pool_create_readonly_mode", "no") status_error = "yes" == params.get("status_error", "no") pre_def_pool = "yes" == params.get("pre_def_pool", "no") pool_type = params.get("pool_type", "dir") source_format = params.get("pool_src_format", "") source_name = params.get("pool_source_name", "") source_path = params.get("pool_source_path", "/") pool_target = params.get("pool_create_target", "pool_target") duplicate_element = params.get("pool_create_duplicate_element", "") new_pool_name = params.get("new_pool_create_name") if not libvirt_version.version_compare(1, 0, 0): if pool_type == "gluster": raise error.TestNAError("Gluster pool is not supported in current" " libvirt version.") if "/PATH/TO/POOL.XML" in pool_xml_f: raise error.TestNAError("Please replace %s with valid pool xml file" % pool_xml_f) pool_ins = libvirt_storage.StoragePool() if pre_def_pool and pool_ins.pool_exists(pool_name): raise error.TestFail("Pool %s already exist" % pool_name) emulated_image = "emulated-image" kwargs = {'image_size': '1G', 'source_path': source_path, 'source_name': source_name, 'source_format': source_format} pvt = utlv.PoolVolumeTest(test, params) old_uuid = None if pre_def_pool: try: pvt.pre_pool(pool_name, pool_type, pool_target, emulated_image, **kwargs) virsh.pool_dumpxml(pool_name, to_file=pool_xml_f) old_uuid = virsh.pool_uuid(pool_name).stdout.strip() if duplicate_element == "name": pass elif duplicate_element == "uuid": # Remove <uuid> cmd = "sed -i '/<uuid>/d' %s" % pool_xml_f utils.run(cmd) elif duplicate_element == "source": # Remove <uuid> and update <name> cmd = "sed -i '/<uuid>/d' %s" % pool_xml_f utils.run(cmd) cmd = "sed -i 's/<name>.*<\/name>/<name>%s<\/name>/g' %s" % (new_pool_name, pool_xml_f) utils.run(cmd) else: # The transient pool will gone after destroyed virsh.pool_destroy(pool_name) new_source_format = params.get("new_pool_src_format") if new_source_format: cmd = "sed -i s/type=\\\'%s\\\'/type=\\\'%s\\\'/g %s" % ( source_format, new_source_format, pool_xml_f) utils.run(cmd) except Exception, e: pvt.cleanup_pool(pool_name, pool_type, pool_target, emulated_image, **kwargs) raise error.TestError("Error occurred when prepare pool xml:\n %s" % e)
def run(test, params, env): """ Test command: virsh pool-create. Create a libvirt pool from an XML file. The file could be given by tester or generated by dumpxml a pre-defined pool. """ pool_xml_f = params.get("pool_create_xml_file", "/PATH/TO/POOL.XML") pool_name = params.get("pool_create_name", "virt_test_pool_tmp") option = params.get("pool_create_extra_option", "") readonly_mode = "yes" == params.get("pool_create_readonly_mode", "no") status_error = "yes" == params.get("status_error", "no") pre_def_pool = "yes" == params.get("pre_def_pool", "no") pool_type = params.get("pool_type", "dir") source_format = params.get("pool_src_format", "") source_name = params.get("pool_source_name", "") source_path = params.get("pool_source_path", "/") pool_target = params.get("pool_target", "pool_target") duplicate_element = params.get("pool_create_duplicate_element", "") new_pool_name = params.get("new_pool_create_name") if not libvirt_version.version_compare(1, 0, 0): if pool_type == "gluster": raise error.TestNAError("Gluster pool is not supported in current" " libvirt version.") if "/PATH/TO/POOL.XML" in pool_xml_f: raise error.TestNAError("Please replace %s with valid pool xml file" % pool_xml_f) pool_ins = libvirt_storage.StoragePool() if pre_def_pool and pool_ins.pool_exists(pool_name): raise error.TestFail("Pool %s already exist" % pool_name) emulated_image = "emulated-image" kwargs = { 'image_size': '1G', 'source_path': source_path, 'source_name': source_name, 'source_format': source_format } pvt = utlv.PoolVolumeTest(test, params) old_uuid = None if pre_def_pool: try: pvt.pre_pool(pool_name, pool_type, pool_target, emulated_image, **kwargs) virsh.pool_dumpxml(pool_name, to_file=pool_xml_f) old_uuid = virsh.pool_uuid(pool_name).stdout.strip() if duplicate_element == "name": pass elif duplicate_element == "uuid": # Remove <uuid> cmd = "sed -i '/<uuid>/d' %s" % pool_xml_f utils.run(cmd) elif duplicate_element == "source": # Remove <uuid> and update <name> cmd = "sed -i '/<uuid>/d' %s" % pool_xml_f utils.run(cmd) cmd = "sed -i 's/<name>.*<\/name>/<name>%s<\/name>/g' %s" % ( new_pool_name, pool_xml_f) utils.run(cmd) else: # The transient pool will gone after destroyed virsh.pool_destroy(pool_name) new_source_format = params.get("new_pool_src_format") if new_source_format: cmd = "sed -i s/type=\\\'%s\\\'/type=\\\'%s\\\'/g %s" % ( source_format, new_source_format, pool_xml_f) utils.run(cmd) except Exception, e: pvt.cleanup_pool(pool_name, pool_type, pool_target, emulated_image, **kwargs) raise error.TestError( "Error occurred when prepare pool xml:\n %s" % e)
def run(test, params, env): """ Test command: virsh pool-create. Create a libvirt pool from an XML file. The file could be given by tester or generated by dumpxml a pre-defined pool. """ pool_xml_f = params.get("pool_create_xml_file", "") pool_name = params.get("pool_create_name", "virt_test_pool_tmp") option = params.get("pool_create_extra_option", "") readonly_mode = "yes" == params.get("pool_create_readonly_mode", "no") status_error = "yes" == params.get("status_error", "no") pre_def_pool = "yes" == params.get("pre_def_pool", "no") pool_type = params.get("pool_type", "dir") source_format = params.get("pool_src_format", "") source_name = params.get("pool_source_name", "") source_path = params.get("pool_source_path", "/") pool_target = params.get("pool_target", "pool_target") duplicate_element = params.get("pool_create_duplicate_element", "") new_pool_name = params.get("new_pool_create_name") no_disk_label = "yes" == params.get("no_disk_label", "no") if not libvirt_version.version_compare(1, 0, 0): if pool_type == "gluster": test.cancel("Gluster pool is not supported in current" " libvirt version.") pool_ins = libvirt_storage.StoragePool() if pre_def_pool and pool_ins.pool_exists(pool_name): test.fail("Pool %s already exist" % pool_name) kwargs = {'image_size': '1G', 'source_path': source_path, 'source_name': source_name, 'source_format': source_format, 'emulated_image': "emulated-image", 'pool_target': pool_target, 'pool_name': pool_name} params.update(kwargs) pvt = utlv.PoolVolumeTest(test, params) old_uuid = None new_device_name = None if pre_def_pool: try: pvt.pre_pool(**params) virsh.pool_dumpxml(pool_name, to_file=pool_xml_f) old_uuid = virsh.pool_uuid(pool_name).stdout.strip() if no_disk_label: # Update <device_path> logging.debug("Try to update device path") new_device_name = utlv.setup_or_cleanup_iscsi(True) p_xml = pool_xml.PoolXML.new_from_dumpxml(pool_name) s_xml = pool_xml.SourceXML() s_xml.device_path = new_device_name p_xml.set_source(s_xml) pool_xml_f = p_xml.xml if duplicate_element == "name": pass elif duplicate_element == "uuid": pass elif duplicate_element == "source": # Remove <uuid> and update <name> cmd = "sed -i '/<uuid>/d' %s" % pool_xml_f process.run(cmd, shell=True) cmd = "sed -i 's/<name>.*<\/name>/<name>%s<\/name>/g' %s" % (new_pool_name, pool_xml_f) process.run(cmd, shell=True) else: # The transient pool will gone after destroyed virsh.pool_destroy(pool_name) new_source_format = params.get("new_pool_src_format") if new_source_format: cmd = "sed -i s/type=\\\'%s\\\'/type=\\\'%s\\\'/g %s" % ( source_format, new_source_format, pool_xml_f) process.run(cmd, shell=True) # Remove uuid cmd = "sed -i '/<uuid>/d' %s" % pool_xml_f process.run(cmd, shell=True) except Exception as details: pvt.cleanup_pool(**params) if new_device_name: utlv.setup_or_cleanup_iscsi(False) test.error("Error occurred when prepare pool xml:\n %s" % details) # Create an invalid pool xml file if pool_xml_f == "invalid-pool-xml": tmp_xml_f = xml_utils.TempXMLFile() tmp_xml_f.write('"<pool><<<BAD>>><\'XML</name\>' '!@#$%^&*)>(}>}{CORRUPTE|>!</pool>') tmp_xml_f.flush() pool_xml_f = tmp_xml_f.name # Readonly mode ro_flag = False if readonly_mode: logging.debug("Readonly mode test") ro_flag = True # Run virsh test if os.path.exists(pool_xml_f): with open(pool_xml_f, 'r') as f: logging.debug("Create pool from file:\n %s", f.read()) try: cmd_result = virsh.pool_create(pool_xml_f, option, ignore_status=True, debug=True, readonly=ro_flag) err = cmd_result.stderr.strip() status = cmd_result.exit_status if not status_error: if status: test.fail(err) utlv.check_actived_pool(pool_name) pool_detail = libvirt_xml.PoolXML.get_pool_details(pool_name) logging.debug("Pool detail: %s", pool_detail) if pool_detail['uuid'] == old_uuid: test.fail("New created pool still use the old UUID %s" % old_uuid) else: if status == 0: test.fail("Expect fail, but run successfully.") else: logging.debug("Command fail as expected") finally: pvt.cleanup_pool(**params) if new_device_name: utlv.setup_or_cleanup_iscsi(False) if os.path.exists(pool_xml_f): os.remove(pool_xml_f)
def run(test, params, env): """ Convert specific xen guest """ for v in list(params.values()): if "V2V_EXAMPLE" in v: test.cancel("Please set real value for %s" % v) if utils_v2v.V2V_EXEC is None: test.cancel('Missing command: virt-v2v') vm_name = params.get('main_vm') new_vm_name = params.get('new_vm_name') xen_host = params.get('xen_hostname') xen_host_user = params.get('xen_host_user', 'root') xen_host_passwd = params.get('xen_host_passwd', 'redhat') output_mode = params.get('output_mode') v2v_timeout = int(params.get('v2v_timeout', 1200)) status_error = 'yes' == params.get('status_error', 'no') pool_name = params.get('pool_name', 'v2v_test') pool_type = params.get('pool_type', 'dir') pool_target = params.get('pool_target_path', 'v2v_pool') pvt = libvirt.PoolVolumeTest(test, params) address_cache = env.get('address_cache') checkpoint = params.get('checkpoint', '') bk_list = ['vnc_autoport', 'vnc_encrypt', 'vnc_encrypt_warning'] error_list = [] def log_fail(msg): """ Log error and update error list """ logging.error(msg) error_list.append(msg) def set_graphics(virsh_instance, param): """ Set graphics attributes of vm xml """ vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name, virsh_instance=virsh_instance) graphic = vmxml.xmltreefile.find('devices').find('graphics') for key in param: logging.debug('Set %s=\'%s\'' % (key, param[key])) graphic.set(key, param[key]) vmxml.sync(virsh_instance=virsh_instance) def check_rhev_file_exist(vmcheck): """ Check if rhev files exist """ file_path = { 'rhev-apt.exe': r'C:\rhev-apt.exe', 'rhsrvany.exe': r'"C:\program files\redhat\rhev\apt\rhsrvany.exe"' } fail = False for key in file_path: status = vmcheck.session.cmd_status('dir %s' % file_path[key]) if not status: logging.error('%s exists' % key) fail = True if fail: log_fail('RHEV file exists after convert to kvm') def check_grub_file(vmcheck, check): """ Check grub file content """ logging.info('Checking grub file') grub_file = utils_misc.get_bootloader_cfg(session=vmcheck.session) if not grub_file: test.error('Not found grub file') content = vmcheck.session.cmd('cat %s' % grub_file) if check == 'console_xvc0': if 'console=xvc0' in content: log_fail('"console=xvc0" still exists') def check_kernel(vmcheck): """ Check content of /etc/sysconfig/kernel """ logging.info('Checking /etc/sysconfig/kernel file') content = vmcheck.session.cmd('cat /etc/sysconfig/kernel') logging.debug(content) if 'DEFAULTKERNEL=kernel' not in content: log_fail('Not find "DEFAULTKERNEL=kernel"') elif 'DEFAULTKERNEL=kernel-xen' in content: log_fail('DEFAULTKERNEL is "kernel-xen"') def check_sound_card(vmcheck, check): """ Check sound status of vm from xml """ xml = virsh.dumpxml(vm_name, session_id=vmcheck.virsh_session_id).stdout logging.debug(xml) if check == 'sound' and '<sound model' in xml: log_fail('Sound card should be removed') if check == 'pcspk' and "<sound model='pcspk'" not in xml: log_fail('Sound card should be "pcspk"') def check_rhsrvany_md5(vmcheck): """ Check if MD5 and SHA1 of rhsrvany.exe are correct """ logging.info('Check md5 and sha1 of rhsrvany.exe') val_md5, val_sha1 = params.get('val_md5'), params.get('val_sha1') logging.info('Expect MD5=%s, SHA1=%s', val_md5, val_sha1) if not val_md5 or not val_sha1: test.error('No MD5 or SHA1 value provided') cmd_sha1 = params.get('cmd_sha1') cmd_md5 = cmd_sha1 + ' MD5' sha1 = vmcheck.session.cmd_output(cmd_sha1, safe=True).strip().split('\n')[1].replace(' ', '') md5 = vmcheck.session.cmd_output(cmd_md5, safe=True).strip().split('\n')[1].replace(' ', '') logging.info('Actual MD5=%s, SHA1=%s', md5, sha1) if sha1 == val_sha1 and md5 == val_md5: logging.info('MD5 and SHA1 are correct') else: log_fail('MD5 or SHA1 of rhsrvany.exe not correct') def check_disk(vmcheck, count): """ Check if number of disks meets expectation """ logging.info('Expect number of disks: %d', count) actual = vmcheck.session.cmd('lsblk |grep disk |wc -l').strip() logging.info('Actual number of disks: %s', actual) if int(actual) != count: log_fail('Number of disks is wrong') def check_result(result, status_error): """ Check virt-v2v command result """ libvirt.check_exit_status(result, status_error) output = result.stdout + result.stderr if not status_error and checkpoint != 'vdsm': if output_mode == 'rhev': if not utils_v2v.import_vm_to_ovirt(params, address_cache, timeout=v2v_timeout): test.fail('Import VM failed') elif output_mode == 'libvirt': try: virsh.start(vm_name, debug=True, ignore_status=False) except Exception as e: test.fail('Start vm failed: %s', str(e)) # Check guest following the checkpoint document after convertion logging.info('Checking common checkpoints for v2v') vmchecker = VMChecker(test, params, env) params['vmchecker'] = vmchecker ret = vmchecker.run() if len(ret) == 0: logging.info("All common checkpoints passed") # Check specific checkpoints if checkpoint == 'rhev_file': check_rhev_file_exist(vmchecker.checker) if checkpoint == 'console_xvc0': check_grub_file(vmchecker.checker, 'console_xvc0') if checkpoint in ('vnc_autoport', 'vnc_encrypt'): vmchecker.check_graphics(params[checkpoint]) if checkpoint == 'sdl': if output_mode == 'libvirt': vmchecker.check_graphics({'type': 'vnc'}) elif output_mode == 'rhev': vmchecker.check_graphics({'type': 'spice'}) if checkpoint == 'pv_with_regular_kernel': check_kernel(vmchecker.checker) if checkpoint in ['sound', 'pcspk']: check_sound_card(vmchecker.checker, checkpoint) if checkpoint == 'rhsrvany_md5': check_rhsrvany_md5(vmchecker.checker) if checkpoint == 'multidisk': check_disk(vmchecker.checker, params['disk_count']) log_check = utils_v2v.check_log(params, output) if log_check: log_fail(log_check) # Merge 2 error lists if params.get('vmchecker'): error_list.extend(params['vmchecker'].errors) # Virtio drivers will not be installed without virtio-win setup if checkpoint == 'virtio_win_unset': missing_list = params.get('missing').split(',') expect_errors = ['Not find driver: ' + x for x in missing_list] logging.debug('Expect errors: %s' % expect_errors) logging.debug('Actual errors: %s' % error_list) if set(error_list) == set(expect_errors): error_list[:] = [] else: logging.error('Virtio drivers not meet expectation') if len(error_list): test.fail('%d checkpoints failed: %s' % (len(error_list), error_list)) try: v2v_params = { 'hostname': xen_host, 'hypervisor': 'xen', 'main_vm': vm_name, 'v2v_opts': '-v -x', 'input_mode': 'libvirt', 'new_name': new_vm_name, 'storage': params.get('output_storage', 'default'), 'network': params.get('network'), 'bridge': params.get('bridge'), 'target': params.get('target') } bk_xml = None os.environ['LIBGUESTFS_BACKEND'] = 'direct' # Setup ssh-agent access to xen hypervisor logging.info('set up ssh-agent access ') ssh_key.setup_ssh_key(xen_host, user=xen_host_user, port=22, password=xen_host_passwd) utils_misc.add_identities_into_ssh_agent() if params.get('output_format'): v2v_params.update({'output_format': params.get('output_format')}) # Build rhev related options if output_mode == 'rhev': # Create SASL user on the ovirt host user_pwd = "[['%s', '%s']]" % (params.get("sasl_user"), params.get("sasl_pwd")) v2v_sasl = utils_sasl.SASL(sasl_user_pwd=user_pwd) v2v_sasl.server_ip = params.get("remote_ip") v2v_sasl.server_user = params.get('remote_user') v2v_sasl.server_pwd = params.get('remote_pwd') v2v_sasl.setup(remote=True) # Create libvirt dir pool if output_mode == 'libvirt': pvt.pre_pool(pool_name, pool_type, pool_target, '') uri = utils_v2v.Uri('xen').get_uri(xen_host) # Check if xen guest exists if not virsh.domain_exists(vm_name, uri=uri): logging.error('VM %s not exists', vm_name) virsh_instance = virsh.VirshPersistent() virsh_instance.set_uri(uri) if checkpoint in bk_list: bk_xml = vm_xml.VMXML.new_from_inactive_dumpxml( vm_name, virsh_instance=virsh_instance) if checkpoint == 'guest_uuid': uuid = virsh.domuuid(vm_name, uri=uri).stdout.strip() v2v_params['main_vm'] = uuid if checkpoint in ['format_convert', 'xvda_disk']: # Get remote disk image path blklist = virsh.domblklist(vm_name, uri=uri).stdout.split('\n') logging.debug('domblklist %s:\n%s', vm_name, blklist) for line in blklist: if line.startswith(('hda', 'vda', 'sda')): params['remote_disk_image'] = line.split()[-1] break # Local path of disk image params['img_path'] = data_dir.get_tmp_dir() + '/%s.img' % vm_name if checkpoint == 'xvda_disk': v2v_params['input_mode'] = 'disk' v2v_params.update({'input_file': params['img_path']}) # Copy remote image to local with scp remote.scp_from_remote(xen_host, 22, xen_host_user, xen_host_passwd, params['remote_disk_image'], params['img_path']) if checkpoint == 'pool_uuid': virsh.pool_start(pool_name) pooluuid = virsh.pool_uuid(pool_name).stdout.strip() v2v_params['storage'] = pooluuid if checkpoint.startswith('vnc'): vm_xml.VMXML.set_graphics_attr(vm_name, {'type': 'vnc'}, virsh_instance=virsh_instance) if checkpoint == 'vnc_autoport': params[checkpoint] = {'autoport': 'yes'} vm_xml.VMXML.set_graphics_attr(vm_name, params[checkpoint], virsh_instance=virsh_instance) elif checkpoint in ['vnc_encrypt', 'vnc_encrypt_warning']: params[checkpoint] = {'passwd': params.get('vnc_passwd', 'redhat')} vmxml = vm_xml.VMXML.new_from_inactive_dumpxml( vm_name, virsh_instance=virsh_instance) vm_xml.VMXML.add_security_info( vmxml, params[checkpoint]['passwd'], virsh_instance=virsh_instance) logging.debug(virsh_instance.dumpxml(vm_name, extra='--security-info')) if checkpoint.startswith('libguestfs_backend'): value = checkpoint[19:] if value == 'empty': value = '' logging.info('Set LIBGUESTFS_BACKEND to "%s"', value) os.environ['LIBGUESTFS_BACKEND'] = value if checkpoint == 'same_name': logging.info('Convert guest and rename to %s', new_vm_name) v2v_params.update({'new_name': new_vm_name}) if checkpoint == 'no_passwordless_SSH': logging.info('Unset $SSH_AUTH_SOCK') os.unsetenv('SSH_AUTH_SOCK') if checkpoint in ['xml_without_image', 'format_convert']: xml_file = os.path.join(data_dir.get_tmp_dir(), '%s.xml' % vm_name) virsh.dumpxml(vm_name, to_file=xml_file, uri=uri) v2v_params['hypervisor'] = 'kvm' v2v_params['input_mode'] = 'libvirtxml' v2v_params.update({'input_file': xml_file}) if params.get('img_path'): cmd = "sed -i 's|%s|%s|' %s" % (params['remote_disk_image'], params['img_path'], xml_file) process.run(cmd) logging.debug(process.run('cat %s' % xml_file).stdout_text) if checkpoint == 'format_convert': v2v_params['output_format'] = 'qcow2' if checkpoint == 'ssh_banner': session = remote.remote_login("ssh", xen_host, "22", "root", xen_host_passwd, "#") ssh_banner_content = r'"# no default banner path\n' \ r'#Banner /path/banner file\n' \ r'Banner /etc/ssh/ssh_banner"' logging.info('Create ssh_banner file') session.cmd('echo -e %s > /etc/ssh/ssh_banner' % ssh_banner_content) logging.info('Content of ssh_banner file:') logging.info(session.cmd_output('cat /etc/ssh/ssh_banner')) logging.info('Restart sshd service on xen host') session.cmd('service sshd restart') if checkpoint.startswith('virtio_win'): src_dir = params.get('virtio_win_dir') dest_dir = os.path.join(data_dir.get_tmp_dir(), 'virtio-win') iso_path = os.path.join(dest_dir, 'virtio-win.iso') if not os.path.exists(dest_dir): shutil.copytree(src_dir, dest_dir) virtio_win_env = params.get('virtio_win_env', 'VIRTIO_WIN') process.run('rpm -e virtio-win') if process.run('rpm -q virtio-win', ignore_status=True).exit_status == 0: test.error('not removed') if checkpoint.endswith('unset'): logging.info('Unset env %s' % virtio_win_env) os.unsetenv(virtio_win_env) if checkpoint.endswith('custom'): logging.info('Set env %s=%s' % (virtio_win_env, dest_dir)) os.environ[virtio_win_env] = dest_dir if checkpoint.endswith('iso_mount'): logging.info('Mount iso to /opt') process.run('mount %s /opt' % iso_path) os.environ[virtio_win_env] = '/opt' if checkpoint.endswith('iso_file'): logging.info('Set env %s=%s' % (virtio_win_env, iso_path)) os.environ[virtio_win_env] = iso_path if checkpoint == 'cdrom': xml = vm_xml.VMXML.new_from_inactive_dumpxml( vm_name, virsh_instance=virsh_instance) logging.debug(xml.xmltreefile) disks = xml.get_disk_all() logging.debug('Disks: %r', disks) for disk in list(disks.values()): # Check if vm has cdrom attached if disk.get('device') == 'cdrom' and disk.find('source') is None: test.error('No CDROM image attached') if checkpoint == 'vdsm': extra_pkg = params.get('extra_pkg') logging.info('Install %s', extra_pkg) utils_package.package_install(extra_pkg.split(',')) # Backup conf file for recovery for conf in params['bk_conf'].strip().split(','): logging.debug('Back up %s', conf) shutil.copyfile(conf, conf + '.bk') logging.info('Configure libvirt for vdsm') process.run('vdsm-tool configure --force') logging.info('Start vdsm service') service_manager = service.Factory.create_generic_service() service_manager.start('vdsmd') # Setup user and password user_pwd = "[['%s', '%s']]" % (params.get("sasl_user"), params.get("sasl_pwd")) v2v_sasl = utils_sasl.SASL(sasl_user_pwd=user_pwd) v2v_sasl.server_ip = 'localhost' v2v_sasl.server_user = params.get('sasl_server_user', 'root') v2v_sasl.server_pwd = params.get('sasl_server_passwd') v2v_sasl.setup() v2v_params['sasl_user'] = params.get("sasl_user") v2v_params['sasl_pwd'] = params.get("sasl_pwd") if checkpoint == 'multidisk': params['disk_count'] = 0 blklist = virsh.domblklist(vm_name, uri=uri).stdout.split('\n') logging.info(blklist) for line in blklist: if '/' in line: params['disk_count'] += 1 logging.info('Total disks: %d', params['disk_count']) # Check if xen guest exists again if not virsh.domain_exists(vm_name, uri=uri): logging.error('VM %s not exists', vm_name) # Execute virt-v2v v2v_result = utils_v2v.v2v_cmd(v2v_params) if new_vm_name: vm_name = new_vm_name params['main_vm'] = new_vm_name check_result(v2v_result, status_error) finally: process.run('ssh-agent -k') if checkpoint == 'vdsm': logging.info('Stop vdsmd') service_manager = service.Factory.create_generic_service() service_manager.stop('vdsmd') if params.get('extra_pkg'): utils_package.package_remove(params['extra_pkg'].split(',')) for conf in params['bk_conf'].strip().split(','): if os.path.exists(conf + '.bk'): logging.debug('Recover %s', conf) os.remove(conf) shutil.move(conf + '.bk', conf) logging.info('Restart libvirtd') libvirtd = utils_libvirtd.Libvirtd() libvirtd.restart() logging.info('Start network "default"') virsh.net_start('default') virsh.undefine(vm_name) if params.get('vmchecker'): params['vmchecker'].cleanup() if output_mode == 'libvirt': pvt.cleanup_pool(pool_name, pool_type, pool_target, '') if bk_xml: bk_xml.sync(virsh_instance=virsh_instance) virsh_instance.close_session() if checkpoint == 'ssh_banner': logging.info('Remove ssh_banner file') session = remote.remote_login("ssh", xen_host, "22", "root", xen_host_passwd, "#") session.cmd('rm -f /etc/ssh/ssh_banner') session.cmd('service sshd restart') if checkpoint.startswith('virtio_win'): utils_package.package_install(['virtio-win'])
def create_pool(): """ Define and start a pool. """ sp = libvirt_storage.StoragePool() if create_by_xml: p_xml = pool_xml.PoolXML(pool_type=pool_type) p_xml.name = pool_name s_xml = pool_xml.SourceXML() s_xml.vg_name = disk_src_pool source_host = [] for (host_name, host_port) in zip( disk_src_host.split(), disk_src_port.split()): source_host.append({'name': host_name, 'port': host_port}) s_xml.hosts = source_host if auth_type: s_xml.auth_type = auth_type if auth_user: s_xml.auth_username = auth_user if auth_usage: s_xml.secret_usage = auth_usage p_xml.source = s_xml logging.debug("Pool xml: %s", p_xml) p_xml.xmltreefile.write() ret = virsh.pool_define(p_xml.xml, **virsh_dargs) libvirt.check_exit_status(ret) ret = virsh.pool_build(pool_name, **virsh_dargs) libvirt.check_exit_status(ret) ret = virsh.pool_start(pool_name, **virsh_dargs) libvirt.check_exit_status(ret) else: auth_opt = "" if client_name and client_key: auth_opt = ("--auth-type %s --auth-username %s --secret-usage '%s'" % (auth_type, auth_user, auth_usage)) if not sp.define_rbd_pool(pool_name, mon_host, disk_src_pool, extra=auth_opt): test.fail("Failed to define storage pool") if not sp.build_pool(pool_name): test.fail("Failed to build storage pool") if not sp.start_pool(pool_name): test.fail("Failed to start storage pool") # Check pool operation ret = virsh.pool_refresh(pool_name, **virsh_dargs) libvirt.check_exit_status(ret) ret = virsh.pool_uuid(pool_name, **virsh_dargs) libvirt.check_exit_status(ret) # pool-info pool_info = sp.pool_info(pool_name) if pool_info["Autostart"] != 'no': test.fail("Failed to check pool information") # pool-autostart if not sp.set_pool_autostart(pool_name): test.fail("Failed to set pool autostart") pool_info = sp.pool_info(pool_name) if pool_info["Autostart"] != 'yes': test.fail("Failed to check pool information") # pool-autostart --disable if not sp.set_pool_autostart(pool_name, "--disable"): test.fail("Failed to set pool autostart") # If port is not pre-configured, port value should not be hardcoded in pool information. if "yes" == params.get("rbd_port", "no"): if 'port' in virsh.pool_dumpxml(pool_name): test.fail("port attribute should not be in pool information") # find-storage-pool-sources-as if "yes" == params.get("find_storage_pool_sources_as", "no"): ret = virsh.find_storage_pool_sources_as("rbd", mon_host) libvirt.check_result(ret, skip_if=unsupported_err)
def run(test, params, env): """ Test the virsh pool commands (1) Define a given type pool (2) List pool with '--inactive --type' options (3) Dumpxml for the pool (4) Undefine the pool (5) Define pool by using the XML file in step (3) (6) Build the pool(except 'disk' type pool For 'fs' type pool, cover --overwrite and --no-overwrite options (7) Start the pool (8) List pool with '--persistent --type' options (9) Mark pool autostart (10) List pool with '--autostart --type' options (11) Restart libvirtd and list pool with '--autostart --persistent' options (12) Destroy the pool (13) Unmark pool autostart (14) Repeat step (11) (15) Start the pool (16) Get pool info (17) Get pool uuid by name (18) Get pool name by uuid (19) Refresh the pool For 'dir' type pool, touch a file under target path and refresh again to make the new file show in vol-list. (20) Check pool 'Capacity', 'Allocation' and 'Available' Create a over size vol in pool(expect fail), then check these values (21) Undefine the pool, and this should fail as pool is still active (22) Destroy the pool (23) Delete pool for 'dir' type pool. After the command, the pool object will still exist but target path will be deleted (24) Undefine the pool """ # Initialize the variables pool_name = params.get("pool_name", "temp_pool_1") pool_type = params.get("pool_type", "dir") pool_target = params.get("pool_target", "") source_format = params.get("source_format", "") source_name = params.get("pool_source_name", "gluster-vol1") source_path = params.get("pool_source_path", "/") new_pool_name = params.get("new_pool_name", "") build_option = params.get("build_option", "") same_source_test = "yes" == params.get("same_source_test", "no") customize_initiator_iqn = "yes" == params.get("customize_initiator_iqn", "no") # The file for dumped pool xml poolxml = os.path.join(data_dir.get_tmp_dir(), "pool.xml.tmp") if os.path.dirname(pool_target) is "": pool_target = os.path.join(data_dir.get_tmp_dir(), pool_target) vol_name = params.get("vol_name", "temp_vol_1") # Use pool name as VG name status_error = "yes" == params.get("status_error", "no") vol_path = os.path.join(pool_target, vol_name) ip_protocal = params.get('ip_protocal', 'ipv4') if not libvirt_version.version_compare(1, 0, 0): if pool_type == "gluster": test.cancel("Gluster pool is not supported in current" " libvirt version.") def check_pool_list(pool_name, option="--all", expect_error=False): """ Check pool by running pool-list command with given option. :param pool_name: Name of the pool :param option: option for pool-list command :param expect_error: Boolean value, expect command success or fail """ found = False # Get the list stored in a variable result = virsh.pool_list(option, ignore_status=True) utlv.check_exit_status(result, False) output = re.findall(r"(\S+)\ +(\S+)\ +(\S+)", str(result.stdout.strip())) for item in output: if pool_name in item[0]: found = True break if found: logging.debug("Find pool '%s' in pool list.", pool_name) else: logging.debug("Not find pool %s in pool list.", pool_name) if expect_error and found: test.fail("Unexpect pool '%s' exist." % pool_name) if not expect_error and not found: test.fail("Expect pool '%s' doesn't exist." % pool_name) def check_vol_list(vol_name, pool_name): """ Check volume from the list :param vol_name: Name of the volume :param pool_name: Name of the pool """ found = False # Get the volume list stored in a variable result = virsh.vol_list(pool_name, ignore_status=True) utlv.check_exit_status(result) output = re.findall(r"(\S+)\ +(\S+)", str(result.stdout.strip())) for item in output: if vol_name in item[0]: found = True break if found: logging.debug( "Find volume '%s' in pool '%s'.", vol_name, pool_name) else: test.fail( "Not find volume '%s' in pool '%s'." % (vol_name, pool_name)) def is_in_range(actual, expected, error_percent): deviation = 100 - (100 * (float(actual) / float(expected))) logging.debug("Deviation: %0.2f%%", float(deviation)) return float(deviation) <= float(error_percent) def check_pool_info(pool_info, check_point, value): """ Check the pool name, uuid, etc. :param pool_info: A dict include pool's information :param key: Key of pool info dict, available value: Name, UUID, State Persistent, Autostart, Capacity, Allocation, Available :param value: Expect value of pool_info[key] """ if pool_info is None: test.fail("Pool info dictionary is needed.") val_tup = ('Capacity', 'Allocation', 'Available') if check_point in val_tup and float(value.split()[0]): # As from bytes to GiB, could cause deviation, and it should not # exceed 1 percent. if is_in_range(float(pool_info[check_point].split()[0]), float(value.split()[0]), 1): logging.debug("Pool '%s' is '%s'.", check_point, value) else: test.fail("Pool '%s' isn't '%s'." % (check_point, value)) else: if pool_info[check_point] == value: logging.debug("Pool '%s' is '%s'.", check_point, value) else: test.fail("Pool '%s' isn't '%s'." % (check_point, value)) # Stop multipathd to avoid start pool fail(For fs like pool, the new add # disk may in use by device-mapper, so start pool will report disk already # mounted error). multipathd = service.Factory.create_service("multipathd") multipathd_status = multipathd.status() if multipathd_status: multipathd.stop() # Run Testcase pvt = utlv.PoolVolumeTest(test, params) emulated_image = "emulated-image" kwargs = {'image_size': '1G', 'pre_disk_vol': ['100M'], 'source_name': source_name, 'source_path': source_path, 'source_format': source_format, 'persistent': True, 'ip_protocal': ip_protocal} try: _pool = libvirt_storage.StoragePool() # Step (1) # Pool define pvt.pre_pool(pool_name, pool_type, pool_target, emulated_image, **kwargs) # Step (2) # Pool list option = "--inactive --type %s" % pool_type check_pool_list(pool_name, option) # Step (3) # Pool dumpxml xml = virsh.pool_dumpxml(pool_name, to_file=poolxml) logging.debug("Pool '%s' XML:\n%s", pool_name, xml) # Update pool name if new_pool_name: if "/" in new_pool_name: new_pool_name = new_pool_name.replace("/", "\/") logging.debug(new_pool_name) p_xml = pool_xml.PoolXML.new_from_dumpxml(pool_name) p_xml.name = new_pool_name del p_xml.uuid poolxml = p_xml.xml logging.debug("XML after update pool name:\n%s" % p_xml) # Update host name if same_source_test: s_xml = p_xml.get_source() s_xml.host_name = "192.168.1.1" p_xml.set_source(s_xml) poolxml = p_xml.xml logging.debug("XML after update host name:\n%s" % p_xml) if customize_initiator_iqn: initiator_iqn = params.get("initiator_iqn", "iqn.2018-07.com.virttest:pool.target") p_xml = pool_xml.PoolXML.new_from_dumpxml(pool_name) s_node = p_xml.xmltreefile.find('/source') i_node = ET.SubElement(s_node, 'initiator') ET.SubElement(i_node, 'iqn', {'name': initiator_iqn}) p_xml.xmltreefile.write() poolxml = p_xml.xml logging.debug('XML after add Multi-IQN:\n%s' % p_xml) # Step (4) # Undefine pool if not same_source_test: result = virsh.pool_undefine(pool_name) utlv.check_exit_status(result) check_pool_list(pool_name, "--all", True) # Step (5) # Define pool from XML file result = virsh.pool_define(poolxml, debug=True) # Give error msg when exit status is not expected if "/" in new_pool_name and not result.exit_status: error_msg = "https://bugzilla.redhat.com/show_bug.cgi?id=639923 " error_msg += "is helpful for tracing this bug." logging.error(error_msg) if "." in new_pool_name and result.exit_status: error_msg = "https://bugzilla.redhat.com/show_bug.cgi?id=1333248 " error_msg += "is helpful for tracing this bug." logging.error(error_msg) if same_source_test and not result.exit_status: error_msg = "https://bugzilla.redhat.com/show_bug.cgi?id=1171984 " error_msg += "is helpful for tracing this bug." logging.error(error_msg) utlv.check_exit_status(result, status_error) if not result.exit_status: # Step (6) # Buid pool # '--overwrite/--no-overwrite' just for fs/disk/logiacl type pool # disk/fs pool: as prepare step already make label and create filesystem # for the disk, use '--overwrite' is necessary # logical_pool: build pool will fail if VG already exist, BZ#1373711 if new_pool_name: pool_name = new_pool_name if pool_type != "logical": result = virsh.pool_build(pool_name, build_option, ignore_status=True) utlv.check_exit_status(result) # Step (7) # Pool start result = virsh.pool_start(pool_name, debug=True, ignore_status=True) utlv.check_exit_status(result) # Step (8) # Pool list option = "--persistent --type %s" % pool_type check_pool_list(pool_name, option) # Step (9) # Pool autostart result = virsh.pool_autostart(pool_name, ignore_status=True) utlv.check_exit_status(result) # Step (10) # Pool list option = "--autostart --type %s" % pool_type check_pool_list(pool_name, option) # Step (11) # Restart libvirtd and check the autostart pool utils_libvirtd.libvirtd_restart() option = "--autostart --persistent" check_pool_list(pool_name, option) # Step (12) # Pool destroy if virsh.pool_destroy(pool_name): logging.debug("Pool %s destroyed.", pool_name) else: test.fail("Destroy pool % failed." % pool_name) # Step (13) # Pool autostart disable result = virsh.pool_autostart(pool_name, "--disable", ignore_status=True) utlv.check_exit_status(result) # Step (14) # Repeat step (11) utils_libvirtd.libvirtd_restart() option = "--autostart" check_pool_list(pool_name, option, True) # Step (15) # Pool start # When libvirtd starts up, it'll check to see if any of the storage # pools have been activated externally. If so, then it'll mark the # pool as active. This is independent of autostart. # So a directory based storage pool is thus pretty much always active, # and so as the SCSI pool. if pool_type not in ["dir", 'scsi']: result = virsh.pool_start(pool_name, ignore_status=True) utlv.check_exit_status(result) # Step (16) # Pool info pool_info = _pool.pool_info(pool_name) logging.debug("Pool '%s' info:\n%s", pool_name, pool_info) # Step (17) # Pool UUID result = virsh.pool_uuid(pool_info["Name"], ignore_status=True) utlv.check_exit_status(result) check_pool_info(pool_info, "UUID", result.stdout.strip()) # Step (18) # Pool Name result = virsh.pool_name(pool_info["UUID"], ignore_status=True) utlv.check_exit_status(result) check_pool_info(pool_info, "Name", result.stdout.strip()) # Step (19) # Pool refresh for 'dir' type pool if pool_type == "dir": os.mknod(vol_path) result = virsh.pool_refresh(pool_name) utlv.check_exit_status(result) check_vol_list(vol_name, pool_name) # Step (20) # Create an over size vol in pool(expect fail), then check pool: # 'Capacity', 'Allocation' and 'Available' # For NFS type pool, there's a bug(BZ#1077068) about allocate volume, # and glusterfs pool not support create volume, so not test them if pool_type != "netfs": vol_capacity = "10000G" vol_allocation = "10000G" result = virsh.vol_create_as("oversize_vol", pool_name, vol_capacity, vol_allocation, "raw") utlv.check_exit_status(result, True) new_info = _pool.pool_info(pool_name) check_items = ["Capacity", "Allocation", "Available"] for i in check_items: check_pool_info(pool_info, i, new_info[i]) # Step (21) # Undefine pool, this should fail as the pool is active result = virsh.pool_undefine(pool_name, ignore_status=True) utlv.check_exit_status(result, expect_error=True) check_pool_list(pool_name, "", False) # Step (22) # Pool destroy if virsh.pool_destroy(pool_name): logging.debug("Pool %s destroyed.", pool_name) else: test.fail("Destroy pool % failed." % pool_name) # Step (23) # Pool delete for 'dir' type pool if pool_type == "dir": for f in os.listdir(pool_target): os.remove(os.path.join(pool_target, f)) result = virsh.pool_delete(pool_name, ignore_status=True) utlv.check_exit_status(result) option = "--inactive --type %s" % pool_type check_pool_list(pool_name, option) if os.path.exists(pool_target): test.fail("The target path '%s' still exist." % pool_target) result = virsh.pool_start(pool_name, ignore_status=True) utlv.check_exit_status(result, True) # Step (24) # Pool undefine result = virsh.pool_undefine(pool_name, ignore_status=True) utlv.check_exit_status(result) check_pool_list(pool_name, "--all", True) finally: # Clean up try: pvt.cleanup_pool(pool_name, pool_type, pool_target, emulated_image, **kwargs) utlv.setup_or_cleanup_iscsi(False) except exceptions.TestFail as detail: logging.error(str(detail)) if multipathd_status: multipathd.start() if os.path.exists(poolxml): os.remove(poolxml)