def run(test, params, env): """ Test virsh vol-create-from command to cover the following matrix: pool = [source, destination] pool_type = [dir, disk, fs, logical, netfs, iscsi, scsi] volume_format = [raw, qcow2, qed] Note, both 'iscsi' and 'scsi' type pools don't support create volume by virsh, so which can't be destination pools. And for disk pool, it can't create volume with specified format. """ src_pool_type = params.get("src_pool_type") src_pool_target = params.get("src_pool_target") src_emulated_image = params.get("src_emulated_image") src_vol_format = params.get("src_vol_format") dest_pool_type = params.get("dest_pool_type") dest_pool_target = params.get("dest_pool_target") dest_emulated_image = params.get("dest_emulated_image") dest_vol_format = params.get("dest_vol_format") prealloc_option = params.get("prealloc_option") status_error = params.get("status_error", "no") if not libvirt_version.version_compare(1, 0, 0): if "--prealloc-metadata" in prealloc_option: test.cancel("metadata preallocation not supported in" " current libvirt version.") vol_file = "" try: # Create the src/dest pool src_pool_name = "virt-%s-pool" % src_pool_type dest_pool_name = "virt-%s-pool" % dest_pool_type pvt = utlv.PoolVolumeTest(test, params) pvt.pre_pool(src_pool_name, src_pool_type, src_pool_target, src_emulated_image, image_size="40M", pre_disk_vol=["1M"]) if src_pool_type != dest_pool_type: pvt.pre_pool(dest_pool_name, dest_pool_type, dest_pool_target, dest_emulated_image, image_size="100M", pre_disk_vol=["1M"]) # Print current pools for debugging logging.debug("Current pools:%s", libvirt_storage.StoragePool().list_pools()) # Create the src vol # 8M is the minimal size for logical volume(PPC) # 4M is the minimal size for logical volume(x86) vol_size = params.get("image_volume_size", "16777216") if src_pool_type in ["dir", "logical", "netfs", "fs"]: src_vol_name = "src_vol" pvt.pre_vol(vol_name=src_vol_name, vol_format=src_vol_format, capacity=vol_size, allocation=None, pool_name=src_pool_name) else: src_vol_name = list(utlv.get_vol_list(src_pool_name).keys())[0] # Prepare vol xml file dest_vol_name = "dest_vol" # According to BZ#1138523, we need inpect the right name # (disk partition) for new volume if dest_pool_type == "disk": dest_vol_name = utlv.new_disk_vol_name(dest_pool_name) if dest_vol_name is None: test.error("Fail to generate volume name") if dest_pool_type == "disk": dest_vol_format = "" prealloc_option = "" vol_xml = """ <volume> <name>%s</name> <capacity unit='bytes'>%s</capacity> <target> <format type='%s'/> </target> </volume> """ % (dest_vol_name, vol_size, dest_vol_format) logging.debug("Prepare the volume xml: %s", vol_xml) vol_file = os.path.join(test.tmpdir, "dest_vol.xml") with open(vol_file, 'w') as xml_object: xml_object.write(vol_xml) # iSCSI and SCSI type pool can't create vols via virsh if dest_pool_type in ["iscsi", "scsi"]: test.fail("Unsupport create vol for %s type pool" % dest_pool_type) # Metadata preallocation is not supported for block volumes if dest_pool_type in ["disk", "logical"]: prealloc_option = "" # Run run_virsh_vol_create_from to create dest vol cmd_result = virsh.vol_create_from(dest_pool_name, vol_file, src_vol_name, src_pool_name, prealloc_option, ignore_status=True, debug=True) status = cmd_result.exit_status # Check result if status_error == "no": if status == 0: dest_pv = libvirt_storage.PoolVolume(dest_pool_name) dest_volumes = list(dest_pv.list_volumes().keys()) logging.debug("Current volumes in %s: %s", dest_pool_name, dest_volumes) if dest_vol_name not in dest_volumes: test.fail("Can't find volume: % from pool: %s" % (dest_vol_name, dest_pool_name)) else: test.fail(cmd_result.stderr) else: if status: logging.debug("Expect error: %s", cmd_result.stderr) else: test.fail("Expect fail, but run successfully!") finally: # Cleanup: both src and dest should be removed try: pvt.cleanup_pool(src_pool_name, src_pool_type, src_pool_target, src_emulated_image) except exceptions.TestFail as detail: logging.error(str(detail)) if src_pool_type != dest_pool_type: pvt.cleanup_pool(dest_pool_name, dest_pool_type, dest_pool_target, dest_emulated_image) if os.path.isfile(vol_file): os.remove(vol_file)
def run(test, params, env): """ Test virsh vol-create-from command to cover the following matrix: pool = [source, destination] pool_type = [dir, disk, fs, logical, netfs, iscsi, scsi] volume_format = [raw, qcow2, qed] Note, both 'iscsi' and 'scsi' type pools don't support create volume by virsh, so which can't be destination pools. And for disk pool, it can't create volume with specified format. """ src_pool_type = params.get("src_pool_type") src_pool_target = params.get("src_pool_target") src_emulated_image = params.get("src_emulated_image") src_vol_format = params.get("src_vol_format") dest_pool_type = params.get("dest_pool_type") dest_pool_target = params.get("dest_pool_target") dest_emulated_image = params.get("dest_emulated_image") dest_vol_format = params.get("dest_vol_format") prealloc_option = params.get("prealloc_option") status_error = params.get("status_error", "no") if not libvirt_version.version_compare(1, 0, 0): if "--prealloc-metadata" in prealloc_option: raise error.TestNAError("metadata preallocation not supported in" " current libvirt version.") vol_file = "" try: # Create the src/dest pool src_pool_name = "virt-%s-pool" % src_pool_type dest_pool_name = "virt-%s-pool" % dest_pool_type pvt = utlv.PoolVolumeTest(test, params) pvt.pre_pool(src_pool_name, src_pool_type, src_pool_target, src_emulated_image, image_size="40M", pre_disk_vol=["1M"]) if src_pool_type != dest_pool_type: pvt.pre_pool(dest_pool_name, dest_pool_type, dest_pool_target, dest_emulated_image, image_size="50M", pre_disk_vol=["1M"]) # Print current pools for debugging logging.debug("Current pools:%s", libvirt_storage.StoragePool().list_pools()) # Create the src vol if src_pool_type in ["scsi", "iscsi"]: vol_size = "41943040" #vol_size = "1048576" else: vol_size = "4194304" if src_pool_type in ["dir", "logical", "netfs", "fs"]: src_vol_name = "src_vol" pvt.pre_vol(vol_name=src_vol_name, vol_format=src_vol_format, capacity=vol_size, allocation=None, pool_name=src_pool_name) else: src_pv = libvirt_storage.PoolVolume(src_pool_name) src_vols = src_pv.list_volumes().keys() if src_vols: src_vol_name = src_vols[0] else: raise error.TestFail("No volume in pool: %s" % src_pool_name) # Prepare vol xml file dest_vol_name = "dest_vol" # According to BZ#1138523, we need inpect the right name # (disk partition) for new volume if dest_pool_type == "disk": dest_vol_name = utlv.new_disk_vol_name(dest_pool_name) if dest_vol_name is None: raise error.TestError("Fail to generate volume name") if dest_pool_type == "disk": dest_vol_format = "" prealloc_option = "" vol_xml = """ <volume> <name>%s</name> <capacity unit='bytes'>%s</capacity> <target> <format type='%s'/> </target> </volume> """ % (dest_vol_name, vol_size, dest_vol_format) logging.debug("Prepare the volume xml: %s", vol_xml) vol_file = os.path.join(test.tmpdir, "dest_vol.xml") xml_object = open(vol_file, 'w') xml_object.write(vol_xml) xml_object.close() # iSCSI and SCSI type pool can't create vols via virsh if dest_pool_type in ["iscsi", "scsi"]: raise error.TestFail("Unsupport create vol for %s type pool" % dest_pool_type) # Metadata preallocation is not supported for block volumes if dest_pool_type in ["disk", "logical"]: prealloc_option = "" # Run run_virsh_vol_create_from to create dest vol cmd_result = virsh.vol_create_from(dest_pool_name, vol_file, src_vol_name, src_pool_name, prealloc_option, ignore_status=True, debug=True) status = cmd_result.exit_status # Check result if status_error == "no": if status == 0: dest_pv = libvirt_storage.PoolVolume(dest_pool_name) dest_volumes = dest_pv.list_volumes().keys() logging.debug("Current volumes in %s: %s", dest_pool_name, dest_volumes) if dest_vol_name not in dest_volumes: raise error.TestFail("Can't find volume: % from pool: %s" % (dest_vol_name, dest_pool_name)) else: raise error.TestFail(cmd_result.stderr) else: if status: logging.debug("Expect error: %s", cmd_result.stderr) else: raise error.TestFail("Expect fail, but run successfully!") finally: # Cleanup: both src and dest should be removed try: pvt.cleanup_pool(src_pool_name, src_pool_type, src_pool_target, src_emulated_image) except error.TestFail, detail: logging.error(str(detail)) if src_pool_type != dest_pool_type: pvt.cleanup_pool(dest_pool_name, dest_pool_type, dest_pool_target, dest_emulated_image) if os.path.isfile(vol_file): os.remove(vol_file)
def run(test, params, env): """ Test virsh vol-create and vol-create-as command to cover the following matrix: pool_type = [dir, fs, netfs] volume_format = [raw, bochs, cloop, cow, dmg, iso, qcow, qcow2, qed, vmdk, vpc] pool_type = [disk] volume_format = [none, linux, fat16, fat32, linux-swap, linux-lvm, linux-raid, extended] pool_type = [logical] volume_format = [none] pool_type = [iscsi, scsi] Not supported with format type TODO: pool_type = [rbd, glusterfs] Reference: http://www.libvirt.org/storage.html """ src_pool_type = params.get("src_pool_type") src_pool_target = params.get("src_pool_target") src_pool_format = params.get("src_pool_format", "") pool_vol_num = int(params.get("src_pool_vol_num", '1')) src_emulated_image = params.get("src_emulated_image") extra_option = params.get("extra_option", "") prefix_vol_name = params.get("vol_name", "vol_create_test") vol_format = params.get("vol_format", "raw") vol_capacity = params.get("vol_capacity", 1048576) vol_allocation = params.get("vol_allocation", 1048576) image_size = params.get("emulate_image_size", "1G") lazy_refcounts = "yes" == params.get("lazy_refcounts") status_error = "yes" == params.get("status_error", "no") by_xml = "yes" == params.get("create_vol_by_xml", "yes") incomplete_target = "yes" == params.get("incomplete_target", "no") luks_encrypted = "luks" == params.get("encryption_method") encryption_secret_type = params.get("encryption_secret_type", "passphrase") virsh_readonly_mode = 'yes' == params.get("virsh_readonly", "no") if not libvirt_version.version_compare(1, 0, 0): if "--prealloc-metadata" in extra_option: test.cancel("metadata preallocation not supported in" " current libvirt version.") if incomplete_target: test.cancel("It does not support generate target path" "in current libvirt version.") pool_type = ['dir', 'disk', 'fs', 'logical', 'netfs', 'iscsi', 'scsi'] if src_pool_type not in pool_type: test.cancel("pool type %s not in supported type list: %s" % (src_pool_type, pool_type)) # libvirt acl polkit related params if not libvirt_version.version_compare(1, 1, 1): if params.get('setup_libvirt_polkit') == 'yes': test.cancel("API acl test not supported in current" " libvirt version.") uri = params.get("virsh_uri") unprivileged_user = params.get('unprivileged_user') if unprivileged_user: if unprivileged_user.count('EXAMPLE'): unprivileged_user = '******' # 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() # Set volume xml attribute dictionary, extract all params start with 'vol_' # which are for setting volume xml, except 'lazy_refcounts'. vol_arg = {} for key in params.keys(): if key.startswith('vol_'): if key[4:] in ['capacity', 'allocation', 'owner', 'group']: vol_arg[key[4:]] = int(params[key]) else: vol_arg[key[4:]] = params[key] vol_arg['lazy_refcounts'] = lazy_refcounts def create_luks_secret(vol_path): """ Create secret for luks encryption :param vol_path. volume path. :return: secret id if create successfully. """ sec_xml = secret_xml.SecretXML("no", "yes") sec_xml.description = "volume secret" sec_xml.usage = 'volume' sec_xml.volume = vol_path sec_xml.xmltreefile.write() ret = virsh.secret_define(sec_xml.xml) utlv.check_exit_status(ret) # Get secret uuid. try: encryption_uuid = re.findall(r".+\S+(\ +\S+)\ +.+\S+", ret.stdout.strip())[0].lstrip() except IndexError as detail: test.error("Fail to get newly created secret uuid") logging.debug("Secret uuid %s", encryption_uuid) # Set secret value. encoding = locale.getpreferredencoding() secret_string = base64.b64encode( 'redhat'.encode(encoding)).decode(encoding) ret = virsh.secret_set_value(encryption_uuid, secret_string) utlv.check_exit_status(ret) return encryption_uuid def post_process_vol(ori_vol_path): """ Create or disactive a volume without libvirt :param ori_vol_path: Full path of an original volume :retur: Volume name for checking """ process_vol_name = params.get("process_vol_name", "process_vol") process_vol_options = params.get("process_vol_options", "") process_vol_capacity = params.get("process_vol_capacity", vol_capacity) process_vol_cmd = "" unsupport_err = "Unsupport do '%s %s' in this test" % ( process_vol_by, process_vol_type) if process_vol_by == "lvcreate": process_vol_cmd = "lvcreate -L %s " % process_vol_capacity if process_vol_type == "thin": if not process_vol_options: process_vol_options = "-T " process_vol_cmd += "%s " % process_vol_options processthin_pool_name = params.get("processthin_pool_name", "thinpool") processthin_vol_name = params.get("processthin_vol_name", "thinvol") process_vol_capacity = params.get("process_vol_capacity", "1G") os.path.dirname(ori_vol_path) process_vol_cmd += "%s/%s " % (os.path.dirname(ori_vol_path), processthin_pool_name) process_vol_cmd += "-V %s " % process_vol_capacity process_vol_cmd += "-n %s " % processthin_vol_name process_vol_name = processthin_vol_name elif process_vol_type == "snapshot": if not process_vol_options: process_vol_options = "-s " process_vol_cmd += "%s " % process_vol_options process_vol_cmd += "-n %s " % process_vol_name process_vol_cmd += "%s " % (ori_vol_path) else: logging.error(unsupport_err) return elif process_vol_by == "qemu-img" and process_vol_type == "create": process_vol_cmd = "qemu-img create " process_vol_path = os.path.dirname(ori_vol_path) + "/" process_vol_path += process_vol_name process_vol_cmd += "%s " % process_vol_options process_vol_cmd += "%s " % process_vol_path process_vol_cmd += "%s " % process_vol_capacity elif process_vol_by == "lvchange" and process_vol_type == "deactivate": process_vol_cmd = "lvchange %s " % ori_vol_path if not process_vol_options: process_vol_options = "-an" process_vol_cmd += process_vol_options else: logging.error(unsupport_err) return rst = process.run(process_vol_cmd, ignore_status=True, shell=True) if rst.exit_status: if "Snapshots of snapshots are not supported" in rst.stderr_text: logging.debug("%s is already a snapshot volume", ori_vol_path) process_vol_name = os.path.basename(ori_vol_path) else: logging.error(rst.stderr_text) return return process_vol_name def check_vol(pool_name, vol_name, expect_exist=True): """ Check volume vol_name in pool pool_name """ src_volumes = src_pv.list_volumes().keys() logging.debug("Current volumes in %s: %s", pool_name, src_volumes) if expect_exist: if vol_name not in src_volumes: test.fail("Can't find volume %s in pool %s" % (vol_name, pool_name)) # check format in volume xml volxml = libvirt_xml.VolXML() post_xml = volxml.new_from_vol_dumpxml(vol_name, pool_name) logging.debug("Volume %s XML: %s" % (vol_name, post_xml.xmltreefile)) if 'format' in post_xml.keys() and vol_format is not None: if post_xml.format != vol_format: test.fail("Volume format %s is not expected" % vol_format + " as defined.") else: if vol_name in src_volumes: test.fail("Find volume %s in pool %s, but expect not" % (vol_name, pool_name)) fmt_err0 = "Unknown file format '%s'" % vol_format fmt_err1 = "Formatting or formatting option not " fmt_err1 += "supported for file format '%s'" % vol_format fmt_err2 = "Driver '%s' does not support " % vol_format fmt_err2 += "image creation" fmt_err_list = [fmt_err0, fmt_err1, fmt_err2] skip_msg = "Volume format '%s' is not supported by qemu-img" % vol_format vol_path_list = [] secret_uuids = [] try: # Create the src pool src_pool_name = "virt-%s-pool" % src_pool_type pvt = utlv.PoolVolumeTest(test, params) pvt.pre_pool(src_pool_name, src_pool_type, src_pool_target, src_emulated_image, image_size=image_size, source_format=src_pool_format) src_pv = libvirt_storage.PoolVolume(src_pool_name) src_pool_uuid = libvirt_storage.StoragePool().pool_info( src_pool_name)['UUID'] # Print current pools for debugging logging.debug("Current pools:%s", libvirt_storage.StoragePool().list_pools()) # Create volumes by virsh in a loop while pool_vol_num > 0: # Set volume xml file vol_name = prefix_vol_name + "_%s" % pool_vol_num bad_vol_name = params.get("bad_vol_name", "") if bad_vol_name: vol_name = bad_vol_name pool_vol_num -= 1 # disk partition for new volume if src_pool_type == "disk": vol_name = utlv.new_disk_vol_name(src_pool_name) if vol_name is None: test.error("Fail to generate volume name") if by_xml: # According to BZ#1138523, we need inpect the right name # (disk partition) for new volume if src_pool_type == "disk": vol_name = utlv.new_disk_vol_name(src_pool_name) if vol_name is None: test.error("Fail to generate volume name") vol_arg['name'] = vol_name volxml = libvirt_xml.VolXML() newvol = volxml.new_vol(**vol_arg) if luks_encrypted: # For luks encrypted disk, add related xml in newvol luks_encryption_params = {} luks_encryption_params.update({"format": "luks"}) luks_secret_uuid = create_luks_secret( os.path.join(src_pool_target, vol_name)) secret_uuids.append(luks_secret_uuid) luks_encryption_params.update({ "secret": { "type": encryption_secret_type, "uuid": luks_secret_uuid } }) newvol.encryption = volxml.new_encryption( **luks_encryption_params) vol_xml = newvol['xml'] if params.get('setup_libvirt_polkit') == 'yes': process.run("chmod 666 %s" % vol_xml, ignore_status=True, shell=True) if luks_encrypted and libvirt_version.version_compare( 4, 5, 0): try: polkit = test_setup.LibvirtPolkitConfig(params) polkit_rules_path = polkit.polkit_rules_path with open(polkit_rules_path, 'r+') as f: rule = f.readlines() for index, v in enumerate(rule): if v.find("secret") >= 0: nextline = rule[index + 1] s = nextline.replace( "QEMU", "secret").replace( "pool_name", "secret_uuid").replace( "virt-dir-pool", "%s" % luks_secret_uuid) rule[index + 1] = s rule = ''.join(rule) with open(polkit_rules_path, 'w+') as f: f.write(rule) logging.debug(rule) polkit.polkitd.restart() except IOError as e: logging.error(e) # Run virsh_vol_create to create vol logging.debug("Create volume from XML: %s" % newvol.xmltreefile) cmd_result = virsh.vol_create( src_pool_name, vol_xml, extra_option, unprivileged_user=unprivileged_user, uri=uri, ignore_status=True, debug=True) else: # Run virsh_vol_create_as to create_vol pool_name = src_pool_name if params.get("create_vol_by_pool_uuid") == "yes": pool_name = src_pool_uuid cmd_result = virsh.vol_create_as( vol_name, pool_name, vol_capacity, vol_allocation, vol_format, extra_option, unprivileged_user=unprivileged_user, uri=uri, readonly=virsh_readonly_mode, ignore_status=True, debug=True) # Check result try: utlv.check_exit_status(cmd_result, status_error) check_vol(src_pool_name, vol_name, not status_error) if bad_vol_name: pattern = "volume name '%s' cannot contain '/'" % vol_name logging.debug("pattern: %s", pattern) if "\\" in pattern and by_xml: pattern = pattern.replace("\\", "\\\\") if re.search(pattern, cmd_result.stderr) is None: test.fail("vol-create failed with unexpected reason") if not status_error: vol_path = virsh.vol_path(vol_name, src_pool_name).stdout.strip() logging.debug("Full path of %s: %s", vol_name, vol_path) vol_path_list.append(vol_path) except exceptions.TestFail as detail: stderr = cmd_result.stderr if any(err in stderr for err in fmt_err_list): test.cancel(skip_msg) else: test.fail("Create volume fail:\n%s" % detail) # Post process vol by other programs process_vol_by = params.get("process_vol_by") process_vol_type = params.get("process_vol_type", "") expect_vol_exist = "yes" == params.get("expect_vol_exist", "yes") if process_vol_by and vol_path_list: process_vol = post_process_vol(vol_path_list[0]) if process_vol is not None: try: virsh.pool_refresh(src_pool_name, ignore_status=False) check_vol(src_pool_name, process_vol, expect_vol_exist) except (process.CmdError, exceptions.TestFail) as detail: if process_vol_type == "thin": logging.error(str(detail)) test.cancel("You may encounter bug BZ#1060287") else: test.fail("Fail to refresh pool:\n%s" % detail) else: test.fail("Post process volume failed") finally: # Cleanup # For old version lvm2(2.02.106 or early), deactivate volume group # (destroy libvirt logical pool) will fail if which has deactivated # lv snapshot, so before destroy the pool, we need activate it manually if src_pool_type == 'logical' and vol_path_list: vg_name = vol_path_list[0].split('/')[2] process.run("lvchange -ay %s" % vg_name, shell=True) try: pvt.cleanup_pool(src_pool_name, src_pool_type, src_pool_target, src_emulated_image) for secret_uuid in set(secret_uuids): virsh.secret_undefine(secret_uuid) except exceptions.TestFail as detail: logging.error(str(detail)) if multipathd_status: multipathd.start()
def run(test, params, env): """ Do test for vol-download and vol-upload Basic steps are 1. Create pool with type defined in cfg 2. Create image with writing data in it 3. Get md5 value before operation 4. Do vol-download/upload with options(offset, length) 5. Check md5 value after operation """ pool_type = params.get("vol_download_upload_pool_type") pool_name = params.get("vol_download_upload_pool_name") pool_target = params.get("vol_download_upload_pool_target") if os.path.dirname(pool_target) is "": pool_target = os.path.join(data_dir.get_tmp_dir(), pool_target) vol_name = params.get("vol_download_upload_vol_name") file_name = params.get("vol_download_upload_file_name") file_path = os.path.join(data_dir.get_tmp_dir(), file_name) offset = params.get("vol_download_upload_offset") length = params.get("vol_download_upload_length") capacity = params.get("vol_download_upload_capacity") allocation = params.get("vol_download_upload_allocation") frmt = params.get("vol_download_upload_format") operation = params.get("vol_download_upload_operation") create_vol = ("yes" == params.get("vol_download_upload_create_vol", "yes")) setup_libvirt_polkit = "yes" == params.get("setup_libvirt_polkit") b_luks_encrypt = "luks" == params.get("encryption_method") encryption_password = params.get("encryption_password", "redhat") secret_uuids = [] vm_name = params.get("main_vm") vm = env.get_vm(vm_name) virsh_dargs = {'debug': True, 'ignore_status': True} sparse_option_support = "yes" == params.get("sparse_option_support", "yes") with_clusterSize = "yes" == params.get("with_clusterSize") vol_clusterSize = params.get("vol_clusterSize", "64") vol_clusterSize_unit = params.get("vol_clusterSize_unit") vol_format = params.get("vol_format", "qcow2") libvirt_version.is_libvirt_feature_supported(params) # libvirt acl polkit related params uri = params.get("virsh_uri") if uri and not utils_split_daemons.is_modular_daemon(): uri = "qemu:///system" unpri_user = params.get('unprivileged_user') if unpri_user: if unpri_user.count('EXAMPLE'): unpri_user = '******' if not libvirt_version.version_compare(1, 1, 1): if setup_libvirt_polkit: test.error("API acl test not supported in current" " libvirt version.") # Destroy VM. if vm.is_alive(): vm.destroy(gracefully=False) # Back up xml file. vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) try: pvt = utlv.PoolVolumeTest(test, params) pvt.pre_pool(pool_name, pool_type, pool_target, "volumetest", pre_disk_vol=["50M"]) # According to BZ#1138523, we need inpect the right name # (disk partition) for new volume if pool_type == "disk": vol_name = utlv.new_disk_vol_name(pool_name) if vol_name is None: test.error("Fail to generate volume name") # update polkit rule as the volume name changed if setup_libvirt_polkit: vol_pat = r"lookup\('vol_name'\) == ('\S+')" new_value = "lookup('vol_name') == '%s'" % vol_name utlv.update_polkit_rule(params, vol_pat, new_value) if create_vol: if b_luks_encrypt: if not libvirt_version.version_compare(2, 0, 0): test.cancel("LUKS format not supported in " "current libvirt version") params['sec_volume'] = os.path.join(pool_target, vol_name) luks_sec_uuid = utlv.create_secret(params) ret = virsh.secret_set_value(luks_sec_uuid, encryption_password, encode=True) utlv.check_exit_status(ret) secret_uuids.append(luks_sec_uuid) vol_arg = {} vol_arg['name'] = vol_name vol_arg['capacity'] = int(capacity) vol_arg['allocation'] = int(allocation) if with_clusterSize: vol_arg['format'] = vol_format vol_arg['clusterSize'] = int(vol_clusterSize) vol_arg['clusterSize_unit'] = vol_clusterSize_unit create_luks_vol(pool_name, vol_name, luks_sec_uuid, vol_arg) else: pvt.pre_vol(vol_name, frmt, capacity, allocation, pool_name) virsh.pool_refresh(pool_name, debug=True) vol_list = virsh.vol_list(pool_name, debug=True).stdout.strip() # iscsi volume name is different from others if pool_type == "iscsi": # Due to BZ 1843791, the volume cannot be obtained sometimes. if len(vol_list.splitlines()) < 3: test.fail("Failed to get iscsi type volume.") vol_name = vol_list.split('\n')[2].split()[0] vol_path = virsh.vol_path(vol_name, pool_name, ignore_status=False).stdout.strip() logging.debug("vol_path is %s", vol_path) # Add command options if pool_type is not None: options = " --pool %s" % pool_name if offset is not None: options += " --offset %s" % offset offset = int(offset) else: offset = 0 if length is not None: options += " --length %s" % length length = int(length) else: length = 0 logging.debug("%s options are %s", operation, options) if operation == "upload": # write data to file write_file(file_path) # Set length for calculate the offset + length in the following # func get_pre_post_digest() and digest() if length == 0: length = 1048576 def get_pre_post_digest(): """ Get pre region and post region digest if have offset and length :return: pre digest and post digest """ # Get digest of pre region before offset if offset != 0: digest_pre = digest(vol_path, 0, offset) else: digest_pre = 0 logging.debug("pre region digest read from %s 0-%s is %s", vol_path, offset, digest_pre) # Get digest of post region after offset+length digest_post = digest(vol_path, offset + length, 0) logging.debug("post region digest read from %s %s-0 is %s", vol_path, offset + length, digest_post) return (digest_pre, digest_post) # Get pre and post digest before operation for compare (ori_pre_digest, ori_post_digest) = get_pre_post_digest() ori_digest = digest(file_path, 0, 0) logging.debug("ori digest read from %s is %s", file_path, ori_digest) if setup_libvirt_polkit: process.run("chmod 666 %s" % file_path, ignore_status=True, shell=True) # Do volume upload result = virsh.vol_upload(vol_name, file_path, options, unprivileged_user=unpri_user, uri=uri, debug=True) if result.exit_status == 0: # Get digest after operation (aft_pre_digest, aft_post_digest) = get_pre_post_digest() aft_digest = digest(vol_path, offset, length) logging.debug("aft digest read from %s is %s", vol_path, aft_digest) # Compare the pre and post part before and after if ori_pre_digest == aft_pre_digest and \ ori_post_digest == aft_post_digest: logging.info("file pre and aft digest match") else: test.fail("file pre or post digests do not" "match, in %s", operation) if operation == "download": # Write data to volume write_file(vol_path) # Record the digest value before operation ori_digest = digest(vol_path, offset, length) logging.debug("original digest read from %s is %s", vol_path, ori_digest) process.run("touch %s" % file_path, ignore_status=True, shell=True) if setup_libvirt_polkit: process.run("chmod 666 %s" % file_path, ignore_status=True, shell=True) # Do volume download result = virsh.vol_download(vol_name, file_path, options, unprivileged_user=unpri_user, uri=uri, debug=True) if result.exit_status == 0: # Get digest after operation aft_digest = digest(file_path, 0, 0) logging.debug("new digest read from %s is %s", file_path, aft_digest) if operation != "mix": if result.exit_status != 0: test.fail("Fail to %s volume: %s" % (operation, result.stderr)) # Compare the change part on volume and file if ori_digest == aft_digest: logging.info("file digests match, volume %s succeed", operation) else: test.fail("file digests do not match, volume %s failed" % operation) if operation == "mix": target = params.get("virt_disk_device_target", "vdb") disk_file_path = os.path.join(pool_target, file_name) # Create one disk xml and attach it to VM. custom_disk_xml = create_disk('file', disk_file_path, 'raw', 'file', 'disk', target, 'virtio') ret = virsh.attach_device(vm_name, custom_disk_xml.xml, flagstr="--config", debug=True) libvirt.check_exit_status(ret) if vm.is_dead(): vm.start() # Write 100M data into disk. data_size = 100 write_disk(test, vm, target, data_size) data_size_in_bytes = data_size * 1024 * 1024 # Refresh directory pool. virsh.pool_refresh(pool_name, debug=True) # Download volume to local with sparse option. download_spare_file = "download-sparse.raw" download_file_path = os.path.join(data_dir.get_tmp_dir(), download_spare_file) options += " --sparse" result = virsh.vol_download(file_name, download_file_path, options, unprivileged_user=unpri_user, uri=uri, debug=True) libvirt.check_exit_status(result) #Check download image size. one_g_in_bytes = 1073741824 download_img_info = utils_misc.get_image_info(download_file_path) download_disk_size = int(download_img_info['dsize']) if (download_disk_size < data_size_in_bytes or download_disk_size >= one_g_in_bytes): test.fail("download image size:%d is less than the generated " "data size:%d or greater than or equal to 1G." % (download_disk_size, data_size_in_bytes)) # Create one upload sparse image file. upload_sparse_file = "upload-sparse.raw" upload_file_path = os.path.join(pool_target, upload_sparse_file) libvirt.create_local_disk('file', upload_file_path, '1', 'raw') # Refresh directory pool. virsh.pool_refresh(pool_name, debug=True) # Do volume upload, upload sparse file which download last time. result = virsh.vol_upload(upload_sparse_file, download_file_path, options, unprivileged_user=unpri_user, uri=uri, debug=True) upload_img_info = utils_misc.get_image_info(upload_file_path) upload_disk_size = int(upload_img_info['dsize']) if (upload_disk_size < data_size_in_bytes or upload_disk_size >= one_g_in_bytes): test.fail("upload image size:%d is less than the generated " "data size:%d or greater than or equal to 1G." % (upload_disk_size, data_size_in_bytes)) finally: # Recover VM. if vm.is_alive(): vm.destroy(gracefully=False) vmxml_backup.sync() pvt.cleanup_pool(pool_name, pool_type, pool_target, "volumetest") for secret_uuid in set(secret_uuids): virsh.secret_undefine(secret_uuid) if os.path.isfile(file_path): os.remove(file_path)
def run(test, params, env): """ Do test for vol-download and vol-upload Basic steps are 1. Create pool with type defined in cfg 2. Create image with writing data in it 3. Get md5 value before operation 4. Do vol-download/upload with options(offset, length) 5. Check md5 value after operation """ pool_type = params.get("vol_download_upload_pool_type") pool_name = params.get("vol_download_upload_pool_name") pool_target = params.get("vol_download_upload_pool_target") if os.path.dirname(pool_target) is "": pool_target = os.path.join(data_dir.get_tmp_dir(), pool_target) vol_name = params.get("vol_download_upload_vol_name") file_name = params.get("vol_download_upload_file_name") file_path = os.path.join(data_dir.get_tmp_dir(), file_name) offset = params.get("vol_download_upload_offset") length = params.get("vol_download_upload_length") capacity = params.get("vol_download_upload_capacity") allocation = params.get("vol_download_upload_allocation") frmt = params.get("vol_download_upload_format") operation = params.get("vol_download_upload_operation") create_vol = ("yes" == params.get("vol_download_upload_create_vol", "yes")) setup_libvirt_polkit = "yes" == params.get("setup_libvirt_polkit") b_luks_encrypt = "luks" == params.get("encryption_method") encryption_password = params.get("encryption_password", "redhat") secret_uuids = [] # libvirt acl polkit related params uri = params.get("virsh_uri") unpri_user = params.get('unprivileged_user') if unpri_user: if unpri_user.count('EXAMPLE'): unpri_user = '******' if not libvirt_version.version_compare(1, 1, 1): if setup_libvirt_polkit: test.error("API acl test not supported in current" " libvirt version.") try: pvt = utlv.PoolVolumeTest(test, params) pvt.pre_pool(pool_name, pool_type, pool_target, "volumetest", pre_disk_vol=["50M"]) # According to BZ#1138523, we need inpect the right name # (disk partition) for new volume if pool_type == "disk": vol_name = utlv.new_disk_vol_name(pool_name) if vol_name is None: test.error("Fail to generate volume name") # update polkit rule as the volume name changed if setup_libvirt_polkit: vol_pat = r"lookup\('vol_name'\) == ('\S+')" new_value = "lookup('vol_name') == '%s'" % vol_name utlv.update_polkit_rule(params, vol_pat, new_value) if create_vol: if b_luks_encrypt: if not libvirt_version.version_compare(2, 0, 0): test.cancel("LUKS format not supported in " "current libvirt version") params['sec_volume'] = os.path.join(pool_target, vol_name) luks_sec_uuid = utlv.create_secret(params) ret = virsh.secret_set_value(luks_sec_uuid, encryption_password, encode=True) utlv.check_exit_status(ret) secret_uuids.append(luks_sec_uuid) vol_arg = {} vol_arg['name'] = vol_name vol_arg['capacity'] = int(capacity) vol_arg['allocation'] = int(allocation) create_luks_vol(pool_name, vol_name, luks_sec_uuid, vol_arg) else: pvt.pre_vol(vol_name, frmt, capacity, allocation, pool_name) vol_list = virsh.vol_list(pool_name).stdout.strip() # iscsi volume name is different from others if pool_type == "iscsi": vol_name = vol_list.split('\n')[2].split()[0] vol_path = virsh.vol_path(vol_name, pool_name, ignore_status=False).stdout.strip() logging.debug("vol_path is %s", vol_path) # Add command options if pool_type is not None: options = " --pool %s" % pool_name if offset is not None: options += " --offset %s" % offset offset = int(offset) else: offset = 0 if length is not None: options += " --length %s" % length length = int(length) else: length = 0 logging.debug("%s options are %s", operation, options) if operation == "upload": # write date to file write_file(file_path) # Set length for calculate the offset + length in the following # func get_pre_post_digest() and digest() if length == 0: length = 1048576 def get_pre_post_digest(): """ Get pre region and post region digest if have offset and length :return: pre digest and post digest """ # Get digest of pre region before offset if offset != 0: digest_pre = digest(vol_path, 0, offset) else: digest_pre = 0 logging.debug("pre region digest read from %s 0-%s is %s", vol_path, offset, digest_pre) # Get digest of post region after offset+length digest_post = digest(vol_path, offset + length, 0) logging.debug("post region digest read from %s %s-0 is %s", vol_path, offset + length, digest_post) return (digest_pre, digest_post) # Get pre and post digest before operation for compare (ori_pre_digest, ori_post_digest) = get_pre_post_digest() ori_digest = digest(file_path, 0, 0) logging.debug("ori digest read from %s is %s", file_path, ori_digest) if setup_libvirt_polkit: process.run("chmod 666 %s" % file_path, ignore_status=True, shell=True) # Do volume upload result = virsh.vol_upload(vol_name, file_path, options, unprivileged_user=unpri_user, uri=uri, debug=True) if result.exit_status == 0: # Get digest after operation (aft_pre_digest, aft_post_digest) = get_pre_post_digest() aft_digest = digest(vol_path, offset, length) logging.debug("aft digest read from %s is %s", vol_path, aft_digest) # Compare the pre and post part before and after if ori_pre_digest == aft_pre_digest and \ ori_post_digest == aft_post_digest: logging.info("file pre and aft digest match") else: test.fail("file pre or post digests do not" "match, in %s", operation) if operation == "download": # Write date to volume write_file(vol_path) # Record the digest value before operation ori_digest = digest(vol_path, offset, length) logging.debug("original digest read from %s is %s", vol_path, ori_digest) process.run("touch %s" % file_path, ignore_status=True, shell=True) if setup_libvirt_polkit: process.run("chmod 666 %s" % file_path, ignore_status=True, shell=True) # Do volume download result = virsh.vol_download(vol_name, file_path, options, unprivileged_user=unpri_user, uri=uri, debug=True) if result.exit_status == 0: # Get digest after operation aft_digest = digest(file_path, 0, 0) logging.debug("new digest read from %s is %s", file_path, aft_digest) if result.exit_status != 0: test.fail("Fail to %s volume: %s" % (operation, result.stderr)) # Compare the change part on volume and file if ori_digest == aft_digest: logging.info("file digests match, volume %s suceed", operation) else: test.fail("file digests do not match, volume %s failed" % operation) finally: pvt.cleanup_pool(pool_name, pool_type, pool_target, "volumetest") for secret_uuid in set(secret_uuids): virsh.secret_undefine(secret_uuid) if os.path.isfile(file_path): os.remove(file_path)
def run(test, params, env): """ This test cover two volume commands: vol-clone and vol-wipe. 1. Create a given type pool. 2. Create a given format volume in the pool. 3. Clone the new create volume. 4. Wipe the new clone volume. 5. Delete the volume and pool. """ pool_name = params.get("pool_name") pool_type = params.get("pool_type") pool_target = params.get("pool_target") if not os.path.dirname(pool_target): pool_target = os.path.join(data_dir.get_tmp_dir(), pool_target) emulated_image = params.get("emulated_image") emulated_image_size = params.get("emulated_image_size") vol_name = params.get("vol_name") new_vol_name = params.get("new_vol_name") vol_capability = params.get("vol_capability") vol_allocation = params.get("vol_allocation") vol_format = params.get("vol_format") clone_option = params.get("clone_option", "") wipe_algorithms = params.get("wipe_algorithms") b_luks_encrypted = "luks" == params.get("encryption_method") encryption_password = params.get("encryption_password", "redhat") secret_uuids = [] wipe_old_vol = False with_clusterSize = "yes" == params.get("with_clusterSize") vol_clusterSize = params.get("vol_clusterSize", "64") vol_clusterSize_unit = params.get("vol_clusterSize_unit") libvirt_version.is_libvirt_feature_supported(params) if virsh.has_command_help_match("vol-clone", "--prealloc-metadata") is None: if "prealloc-metadata" in clone_option: test.cancel("Option --prealloc-metadata " "is not supported.") clone_status_error = "yes" == params.get("clone_status_error", "no") wipe_status_error = "yes" == params.get("wipe_status_error", "no") setup_libvirt_polkit = "yes" == params.get("setup_libvirt_polkit") # libvirt acl polkit related params uri = params.get("virsh_uri") unpri_user = params.get('unprivileged_user') if unpri_user: if unpri_user.count('EXAMPLE'): unpri_user = '******' if not libvirt_version.version_compare(1, 1, 1): if setup_libvirt_polkit: test.cancel("API acl test not supported in current" " libvirt version.") # Using algorithms other than zero need scrub installed. try: utils_path.find_command('scrub') except utils_path.CmdNotFoundError: logging.warning("Can't locate scrub binary, only 'zero' algorithm " "is used.") valid_algorithms = ["zero"] else: valid_algorithms = [ "zero", "nnsa", "dod", "bsi", "gutmann", "schneier", "pfitzner7", "pfitzner33", "random" ] # Choose an algorithm randomly if wipe_algorithms: alg = random.choice(wipe_algorithms.split()) else: alg = random.choice(valid_algorithms) libvirt_pvt = utlv.PoolVolumeTest(test, params) libvirt_pool = libvirt_storage.StoragePool() if libvirt_pool.pool_exists(pool_name): test.error("Pool '%s' already exist" % pool_name) try: # Create a new pool disk_vol = [] if pool_type == 'disk': disk_vol.append(params.get("pre_vol", '10M')) libvirt_pvt.pre_pool(pool_name=pool_name, pool_type=pool_type, pool_target=pool_target, emulated_image=emulated_image, image_size=emulated_image_size, pre_disk_vol=disk_vol) libvirt_vol = libvirt_storage.PoolVolume(pool_name) # Create a new volume if vol_format in ['raw', 'qcow2', 'qed', 'vmdk']: if (b_luks_encrypted and vol_format in ['raw', 'qcow2']): if not libvirt_version.version_compare(2, 0, 0): test.cancel("LUKS is not supported in current" " libvirt version") if vol_format == "qcow2" and not libvirt_version.version_compare( 6, 10, 0): test.cancel("Qcow2 format with luks encryption is not" " supported in current libvirt version") luks_sec_uuid = create_luks_secret( os.path.join(pool_target, vol_name), encryption_password, test) secret_uuids.append(luks_sec_uuid) vol_arg = {} vol_arg['name'] = vol_name vol_arg['capacity'] = int(vol_capability) vol_arg['allocation'] = int(vol_allocation) vol_arg['format'] = vol_format if with_clusterSize: vol_arg['clusterSize'] = int(vol_clusterSize) vol_arg['clusterSize_unit'] = vol_clusterSize_unit create_luks_vol(pool_name, vol_name, luks_sec_uuid, vol_arg) else: libvirt_pvt.pre_vol(vol_name=vol_name, vol_format=vol_format, capacity=vol_capability, allocation=None, pool_name=pool_name) elif vol_format == 'partition': vol_name = list(utlv.get_vol_list(pool_name).keys())[0] logging.debug("Find partition %s in disk pool", vol_name) elif vol_format == 'sparse': # Create a sparse file in pool sparse_file = pool_target + '/' + vol_name cmd = "dd if=/dev/zero of=" + sparse_file cmd += " bs=1 count=0 seek=" + vol_capability process.run(cmd, ignore_status=True, shell=True) else: test.error("Unknown volume format %s" % vol_format) # Refresh the pool virsh.pool_refresh(pool_name, debug=True) vol_info = libvirt_vol.volume_info(vol_name) if not vol_info: test.error("Fail to get info of volume %s" % vol_name) for key in vol_info: logging.debug("Original volume info: %s = %s", key, vol_info[key]) # Metadata preallocation is not support for block volume if vol_info["Type"] == "block" and clone_option.count( "prealloc-metadata"): clone_status_error = True if b_luks_encrypted: wipe_old_vol = True if pool_type == "disk": new_vol_name = utlv.new_disk_vol_name(pool_name) if new_vol_name is None: test.error("Fail to generate volume name") # update polkit rule as the volume name changed if setup_libvirt_polkit: vol_pat = r"lookup\('vol_name'\) == ('\S+')" new_value = "lookup('vol_name') == '%s'" % new_vol_name utlv.update_polkit_rule(params, vol_pat, new_value) bad_cloned_vol_name = params.get("bad_cloned_vol_name", "") if bad_cloned_vol_name: new_vol_name = bad_cloned_vol_name # Clone volume clone_result = virsh.vol_clone(vol_name, new_vol_name, pool_name, clone_option, debug=True) if not clone_status_error: if clone_result.exit_status != 0: test.fail("Clone volume fail:\n%s" % clone_result.stderr.strip()) else: vol_info = libvirt_vol.volume_info(new_vol_name) for key in vol_info: logging.debug("Cloned volume info: %s = %s", key, vol_info[key]) logging.debug("Clone volume successfully.") # Wipe the new clone volume if alg: logging.debug("Wiping volume by '%s' algorithm", alg) wipe_result = virsh.vol_wipe(new_vol_name, pool_name, alg, unprivileged_user=unpri_user, uri=uri, debug=True) unsupported_err = [ "Unsupported algorithm", "no such pattern sequence" ] if not wipe_status_error: if wipe_result.exit_status != 0: if any(err in wipe_result.stderr for err in unsupported_err): test.cancel(wipe_result.stderr) test.fail("Wipe volume fail:\n%s" % clone_result.stdout.strip()) else: virsh_vol_info = libvirt_vol.volume_info(new_vol_name) for key in virsh_vol_info: logging.debug("Wiped volume info(virsh): %s = %s", key, virsh_vol_info[key]) vol_path = virsh.vol_path(new_vol_name, pool_name).stdout.strip() qemu_vol_info = utils_misc.get_image_info(vol_path) for key in qemu_vol_info: logging.debug("Wiped volume info(qemu): %s = %s", key, qemu_vol_info[key]) if qemu_vol_info['format'] != 'raw': test.fail("Expect wiped volume " "format is raw") elif wipe_status_error and wipe_result.exit_status == 0: test.fail("Expect wipe volume fail, but run" " successfully.") elif clone_status_error and clone_result.exit_status == 0: test.fail("Expect clone volume fail, but run" " successfully.") if wipe_old_vol: # Wipe the old volume if alg: logging.debug("Wiping volume by '%s' algorithm", alg) wipe_result = virsh.vol_wipe(vol_name, pool_name, alg, unprivileged_user=unpri_user, uri=uri, debug=True) unsupported_err = [ "Unsupported algorithm", "no such pattern sequence" ] if not wipe_status_error: if wipe_result.exit_status != 0: if any(err in wipe_result.stderr for err in unsupported_err): test.cancel(wipe_result.stderr) test.fail("Wipe volume fail:\n%s" % clone_result.stdout.strip()) else: virsh_vol_info = libvirt_vol.volume_info(vol_name) for key in virsh_vol_info: logging.debug("Wiped volume info(virsh): %s = %s", key, virsh_vol_info[key]) vol_path = virsh.vol_path(vol_name, pool_name).stdout.strip() qemu_vol_info = utils_misc.get_image_info(vol_path) for key in qemu_vol_info: logging.debug("Wiped volume info(qemu): %s = %s", key, qemu_vol_info[key]) if qemu_vol_info['format'] != 'raw': test.fail("Expect wiped volume " "format is raw") elif wipe_status_error and wipe_result.exit_status == 0: test.fail("Expect wipe volume fail, but run" " successfully.") if bad_cloned_vol_name: pattern = "volume name '%s' cannot contain '/'" % new_vol_name if re.search(pattern, clone_result.stderr) is None: test.fail("vol-clone failed with unexpected reason") finally: # Clean up try: libvirt_pvt.cleanup_pool(pool_name, pool_type, pool_target, emulated_image) for secret_uuid in set(secret_uuids): virsh.secret_undefine(secret_uuid) except exceptions.TestFail as detail: logging.error(str(detail))
def run(test, params, env): """ Test virsh vol-create command to cover the following matrix: pool_type = [dir, fs, netfs] volume_format = [raw, bochs, cloop, cow, dmg, iso, qcow, qcow2, qed, vmdk, vpc] pool_type = [disk] volume_format = [none, linux, fat16, fat32, linux-swap, linux-lvm, linux-raid, extended] pool_type = [logical] volume_format = [none] pool_type = [iscsi, scsi] Not supported with format type TODO: pool_type = [rbd, glusterfs] Reference: http://www.libvirt.org/storage.html """ src_pool_type = params.get("src_pool_type") src_pool_target = params.get("src_pool_target") src_pool_format = params.get("src_pool_format", "") pool_vol_num = int(params.get("src_pool_vol_num", '1')) src_emulated_image = params.get("src_emulated_image") extra_option = params.get("extra_option", "") prefix_vol_name = params.get("vol_name", "vol_create_test") vol_format = params.get("vol_format", "raw") vol_capacity = params.get("vol_capacity", 1048576) vol_allocation = params.get("vol_allocation", 1048576) image_size = params.get("emulate_image_size", "1G") lazy_refcounts = "yes" == params.get("lazy_refcounts") status_error = "yes" == params.get("status_error", "no") by_xml = "yes" == params.get("create_vol_by_xml", "yes") incomplete_target = "yes" == params.get("incomplete_target", "no") if not libvirt_version.version_compare(1, 0, 0): if "--prealloc-metadata" in extra_option: raise error.TestNAError("metadata preallocation not supported in" " current libvirt version.") if incomplete_target: raise error.TestNAError("It does not support generate target " "path in thi libvirt version.") pool_type = ['dir', 'disk', 'fs', 'logical', 'netfs', 'iscsi', 'scsi'] if src_pool_type not in pool_type: raise error.TestNAError("pool type %s not in supported type list: %s" % (src_pool_type, pool_type)) # libvirt acl polkit related params if not libvirt_version.version_compare(1, 1, 1): if params.get('setup_libvirt_polkit') == 'yes': raise error.TestNAError("API acl test not supported in current" " libvirt version.") uri = params.get("virsh_uri") unprivileged_user = params.get('unprivileged_user') if unprivileged_user: if unprivileged_user.count('EXAMPLE'): unprivileged_user = '******' # 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() # Set volume xml attribute dictionary, extract all params start with 'vol_' # which are for setting volume xml, except 'lazy_refcounts'. vol_arg = {} for key in params.keys(): if key.startswith('vol_'): if key[4:] in ['capacity', 'allocation', 'owner', 'group']: vol_arg[key[4:]] = int(params[key]) else: vol_arg[key[4:]] = params[key] vol_arg['lazy_refcounts'] = lazy_refcounts def post_process_vol(ori_vol_path): """ Create or disactive a volume without libvirt :param ori_vol_path: Full path of an original volume :retur: Volume name for checking """ process_vol_name = params.get("process_vol_name", "process_vol") process_vol_options = params.get("process_vol_options", "") process_vol_capacity = params.get("process_vol_capacity", vol_capacity) process_vol_cmd = "" unsupport_err = "Unsupport do '%s %s' in this test" % (process_vol_by, process_vol_type) if process_vol_by == "lvcreate": process_vol_cmd = "lvcreate -L %s " % process_vol_capacity if process_vol_type == "thin": if not process_vol_options: process_vol_options = "-T " process_vol_cmd += "%s " % process_vol_options processthin_pool_name = params.get("processthin_pool_name", "thinpool") processthin_vol_name = params.get("processthin_vol_name", "thinvol") process_vol_capacity = params.get("process_vol_capacity", "1G") os.path.dirname(ori_vol_path) process_vol_cmd += "%s/%s " % (os.path.dirname(ori_vol_path), processthin_pool_name) process_vol_cmd += "-V %s " % process_vol_capacity process_vol_cmd += "-n %s " % processthin_vol_name process_vol_name = processthin_vol_name elif process_vol_type == "snapshot": if not process_vol_options: process_vol_options = "-s " process_vol_cmd += "%s " % process_vol_options process_vol_cmd += "-n %s " % process_vol_name process_vol_cmd += "%s " % (ori_vol_path) else: logging.error(unsupport_err) return elif process_vol_by == "qemu-img" and process_vol_type == "create": process_vol_cmd = "qemu-img create " process_vol_path = os.path.dirname(ori_vol_path) + "/" process_vol_path += process_vol_name process_vol_cmd += "%s " % process_vol_options process_vol_cmd += "%s " % process_vol_path process_vol_cmd += "%s " % process_vol_capacity elif process_vol_by == "lvchange" and process_vol_type == "deactivate": process_vol_cmd = "lvchange %s " % ori_vol_path if not process_vol_options: process_vol_options = "-an" process_vol_cmd += process_vol_options else: logging.error(unsupport_err) return rst = process.run(process_vol_cmd, ignore_status=True, shell=True) if rst.exit_status: if "Snapshots of snapshots are not supported" in rst.stderr: logging.debug("%s is already a snapshot volume", ori_vol_path) process_vol_name = os.path.basename(ori_vol_path) else: logging.error(rst.stderr) return return process_vol_name def check_vol(pool_name, vol_name, expect_exist=True): """ Check volume vol_name in pool pool_name """ src_volumes = src_pv.list_volumes().keys() logging.debug("Current volumes in %s: %s", pool_name, src_volumes) if expect_exist: if vol_name not in src_volumes: raise error.TestFail("Can't find volume %s in pool %s" % (vol_name, pool_name)) # check format in volume xml post_xml = volxml.new_from_vol_dumpxml(vol_name, pool_name) logging.debug("Volume %s XML: %s" % (vol_name, post_xml.xmltreefile)) if 'format' in post_xml.keys() and vol_format is not None: if post_xml.format != vol_format: raise error.TestFail("Volume format %s is not expected" % vol_format + " as defined.") else: if vol_name in src_volumes: raise error.TestFail("Find volume %s in pool %s, but expect not" % (vol_name, pool_name)) fmt_err0 = "Unknown file format '%s'" % vol_format fmt_err1 = "Formatting or formatting option not " fmt_err1 += "supported for file format '%s'" % vol_format fmt_err2 = "Driver '%s' does not support " % vol_format fmt_err2 += "image creation" fmt_err_list = [fmt_err0, fmt_err1, fmt_err2] skip_msg = "Volume format '%s' is not supported by qemu-img" % vol_format vol_path_list = [] try: # Create the src pool src_pool_name = "virt-%s-pool" % src_pool_type pvt = utlv.PoolVolumeTest(test, params) pvt.pre_pool(src_pool_name, src_pool_type, src_pool_target, src_emulated_image, image_size=image_size, source_format=src_pool_format) src_pv = libvirt_storage.PoolVolume(src_pool_name) # Print current pools for debugging logging.debug("Current pools:%s", libvirt_storage.StoragePool().list_pools()) # Create volumes by virsh in a loop while pool_vol_num > 0: # Set volume xml file vol_name = prefix_vol_name + "_%s" % pool_vol_num pool_vol_num -= 1 if by_xml: # According to BZ#1138523, we need inpect the right name # (disk partition) for new volume if src_pool_type == "disk": vol_name = utlv.new_disk_vol_name(src_pool_name) if vol_name is None: raise error.TestError("Fail to generate volume name") vol_arg['name'] = vol_name volxml = libvirt_xml.VolXML() newvol = volxml.new_vol(**vol_arg) vol_xml = newvol['xml'] if params.get('setup_libvirt_polkit') == 'yes': process.run("chmod 666 %s" % vol_xml, ignore_status=True, shell=True) # Run virsh_vol_create to create vol logging.debug("Create volume from XML: %s" % newvol.xmltreefile) cmd_result = virsh.vol_create( src_pool_name, vol_xml, extra_option, unprivileged_user=unprivileged_user, uri=uri, ignore_status=True, debug=True) else: # Run virsh_vol_create_as to create_vol cmd_result = virsh.vol_create_as( vol_name, src_pool_name, vol_capacity, vol_allocation, vol_format, unprivileged_user=unprivileged_user, uri=uri, ignore_status=True, debug=True) # Check result try: utlv.check_exit_status(cmd_result, status_error) check_vol(src_pool_name, vol_name, not status_error) if not status_error: vol_path = virsh.vol_path(vol_name, src_pool_name).stdout.strip() logging.debug("Full path of %s: %s", vol_name, vol_path) vol_path_list.append(vol_path) except error.TestFail, e: stderr = cmd_result.stderr if any(err in stderr for err in fmt_err_list): raise error.TestNAError(skip_msg) else: raise e # Post process vol by other programs process_vol_by = params.get("process_vol_by") process_vol_type = params.get("process_vol_type", "") expect_vol_exist = "yes" == params.get("expect_vol_exist", "yes") if process_vol_by and vol_path_list: process_vol = post_process_vol(vol_path_list[0]) if process_vol is not None: try: virsh.pool_refresh(src_pool_name, ignore_status=False) check_vol(src_pool_name, process_vol, expect_vol_exist) except (process.CmdError, error.TestFail), e: if process_vol_type == "thin": logging.error(e) raise error.TestNAError("You may encounter bug BZ#1060287") else: raise e else: raise error.TestFail("Post process volume failed")
def run(test, params, env): """ This test cover two volume commands: vol-clone and vol-wipe. 1. Create a given type pool. 2. Create a given format volume in the pool. 3. Clone the new create volume. 4. Wipe the new clone volume. 5. Delete the volume and pool. """ pool_name = params.get("pool_name") pool_type = params.get("pool_type") pool_target = params.get("pool_target") if not os.path.dirname(pool_target): pool_target = os.path.join(data_dir.get_tmp_dir(), pool_target) emulated_image = params.get("emulated_image") emulated_image_size = params.get("emulated_image_size") vol_name = params.get("vol_name") new_vol_name = params.get("new_vol_name") vol_capability = params.get("vol_capability") vol_allocation = params.get("vol_allocation") vol_format = params.get("vol_format") clone_option = params.get("clone_option", "") wipe_algorithms = params.get("wipe_algorithms") b_luks_encrypted = "luks" == params.get("encryption_method") encryption_password = params.get("encryption_password", "redhat") secret_uuids = [] wipe_old_vol = False if virsh.has_command_help_match("vol-clone", "--prealloc-metadata") is None: if "prealloc-metadata" in clone_option: test.cancel("Option --prealloc-metadata " "is not supported.") clone_status_error = "yes" == params.get("clone_status_error", "no") wipe_status_error = "yes" == params.get("wipe_status_error", "no") setup_libvirt_polkit = "yes" == params.get("setup_libvirt_polkit") # libvirt acl polkit related params uri = params.get("virsh_uri") unpri_user = params.get('unprivileged_user') if unpri_user: if unpri_user.count('EXAMPLE'): unpri_user = '******' if not libvirt_version.version_compare(1, 1, 1): if setup_libvirt_polkit: test.cancel("API acl test not supported in current" " libvirt version.") # Using algorithms other than zero need scrub installed. try: utils_path.find_command('scrub') except utils_path.CmdNotFoundError: logging.warning("Can't locate scrub binary, only 'zero' algorithm " "is used.") valid_algorithms = ["zero"] else: valid_algorithms = ["zero", "nnsa", "dod", "bsi", "gutmann", "schneier", "pfitzner7", "pfitzner33", "random"] # Choose an algorithm randomly if wipe_algorithms: alg = random.choice(wipe_algorithms.split()) else: alg = random.choice(valid_algorithms) libvirt_pvt = utlv.PoolVolumeTest(test, params) libvirt_pool = libvirt_storage.StoragePool() if libvirt_pool.pool_exists(pool_name): test.error("Pool '%s' already exist" % pool_name) try: # Create a new pool disk_vol = [] if pool_type == 'disk': disk_vol.append(params.get("pre_vol", '10M')) libvirt_pvt.pre_pool(pool_name=pool_name, pool_type=pool_type, pool_target=pool_target, emulated_image=emulated_image, image_size=emulated_image_size, pre_disk_vol=disk_vol) libvirt_vol = libvirt_storage.PoolVolume(pool_name) # Create a new volume if vol_format in ['raw', 'qcow2', 'qed', 'vmdk']: if (b_luks_encrypted and vol_format in ['raw']): if not libvirt_version.version_compare(2, 0, 0): test.cancel("LUKS is not supported in current" " libvirt version") luks_sec_uuid = create_luks_secret(os.path.join(pool_target, vol_name), encryption_password, test) secret_uuids.append(luks_sec_uuid) vol_arg = {} vol_arg['name'] = vol_name vol_arg['capacity'] = int(vol_capability) vol_arg['allocation'] = int(vol_allocation) create_luks_vol(pool_name, vol_name, luks_sec_uuid, vol_arg) else: libvirt_pvt.pre_vol(vol_name=vol_name, vol_format=vol_format, capacity=vol_capability, allocation=None, pool_name=pool_name) elif vol_format == 'partition': vol_name = list(utlv.get_vol_list(pool_name).keys())[0] logging.debug("Find partition %s in disk pool", vol_name) elif vol_format == 'sparse': # Create a sparse file in pool sparse_file = pool_target + '/' + vol_name cmd = "dd if=/dev/zero of=" + sparse_file cmd += " bs=1 count=0 seek=" + vol_capability process.run(cmd, ignore_status=True, shell=True) else: test.error("Unknown volume format %s" % vol_format) # Refresh the pool virsh.pool_refresh(pool_name, debug=True) vol_info = libvirt_vol.volume_info(vol_name) if not vol_info: test.error("Fail to get info of volume %s" % vol_name) for key in vol_info: logging.debug("Original volume info: %s = %s", key, vol_info[key]) # Metadata preallocation is not support for block volume if vol_info["Type"] == "block" and clone_option.count("prealloc-metadata"): clone_status_error = True if b_luks_encrypted: wipe_old_vol = True if pool_type == "disk": new_vol_name = utlv.new_disk_vol_name(pool_name) if new_vol_name is None: test.error("Fail to generate volume name") # update polkit rule as the volume name changed if setup_libvirt_polkit: vol_pat = r"lookup\('vol_name'\) == ('\S+')" new_value = "lookup('vol_name') == '%s'" % new_vol_name utlv.update_polkit_rule(params, vol_pat, new_value) bad_cloned_vol_name = params.get("bad_cloned_vol_name", "") if bad_cloned_vol_name: new_vol_name = bad_cloned_vol_name # Clone volume clone_result = virsh.vol_clone(vol_name, new_vol_name, pool_name, clone_option, debug=True) if not clone_status_error: if clone_result.exit_status != 0: test.fail("Clone volume fail:\n%s" % clone_result.stderr.strip()) else: vol_info = libvirt_vol.volume_info(new_vol_name) for key in vol_info: logging.debug("Cloned volume info: %s = %s", key, vol_info[key]) logging.debug("Clone volume successfully.") # Wipe the new clone volume if alg: logging.debug("Wiping volume by '%s' algorithm", alg) wipe_result = virsh.vol_wipe(new_vol_name, pool_name, alg, unprivileged_user=unpri_user, uri=uri, debug=True) unsupported_err = ["Unsupported algorithm", "no such pattern sequence"] if not wipe_status_error: if wipe_result.exit_status != 0: if any(err in wipe_result.stderr for err in unsupported_err): test.cancel(wipe_result.stderr) test.fail("Wipe volume fail:\n%s" % clone_result.stdout.strip()) else: virsh_vol_info = libvirt_vol.volume_info(new_vol_name) for key in virsh_vol_info: logging.debug("Wiped volume info(virsh): %s = %s", key, virsh_vol_info[key]) vol_path = virsh.vol_path(new_vol_name, pool_name).stdout.strip() qemu_vol_info = utils_misc.get_image_info(vol_path) for key in qemu_vol_info: logging.debug("Wiped volume info(qemu): %s = %s", key, qemu_vol_info[key]) if qemu_vol_info['format'] != 'raw': test.fail("Expect wiped volume " "format is raw") elif wipe_status_error and wipe_result.exit_status == 0: test.fail("Expect wipe volume fail, but run" " successfully.") elif clone_status_error and clone_result.exit_status == 0: test.fail("Expect clone volume fail, but run" " successfully.") if wipe_old_vol: # Wipe the old volume if alg: logging.debug("Wiping volume by '%s' algorithm", alg) wipe_result = virsh.vol_wipe(vol_name, pool_name, alg, unprivileged_user=unpri_user, uri=uri, debug=True) unsupported_err = ["Unsupported algorithm", "no such pattern sequence"] if not wipe_status_error: if wipe_result.exit_status != 0: if any(err in wipe_result.stderr for err in unsupported_err): test.cancel(wipe_result.stderr) test.fail("Wipe volume fail:\n%s" % clone_result.stdout.strip()) else: virsh_vol_info = libvirt_vol.volume_info(vol_name) for key in virsh_vol_info: logging.debug("Wiped volume info(virsh): %s = %s", key, virsh_vol_info[key]) vol_path = virsh.vol_path(vol_name, pool_name).stdout.strip() qemu_vol_info = utils_misc.get_image_info(vol_path) for key in qemu_vol_info: logging.debug("Wiped volume info(qemu): %s = %s", key, qemu_vol_info[key]) if qemu_vol_info['format'] != 'raw': test.fail("Expect wiped volume " "format is raw") elif wipe_status_error and wipe_result.exit_status == 0: test.fail("Expect wipe volume fail, but run" " successfully.") if bad_cloned_vol_name: pattern = "volume name '%s' cannot contain '/'" % new_vol_name if re.search(pattern, clone_result.stderr) is None: test.fail("vol-clone failed with unexpected reason") finally: # Clean up try: libvirt_pvt.cleanup_pool(pool_name, pool_type, pool_target, emulated_image) for secret_uuid in set(secret_uuids): virsh.secret_undefine(secret_uuid) except exceptions.TestFail as detail: logging.error(str(detail))
def run(test, params, env): """ This test cover two volume commands: vol-clone and vol-wipe. 1. Create a given type pool. 2. Create a given format volume in the pool. 3. Clone the new create volume. 4. Wipe the new clone volume. 5. Delete the volume and pool. """ pool_name = params.get("pool_name") pool_type = params.get("pool_type") pool_target = params.get("pool_target") if not os.path.dirname(pool_target): pool_target = os.path.join(test.tmpdir, pool_target) emulated_image = params.get("emulated_image") emulated_image_size = params.get("emulated_image_size") vol_name = params.get("vol_name") new_vol_name = params.get("new_vol_name") vol_capability = params.get("vol_capability") vol_format = params.get("vol_format") clone_option = params.get("clone_option", "") wipe_algorithms = params.get("wipe_algorithms") if virsh.has_command_help_match("vol-wipe", "--prealloc-metadata") is None: if "prealloc-metadata" in clone_option: raise error.TestNAError("Option --prealloc-metadata " "is not supported.") # Using algorithms other than zero need scrub installed. try: utils_misc.find_command('scrub') except ValueError: logging.warning("Can't locate scrub binary, only 'zero' algorithm " "is used.") valid_algorithms = ["zero"] else: valid_algorithms = [ "zero", "nnsa", "dod", "bsi", "gutmann", "schneier", "pfitzner7", "pfitzner33", "random" ] # Choose an algorithms randomly if wipe_algorithms: alg = random.choice(wipe_algorithms.split()) else: alg = random.choice(valid_algorithms) clone_status_error = "yes" == params.get("clone_status_error", "no") wipe_status_error = "yes" == params.get("wipe_status_error", "no") setup_libvirt_polkit = "yes" == params.get("setup_libvirt_polkit") # libvirt acl polkit related params uri = params.get("virsh_uri") unpri_user = params.get('unprivileged_user') if unpri_user: if unpri_user.count('EXAMPLE'): unpri_user = '******' if not libvirt_version.version_compare(1, 1, 1): if setup_libvirt_polkit: raise error.TestNAError("API acl test not supported in current" " libvirt version.") del_pool = True libv_pvt = libvirt.PoolVolumeTest(test, params) try: libv_pool = libvirt_storage.StoragePool() while libv_pool.pool_exists(pool_name): logging.debug("Use exist pool '%s'", pool_name) del_pool = False else: # Create a new pool disk_vol = [] if pool_type == 'disk': disk_vol.append(params.get("pre_vol", '10M')) libv_pvt.pre_pool(pool_name=pool_name, pool_type=pool_type, pool_target=pool_target, emulated_image=emulated_image, image_size=emulated_image_size, pre_disk_vol=disk_vol) libv_vol = libvirt_storage.PoolVolume(pool_name) if libv_vol.volume_exists(vol_name): logging.debug("Use exist volume '%s'", vol_name) elif vol_format in ['raw', 'qcow2', 'qed', 'vmdk']: # Create a new volume libv_pvt.pre_vol(vol_name=vol_name, vol_format=vol_format, capacity=vol_capability, allocation=None, pool_name=pool_name) elif vol_format == 'partition': vol_name = libv_vol.list_volumes().keys()[0] logging.debug("Partition %s in disk pool is volume" % vol_name) elif vol_format == 'sparse': # Create a sparse file in pool sparse_file = pool_target + '/' + vol_name cmd = "dd if=/dev/zero of=" + sparse_file cmd += " bs=1 count=0 seek=" + vol_capability utils.run(cmd) else: raise error.TestError("Unknown volume format %s" % vol_format) # Refresh the pool virsh.pool_refresh(pool_name) vol_info = libv_vol.volume_info(vol_name) for key in vol_info: logging.debug("Original volume info: %s = %s", key, vol_info[key]) # Metadata preallocation is not support for block volume if vol_info["Type"] == "block" and clone_option.count( "prealloc-metadata"): clone_status_error = True if pool_type == "disk": new_vol_name = libvirt.new_disk_vol_name(pool_name) if new_vol_name is None: raise error.TestError("Fail to generate volume name") # update polkit rule as the volume name changed if setup_libvirt_polkit: vol_pat = r"lookup\('vol_name'\) == ('\S+')" new_value = "lookup('vol_name') == '%s'" % new_vol_name libvirt.update_polkit_rule(params, vol_pat, new_value) # Clone volume clone_result = virsh.vol_clone(vol_name, new_vol_name, pool_name, clone_option, debug=True) if not clone_status_error: if clone_result.exit_status != 0: raise error.TestFail("Clone volume fail:\n%s" % clone_result.stderr.strip()) else: vol_info = libv_vol.volume_info(new_vol_name) for key in vol_info: logging.debug("Cloned volume info: %s = %s", key, vol_info[key]) logging.debug("Clone volume successfully.") # Wipe the new clone volume if alg: logging.debug("Wiping volume by '%s' algorithm", alg) wipe_result = virsh.vol_wipe(new_vol_name, pool_name, alg, unprivileged_user=unpri_user, uri=uri, debug=True) unsupported_err = [ "Unsupported algorithm", "no such pattern sequence" ] if not wipe_status_error: if wipe_result.exit_status != 0: if any(err in wipe_result.stderr for err in unsupported_err): raise error.TestNAError(wipe_result.stderr) raise error.TestFail("Wipe volume fail:\n%s" % clone_result.stdout.strip()) else: virsh_vol_info = libv_vol.volume_info(new_vol_name) for key in virsh_vol_info: logging.debug("Wiped volume info(virsh): %s = %s", key, virsh_vol_info[key]) vol_path = virsh.vol_path(new_vol_name, pool_name).stdout.strip() qemu_vol_info = utils_misc.get_image_info(vol_path) for key in qemu_vol_info: logging.debug("Wiped volume info(qemu): %s = %s", key, qemu_vol_info[key]) if qemu_vol_info['format'] != 'raw': raise error.TestFail("Expect wiped volume " "format is raw") elif wipe_status_error and wipe_result.exit_status == 0: raise error.TestFail("Expect wipe volume fail, but run" " successfully.") elif clone_status_error and clone_result.exit_status == 0: raise error.TestFail("Expect clone volume fail, but run" " successfully.") finally: # Clean up try: if del_pool: libv_pvt.cleanup_pool(pool_name, pool_type, pool_target, emulated_image) else: # Only delete the volumes libv_vol = libvirt_storage.PoolVolume(pool_name) for vol in [vol_name, new_vol_name]: libv_vol.delete_volume(vol) except error.TestFail, detail: logging.error(str(detail))
def run(test, params, env): """ This test cover two volume commands: vol-clone and vol-wipe. 1. Create a given type pool. 2. Create a given format volume in the pool. 3. Clone the new create volume. 4. Wipe the new clone volume. 5. Delete the volume and pool. """ pool_name = params.get("pool_name") pool_type = params.get("pool_type") pool_target = params.get("pool_target") if not os.path.dirname(pool_target): pool_target = os.path.join(test.tmpdir, pool_target) emulated_image = params.get("emulated_image") emulated_image_size = params.get("emulated_image_size") vol_name = params.get("vol_name") new_vol_name = params.get("new_vol_name") vol_capability = params.get("vol_capability") vol_format = params.get("vol_format") clone_option = params.get("clone_option", "") wipe_algorithms = params.get("wipe_algorithms") if virsh.has_command_help_match("vol-wipe", "--prealloc-metadata") is None: if "prealloc-metadata" in clone_option: raise error.TestNAError("Option --prealloc-metadata " "is not supported.") # Using algorithms other than zero need scrub installed. try: utils_misc.find_command("scrub") except ValueError: logging.warning("Can't locate scrub binary, only 'zero' algorithm " "is used.") valid_algorithms = ["zero"] else: valid_algorithms = ["zero", "nnsa", "dod", "bsi", "gutmann", "schneier", "pfitzner7", "pfitzner33", "random"] # Choose an algorithms randomly if wipe_algorithms: alg = random.choice(wipe_algorithms.split()) else: alg = random.choice(valid_algorithms) clone_status_error = "yes" == params.get("clone_status_error", "no") wipe_status_error = "yes" == params.get("wipe_status_error", "no") setup_libvirt_polkit = "yes" == params.get("setup_libvirt_polkit") # libvirt acl polkit related params uri = params.get("virsh_uri") unpri_user = params.get("unprivileged_user") if unpri_user: if unpri_user.count("EXAMPLE"): unpri_user = "******" if not libvirt_version.version_compare(1, 1, 1): if setup_libvirt_polkit: raise error.TestNAError("API acl test not supported in current" " libvirt version.") del_pool = True libv_pvt = libvirt.PoolVolumeTest(test, params) try: libv_pool = libvirt_storage.StoragePool() while libv_pool.pool_exists(pool_name): logging.debug("Use exist pool '%s'", pool_name) del_pool = False else: # Create a new pool disk_vol = [] if pool_type == "disk": disk_vol.append(params.get("pre_vol", "10M")) libv_pvt.pre_pool( pool_name=pool_name, pool_type=pool_type, pool_target=pool_target, emulated_image=emulated_image, image_size=emulated_image_size, pre_disk_vol=disk_vol, ) libv_vol = libvirt_storage.PoolVolume(pool_name) if libv_vol.volume_exists(vol_name): logging.debug("Use exist volume '%s'", vol_name) elif vol_format in ["raw", "qcow2", "qed", "vmdk"]: # Create a new volume libv_pvt.pre_vol( vol_name=vol_name, vol_format=vol_format, capacity=vol_capability, allocation=None, pool_name=pool_name ) elif vol_format == "partition": vol_name = libv_vol.list_volumes().keys()[0] logging.debug("Partition %s in disk pool is volume" % vol_name) elif vol_format == "sparse": # Create a sparse file in pool sparse_file = pool_target + "/" + vol_name cmd = "dd if=/dev/zero of=" + sparse_file cmd += " bs=1 count=0 seek=" + vol_capability utils.run(cmd) else: raise error.TestError("Unknown volume format %s" % vol_format) # Refresh the pool virsh.pool_refresh(pool_name) vol_info = libv_vol.volume_info(vol_name) for key in vol_info: logging.debug("Original volume info: %s = %s", key, vol_info[key]) # Metadata preallocation is not support for block volume if vol_info["Type"] == "block" and clone_option.count("prealloc-metadata"): clone_status_error = True if pool_type == "disk": new_vol_name = libvirt.new_disk_vol_name(pool_name) if new_vol_name is None: raise error.TestError("Fail to generate volume name") # update polkit rule as the volume name changed if setup_libvirt_polkit: vol_pat = r"lookup\('vol_name'\) == ('\S+')" new_value = "lookup('vol_name') == '%s'" % new_vol_name libvirt.update_polkit_rule(params, vol_pat, new_value) # Clone volume clone_result = virsh.vol_clone(vol_name, new_vol_name, pool_name, clone_option, debug=True) if not clone_status_error: if clone_result.exit_status != 0: raise error.TestFail("Clone volume fail:\n%s" % clone_result.stderr.strip()) else: vol_info = libv_vol.volume_info(new_vol_name) for key in vol_info: logging.debug("Cloned volume info: %s = %s", key, vol_info[key]) logging.debug("Clone volume successfully.") # Wipe the new clone volume if alg: logging.debug("Wiping volume by '%s' algorithm", alg) wipe_result = virsh.vol_wipe( new_vol_name, pool_name, alg, unprivileged_user=unpri_user, uri=uri, debug=True ) unsupported_err = ["Unsupported algorithm", "no such pattern sequence"] if not wipe_status_error: if wipe_result.exit_status != 0: if any(err in wipe_result.stderr for err in unsupported_err): raise error.TestNAError(wipe_result.stderr) raise error.TestFail("Wipe volume fail:\n%s" % clone_result.stdout.strip()) else: virsh_vol_info = libv_vol.volume_info(new_vol_name) for key in virsh_vol_info: logging.debug("Wiped volume info(virsh): %s = %s", key, virsh_vol_info[key]) vol_path = virsh.vol_path(new_vol_name, pool_name).stdout.strip() qemu_vol_info = utils_misc.get_image_info(vol_path) for key in qemu_vol_info: logging.debug("Wiped volume info(qemu): %s = %s", key, qemu_vol_info[key]) if qemu_vol_info["format"] != "raw": raise error.TestFail("Expect wiped volume " "format is raw") elif wipe_status_error and wipe_result.exit_status == 0: raise error.TestFail("Expect wipe volume fail, but run" " successfully.") elif clone_status_error and clone_result.exit_status == 0: raise error.TestFail("Expect clone volume fail, but run" " successfully.") finally: # Clean up try: if del_pool: libv_pvt.cleanup_pool(pool_name, pool_type, pool_target, emulated_image) else: # Only delete the volumes libv_vol = libvirt_storage.PoolVolume(pool_name) for vol in [vol_name, new_vol_name]: libv_vol.delete_volume(vol) except error.TestFail, detail: logging.error(str(detail))
def run(test, params, env): """ Test virsh vol-create command to cover the following matrix: pool_type = [dir, fs, netfs] volume_format = [raw, bochs, cloop, cow, dmg, iso, qcow, qcow2, qed, vmdk, vpc] pool_type = [disk] volume_format = [none, linux, fat16, fat32, linux-swap, linux-lvm, linux-raid, extended] pool_type = [logical] volume_format = [none] pool_type = [iscsi, scsi] Not supported with format type TODO: pool_type = [rbd, glusterfs] Reference: http://www.libvirt.org/storage.html """ src_pool_type = params.get("src_pool_type") src_pool_target = params.get("src_pool_target") src_pool_format = params.get("src_pool_format", "") pool_vol_num = int(params.get("src_pool_vol_num", '1')) src_emulated_image = params.get("src_emulated_image") extra_option = params.get("extra_option", "") prefix_vol_name = params.get("vol_name", "vol_create_test") vol_format = params.get("vol_format", "raw") vol_capacity = params.get("vol_capacity", 1048576) vol_allocation = params.get("vol_allocation", 1048576) image_size = params.get("emulate_image_size", "1G") lazy_refcounts = "yes" == params.get("lazy_refcounts") status_error = "yes" == params.get("status_error", "no") by_xml = "yes" == params.get("create_vol_by_xml", "yes") incomplete_target = "yes" == params.get("incomplete_target", "no") if not libvirt_version.version_compare(1, 0, 0): if "--prealloc-metadata" in extra_option: raise error.TestNAError("metadata preallocation not supported in" " current libvirt version.") if incomplete_target: raise error.TestNAError("It does not support generate target " "path in thi libvirt version.") pool_type = ['dir', 'disk', 'fs', 'logical', 'netfs', 'iscsi', 'scsi'] if src_pool_type not in pool_type: raise error.TestNAError("pool type %s not in supported type list: %s" % (src_pool_type, pool_type)) # libvirt acl polkit related params if not libvirt_version.version_compare(1, 1, 1): if params.get('setup_libvirt_polkit') == 'yes': raise error.TestNAError("API acl test not supported in current" " libvirt version.") uri = params.get("virsh_uri") unprivileged_user = params.get('unprivileged_user') if unprivileged_user: if unprivileged_user.count('EXAMPLE'): unprivileged_user = '******' # 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() # Set volume xml attribute dictionary, extract all params start with 'vol_' # which are for setting volume xml, except 'lazy_refcounts'. vol_arg = {} for key in params.keys(): if key.startswith('vol_'): if key[4:] in ['capacity', 'allocation', 'owner', 'group']: vol_arg[key[4:]] = int(params[key]) else: vol_arg[key[4:]] = params[key] vol_arg['lazy_refcounts'] = lazy_refcounts def post_process_vol(ori_vol_path): """ Create or disactive a volume without libvirt :param ori_vol_path: Full path of an original volume :retur: Volume name for checking """ process_vol_name = params.get("process_vol_name", "process_vol") process_vol_options = params.get("process_vol_options", "") process_vol_capacity = params.get("process_vol_capacity", vol_capacity) process_vol_cmd = "" unsupport_err = "Unsupport do '%s %s' in this test" % ( process_vol_by, process_vol_type) if process_vol_by == "lvcreate": process_vol_cmd = "lvcreate -L %s " % process_vol_capacity if process_vol_type == "thin": if not process_vol_options: process_vol_options = "-T " process_vol_cmd += "%s " % process_vol_options processthin_pool_name = params.get("processthin_pool_name", "thinpool") processthin_vol_name = params.get("processthin_vol_name", "thinvol") process_vol_capacity = params.get("process_vol_capacity", "1G") os.path.dirname(ori_vol_path) process_vol_cmd += "%s/%s " % (os.path.dirname(ori_vol_path), processthin_pool_name) process_vol_cmd += "-V %s " % process_vol_capacity process_vol_cmd += "-n %s " % processthin_vol_name process_vol_name = processthin_vol_name elif process_vol_type == "snapshot": if not process_vol_options: process_vol_options = "-s " process_vol_cmd += "%s " % process_vol_options process_vol_cmd += "-n %s " % process_vol_name process_vol_cmd += "%s " % (ori_vol_path) else: logging.error(unsupport_err) return elif process_vol_by == "qemu-img" and process_vol_type == "create": process_vol_cmd = "qemu-img create " process_vol_path = os.path.dirname(ori_vol_path) + "/" process_vol_path += process_vol_name process_vol_cmd += "%s " % process_vol_options process_vol_cmd += "%s " % process_vol_path process_vol_cmd += "%s " % process_vol_capacity elif process_vol_by == "lvchange" and process_vol_type == "deactivate": process_vol_cmd = "lvchange %s " % ori_vol_path if not process_vol_options: process_vol_options = "-an" process_vol_cmd += process_vol_options else: logging.error(unsupport_err) return rst = utils.run(process_vol_cmd, ignore_status=True) if rst.exit_status: if "Snapshots of snapshots are not supported" in rst.stderr: logging.debug("%s is already a snapshot volume", ori_vol_path) process_vol_name = os.path.basename(ori_vol_path) else: logging.error(rst.stderr) return return process_vol_name def check_vol(pool_name, vol_name, expect_exist=True): """ Check volume vol_name in pool pool_name """ src_volumes = src_pv.list_volumes().keys() logging.debug("Current volumes in %s: %s", pool_name, src_volumes) if expect_exist: if vol_name not in src_volumes: raise error.TestFail("Can't find volume %s in pool %s" % (vol_name, pool_name)) # check format in volume xml post_xml = volxml.new_from_vol_dumpxml(vol_name, pool_name) logging.debug("Volume %s XML: %s" % (vol_name, post_xml.xmltreefile)) if 'format' in post_xml.keys() and vol_format is not None: if post_xml.format != vol_format: raise error.TestFail("Volume format %s is not expected" % vol_format + " as defined.") else: if vol_name in src_volumes: raise error.TestFail( "Find volume %s in pool %s, but expect not" % (vol_name, pool_name)) fmt_err0 = "Unknown file format '%s'" % vol_format fmt_err1 = "Formatting or formatting option not " fmt_err1 += "supported for file format '%s'" % vol_format fmt_err2 = "Driver '%s' does not support " % vol_format fmt_err2 += "image creation" fmt_err_list = [fmt_err0, fmt_err1, fmt_err2] skip_msg = "Volume format '%s' is not supported by qemu-img" % vol_format vol_path_list = [] try: # Create the src pool src_pool_name = "virt-%s-pool" % src_pool_type pvt = utlv.PoolVolumeTest(test, params) pvt.pre_pool(src_pool_name, src_pool_type, src_pool_target, src_emulated_image, image_size=image_size, source_format=src_pool_format) src_pv = libvirt_storage.PoolVolume(src_pool_name) # Print current pools for debugging logging.debug("Current pools:%s", libvirt_storage.StoragePool().list_pools()) # Create volumes by virsh in a loop while pool_vol_num > 0: # Set volume xml file vol_name = prefix_vol_name + "_%s" % pool_vol_num pool_vol_num -= 1 if by_xml: # According to BZ#1138523, we need inpect the right name # (disk partition) for new volume if src_pool_type == "disk": vol_name = utlv.new_disk_vol_name(src_pool_name) if vol_name is None: raise error.TestError("Fail to generate volume name") vol_arg['name'] = vol_name volxml = libvirt_xml.VolXML() newvol = volxml.new_vol(**vol_arg) vol_xml = newvol['xml'] if params.get('setup_libvirt_polkit') == 'yes': utils.run("chmod 666 %s" % vol_xml, ignore_status=True) # Run virsh_vol_create to create vol logging.debug("Create volume from XML: %s" % newvol.xmltreefile) cmd_result = virsh.vol_create( src_pool_name, vol_xml, extra_option, unprivileged_user=unprivileged_user, uri=uri, ignore_status=True, debug=True) else: # Run virsh_vol_create_as to create_vol cmd_result = virsh.vol_create_as( vol_name, src_pool_name, vol_capacity, vol_allocation, vol_format, unprivileged_user=unprivileged_user, uri=uri, ignore_status=True, debug=True) # Check result try: utlv.check_exit_status(cmd_result, status_error) check_vol(src_pool_name, vol_name, not status_error) if not status_error: vol_path = virsh.vol_path(vol_name, src_pool_name).stdout.strip() logging.debug("Full path of %s: %s", vol_name, vol_path) vol_path_list.append(vol_path) except error.TestFail, e: stderr = cmd_result.stderr if any(err in stderr for err in fmt_err_list): raise error.TestNAError(skip_msg) else: raise e # Post process vol by other programs process_vol_by = params.get("process_vol_by") process_vol_type = params.get("process_vol_type", "") expect_vol_exist = "yes" == params.get("expect_vol_exist", "yes") if process_vol_by and vol_path_list: process_vol = post_process_vol(vol_path_list[0]) if process_vol is not None: try: virsh.pool_refresh(src_pool_name, ignore_status=False) check_vol(src_pool_name, process_vol, expect_vol_exist) except (error.CmdError, error.TestFail), e: if process_vol_type == "thin": logging.error(e) raise error.TestNAError( "You may encounter bug BZ#1060287") else: raise e else: raise error.TestFail("Post process volume failed")
src_pv = libvirt_storage.PoolVolume(src_pool_name) # Print current pools for debugging logging.debug("Current pools:%s", libvirt_storage.StoragePool().list_pools()) # Create volumes by virsh in a loop while pool_vol_num > 0: # Set volume xml file vol_name = prefix_vol_name + "_%s" % pool_vol_num pool_vol_num -= 1 if by_xml: # According to BZ#1138523, we need inpect the right name # (disk partition) for new volume if src_pool_type == "disk": vol_name = utlv.new_disk_vol_name(src_pool_name) if vol_name is None: raise error.TestError("Fail to generate volume name") vol_arg['name'] = vol_name volxml = libvirt_xml.VolXML() newvol = volxml.new_vol(**vol_arg) if luks_encrypted: # For luks encrypted disk, add related xml in newvol luks_encryption_params = {} luks_encryption_params.update({"format": "luks"}) luks_secret_uuid = create_luks_secret(os.path.join(src_pool_target, vol_name)) secret_uuids.append(luks_secret_uuid) luks_encryption_params.update({"secret": {"type": encryption_secret_type, "uuid": luks_secret_uuid}}) newvol.encryption = volxml.new_encryption(**luks_encryption_params)