def set_domain_disk(vmxml, blk_source, params, test): """ Replace the domain disk with new setup device or download image :param vmxml: The instance of VMXML class :param params: Avocado params object :param test: Avocado test object :param blk_source: The domain disk image path """ disk_type = params.get("disk_type", "file") boot_dev = params.get("boot_dev", "hd") target_dev = params.get("target_dev", "vdb") device_bus = params.get("device_bus", "virtio") disk_img = params.get("disk_img") image_size = params.get("image_size", "3G") vol_name = params.get("vol_name") disk_format = params.get("disk_format", "qcow2") driver_type = params.get("driver_type", "qcow2") mon_host = params.get("mon_host") disk_src_name = params.get("disk_source_name") disk_src_host = params.get("disk_source_host") disk_src_port = params.get("disk_source_port") source_protocol = params.get("source_protocol", "") boot_iso_file = os.path.join(data_dir.get_tmp_dir(), "boot.iso") non_release_os_url = params.get("non_release_os_url", "") download_file_path = os.path.join(data_dir.get_tmp_dir(), "non_released_os.qcow2") release_os_url = params.get("release_os_url", "") download_released_file_path = os.path.join(data_dir.get_tmp_dir(), "released_os.qcow2") brick_path = os.path.join(test.virtdir, "gluster-pool") usb_index = params.get("usb_index", "0") bus_controller = params.get("bus_controller", "") usb_controller = params.get("usb_controller", "") usb_model = params.get("usb_model", "") global cleanup_iscsi global cleanup_gluster disk_params = { 'disk_type': disk_type, 'target_dev': target_dev, 'target_bus': device_bus, 'driver_type': driver_type } if source_protocol == 'iscsi': if disk_type == 'block': if release_os_url: blk_source = download_released_file_path kwargs = {'image_size': image_size, 'disk_format': disk_format} iscsi_target = prepare_iscsi_disk(blk_source, **kwargs) if iscsi_target is None: test.error("Failed to create iscsi disk") else: cleanup_iscsi = True disk_params.update({'source_file': iscsi_target}) elif source_protocol == 'usb': # assemble the xml of usb controller controllers = vmxml.get_devices(device_type="controller") for dev in controllers: if dev.type == "usb": vmxml.del_device(dev) for model in usb_model.split(','): controller = Controller("controller") controller.type = "usb" controller.index = usb_index controller.model = model vmxml.add_device(controller) # prepare virtual disk device dir_name = os.path.dirname(blk_source) device_name = os.path.join(dir_name, "usb_virtual_disk.qcow2") cmd = ("qemu-img convert -O {} {} {}".format(disk_format, blk_source, device_name)) process.run(cmd, shell=True) disk_params.update({'source_file': device_name}) elif source_protocol == 'gluster': if disk_type == 'network': if release_os_url: blk_source = download_released_file_path host_ip = prepare_gluster_disk(blk_source, test, brick_path=brick_path, **params) if host_ip is None: test.error("Failed to create glusterfs disk") else: cleanup_gluster = True source_name = "%s/%s" % (vol_name, disk_img) disk_params.update({ 'source_name': source_name, 'source_host_name': host_ip, 'source_host_port': '24007', 'source_protocol': source_protocol }) elif source_protocol == 'rbd': if disk_type == 'network': if release_os_url: blk_source = download_released_file_path disk_path = ("rbd:%s:mon_host=%s" % (disk_src_name, mon_host)) disk_cmd = ("qemu-img convert -O %s %s %s" % (disk_format, blk_source, disk_path)) process.run(disk_cmd, ignore_status=False) disk_params.update({ 'source_name': disk_src_name, 'source_host_name': disk_src_host, 'source_host_port': disk_src_port, 'source_protocol': source_protocol }) elif non_release_os_url: disk_params.update({'source_file': download_file_path}) elif boot_dev == "cdrom": disk_params.update({ 'device_type': 'cdrom', 'source_file': boot_iso_file }) elif release_os_url: disk_params.update({'source_file': download_released_file_path}) else: disk_params.update({'source_file': blk_source}) new_disk = Disk(type_name=disk_type) new_disk.xml = open(create_disk_xml(disk_params)).read() vmxml.remove_all_disk() vmxml.add_device(new_disk)
def run(test, params, env): """ Test vm backingchain, blockcopy """ vm_name = params.get('main_vm') vm = env.get_vm(vm_name) status_error = 'yes' == params.get('status_error', 'no') error_msg = params.get('error_msg', '') case = params.get('case', '') blockcommand = params.get('blockcommand', '') blk_top = int(params.get('top', 0)) blk_base = int(params.get('base', 0)) opts = params.get('opts', '--verbose --wait') check_func = params.get('check_func', '') disk_type = params.get('disk_type', '') disk_src = params.get('disk_src', '') driver_type = params.get('driver_type', 'qcow2') vol_name = params.get('vol_name', 'vol_blockpull') pool_name = params.get('pool_name', '') brick_path = os.path.join(data_dir.get_tmp_dir(), pool_name) vg_name = params.get('vg_name', 'HostVG') vol_size = params.get('vol_size', '10M') vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) bkxml = vmxml.copy() # List to collect paths to delete after test file_to_del = [] virsh_dargs = {'debug': True, 'ignore_status': False} try: all_disks = vmxml.get_disk_source(vm_name) if not all_disks: test.error('Not found any disk file in vm.') image_file = all_disks[0].find('source').get('file') logging.debug('Image file of vm: %s', image_file) # Get all dev of virtio disks to calculate the dev of new disk all_vdisks = [disk for disk in all_disks if disk.find('target').get('dev').startswith('vd')] disk_dev = all_vdisks[-1].find('target').get('dev') new_dev = disk_dev[:-1] + chr(ord(disk_dev[-1]) + 1) # Setup iscsi target if disk_src == 'iscsi': disk_target = libvirt.setup_or_cleanup_iscsi( is_setup=True, is_login=True, image_size='1G') logging.debug('ISCSI target: %s', disk_target) # Setup lvm elif disk_src == 'lvm': # Stop multipathd to avoid vgcreate fail multipathd = service.Factory.create_service("multipathd") multipathd_status = multipathd.status() if multipathd_status: multipathd.stop() # Setup iscsi target device_name = libvirt.setup_or_cleanup_iscsi( is_setup=True, is_login=True, image_size='1G') logging.debug('ISCSI target for lvm: %s', device_name) # Create logical device logical_device = device_name lv_utils.vg_create(vg_name, logical_device) vg_created = True # Create logical volume as backing store vol_bk, vol_disk = 'vol1', 'vol2' lv_utils.lv_create(vg_name, vol_bk, vol_size) disk_target = '/dev/%s/%s' % (vg_name, vol_bk) src_vol = '/dev/%s/%s' % (vg_name, vol_disk) # Setup gluster elif disk_src == 'gluster': host_ip = gluster.setup_or_cleanup_gluster( is_setup=True, brick_path=brick_path, **params) logging.debug(host_ip) gluster_img = 'test.img' img_create_cmd = "qemu-img create -f raw /mnt/%s 10M" % gluster_img process.run("mount -t glusterfs %s:%s /mnt; %s; umount /mnt" % (host_ip, vol_name, img_create_cmd), shell=True) disk_target = 'gluster://%s/%s/%s' % (host_ip, vol_name, gluster_img) else: test.error('Wrong disk source, unsupported by this test.') new_image = os.path.join(os.path.split(image_file)[0], 'test.img') params['snapshot_list'] = ['s%d' % i for i in range(1, 5)] if disk_src == 'lvm': new_image = src_vol if disk_type == 'block': new_image = disk_target for i in range(2, 6): lv_utils.lv_create(vg_name, 'vol%s' % i, vol_size) snapshot_image_list = ['/dev/%s/vol%s' % (vg_name, i) for i in range(2, 6)] else: file_to_del.append(new_image) snapshot_image_list = [new_image.replace('img', i) for i in params['snapshot_list']] cmd_create_img = 'qemu-img create -f %s -b %s %s -F raw' % (driver_type, disk_target, new_image) if disk_type == 'block' and driver_type == 'raw': pass else: process.run(cmd_create_img, verbose=True, shell=True) info_new = utils_misc.get_image_info(new_image) logging.debug(info_new) # Create xml of new disk and add it to vmxml if disk_type: new_disk = Disk() new_disk.xml = libvirt.create_disk_xml({ 'type_name': disk_type, 'driver_type': driver_type, 'target_dev': new_dev, 'source_file': new_image }) logging.debug(new_disk.xml) vmxml.devices = vmxml.devices.append(new_disk) vmxml.xmltreefile.write() logging.debug(vmxml) vmxml.sync() vm.start() logging.debug(virsh.dumpxml(vm_name)) # Create backing chain for i in range(len(params['snapshot_list'])): virsh.snapshot_create_as( vm_name, '%s --disk-only --diskspec %s,file=%s,stype=%s' % (params['snapshot_list'][i], new_dev, snapshot_image_list[i], disk_type), **virsh_dargs ) # Get path of each snapshot file snaps = virsh.domblklist(vm_name, debug=True).stdout.splitlines() for line in snaps: if line.lstrip().startswith(('hd', 'sd', 'vd')): file_to_del.append(line.split()[-1]) qemu_img_cmd = 'qemu-img info --backing-chain %s' % snapshot_image_list[-1] if libvirt_storage.check_qemu_image_lock_support(): qemu_img_cmd += " -U" bc_info = process.run(qemu_img_cmd, verbose=True, shell=True).stdout_text if not disk_type == 'block': bc_chain = snapshot_image_list[::-1] + [new_image, disk_target] else: bc_chain = snapshot_image_list[::-1] + [new_image] bc_result = check_backingchain(bc_chain, bc_info) if not bc_result: test.fail('qemu-img info output of backing chain is not correct: %s' % bc_info) # Generate blockpull/blockcommit options virsh_blk_cmd = eval('virsh.%s' % blockcommand) if blockcommand == 'blockpull' and blk_base != 0: opts += '--base {dev}[{}]'.format(blk_base, dev=new_dev) elif blockcommand == 'blockcommit': opt_top = ' --top {dev}[{}]'.format(blk_top, dev=new_dev) if blk_top != 0 else '' opt_base = ' --base {dev}[{}]'.format(blk_base, dev=new_dev) if blk_base != 0 else '' opts += opt_top + opt_base + ' --active' if blk_top == 0 else '' # Do blockpull/blockcommit virsh_blk_cmd(vm_name, new_dev, opts, **virsh_dargs) if blockcommand == 'blockcommit': virsh.blockjob(vm_name, new_dev, '--pivot', **virsh_dargs) vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) logging.debug("XML after %s: %s" % (blockcommand, vmxml)) # Check backing chain after blockpull/blockcommit check_bc_func_name = 'check_bc_%s' % check_func if check_bc_func_name in globals(): check_bc = eval(check_bc_func_name) if not callable(check_bc): logging.warning('Function "%s" is not callable.', check_bc_func_name) if not check_bc(blockcommand, vmxml, new_dev, bc_chain): test.fail('Backing chain check after %s failed' % blockcommand) else: logging.warning('Function "%s" is not implemented.', check_bc_func_name) virsh.dumpxml(vm_name, debug=True) # Check whether login is successful try: vm.wait_for_login().close() except Exception as e: test.fail('Vm login failed') finally: logging.info('Start cleaning up.') for ss in params.get('snapshot_list', []): virsh.snapshot_delete(vm_name, '%s --metadata' % ss, debug=True) bkxml.sync() for path in file_to_del: logging.debug('Remove %s', path) if os.path.exists(path): os.remove(path) if disk_src == 'iscsi': libvirt.setup_or_cleanup_iscsi(is_setup=False) elif disk_src == 'lvm': process.run('rm -rf /dev/%s/%s' % (vg_name, vol_disk), ignore_status=True) if 'vol_bk' in locals(): lv_utils.lv_remove(vg_name, vol_bk) if 'vg_created' in locals() and vg_created: lv_utils.vg_remove(vg_name) cmd = "pvs |grep %s |awk '{print $1}'" % vg_name pv_name = process.system_output(cmd, shell=True, verbose=True).strip() if pv_name: process.run("pvremove %s" % pv_name, verbose=True, ignore_status=True) libvirt.setup_or_cleanup_iscsi(is_setup=False) elif disk_src == 'gluster': gluster.setup_or_cleanup_gluster( is_setup=False, brick_path=brick_path, **params) if 'multipathd_status' in locals() and multipathd_status: multipathd.start()
def set_domain_disk(vmxml, blk_source, params, test): """ Replace the domain disk with new setup device or download image :param vmxml: The instance of VMXML class :param params: Avocado params object :param test: Avocado test object :param blk_source: The domain disk image path """ disk_type = params.get("disk_type", "file") boot_dev = params.get("boot_dev", "hd") target_dev = params.get("target_dev", "vdb") device_bus = params.get("device_bus", "virtio") disk_img = params.get("disk_img") image_size = params.get("image_size", "3G") vol_name = params.get("vol_name") disk_format = params.get("disk_format", "qcow2") driver_type = params.get("driver_type", "qcow2") mon_host = params.get("mon_host") disk_src_name = params.get("disk_source_name") disk_src_host = params.get("disk_source_host") disk_src_port = params.get("disk_source_port") source_protocol = params.get("source_protocol", "") boot_iso_file = os.path.join(data_dir.get_tmp_dir(), "boot.iso") non_release_os_url = params.get("non_release_os_url", "") download_file_path = os.path.join(data_dir.get_tmp_dir(), "non_released_os.qcow2") brick_path = os.path.join(test.virtdir, "gluster-pool") global cleanup_iscsi global cleanup_gluster disk_params = { 'disk_type': disk_type, 'target_dev': target_dev, 'target_bus': device_bus, 'driver_type': driver_type } if source_protocol == 'iscsi': if disk_type == 'block': kwargs = {'image_size': image_size, 'disk_format': disk_format} iscsi_target = prepare_iscsi_disk(blk_source, **kwargs) if iscsi_target is None: test.error("Failed to create iscsi disk") else: cleanup_iscsi = True disk_params.update({'source_file': iscsi_target}) elif source_protocol == 'gluster': if disk_type == 'network': kwargs = { 'vol_name': vol_name, 'brick_path': brick_path, 'disk_img': disk_img, 'disk_format': disk_format } host_ip = prepare_gluster_disk(blk_source, test, **kwargs) if host_ip is None: test.error("Failed to create glusterfs disk") else: cleanup_gluster = True source_name = "%s/%s" % (vol_name, disk_img) disk_params.update({ 'source_name': source_name, 'source_host_name': host_ip, 'source_host_port': '24007', 'source_protocol': source_protocol }) elif source_protocol == 'rbd': if disk_type == 'network': disk_path = ("rbd:%s:mon_host=%s" % (disk_src_name, mon_host)) disk_cmd = ("qemu-img convert -O %s %s %s" % (disk_format, blk_source, disk_path)) process.run(disk_cmd, ignore_status=False) disk_params.update({ 'source_name': disk_src_name, 'source_host_name': disk_src_host, 'source_host_port': disk_src_port, 'source_protocol': source_protocol }) elif non_release_os_url: disk_params.update({'source_file': download_file_path}) elif boot_dev == "cdrom": disk_params.update({ 'device_type': 'cdrom', 'source_file': boot_iso_file }) else: disk_params.update({'source_file': blk_source}) new_disk = Disk(type_name=disk_type) new_disk.xml = open(create_disk_xml(disk_params)).read() vmxml.remove_all_disk() vmxml.add_device(new_disk)
def set_domain_disk(vmxml, blk_source, params, test): """ Replace the domain disk with new setup device or download image :param vmxml: The instance of VMXML class :param params: Avocado params object :param test: Avocado test object :param blk_source: The domain disk image path """ disk_type = params.get("disk_type", "file") boot_dev = params.get("boot_dev", "hd") target_dev = params.get("target_dev", "vdb") device_bus = params.get("device_bus", "virtio") disk_img = params.get("disk_img") image_size = params.get("image_size", "3G") vol_name = params.get("vol_name") disk_format = params.get("disk_format", "qcow2") driver_type = params.get("driver_type", "qcow2") mon_host = params.get("mon_host") disk_src_name = params.get("disk_source_name") disk_src_host = params.get("disk_source_host") disk_src_port = params.get("disk_source_port") source_protocol = params.get("source_protocol", "") boot_iso_file = os.path.join(data_dir.get_tmp_dir(), "boot.iso") non_release_os_url = params.get("non_release_os_url", "") download_file_path = os.path.join(data_dir.get_tmp_dir(), "non_released_os.qcow2") brick_path = os.path.join(test.virtdir, "gluster-pool") global cleanup_iscsi global cleanup_gluster disk_params = {'disk_type': disk_type, 'target_dev': target_dev, 'target_bus': device_bus, 'driver_type': driver_type} if source_protocol == 'iscsi': if disk_type == 'block': kwargs = {'image_size': image_size, 'disk_format': disk_format} iscsi_target = prepare_iscsi_disk(blk_source, **kwargs) if iscsi_target is None: test.error("Failed to create iscsi disk") else: cleanup_iscsi = True disk_params.update({'source_file': iscsi_target}) elif source_protocol == 'gluster': if disk_type == 'network': kwargs = {'vol_name': vol_name, 'brick_path': brick_path, 'disk_img': disk_img, 'disk_format': disk_format} host_ip = prepare_gluster_disk(blk_source, test, **kwargs) if host_ip is None: test.error("Failed to create glusterfs disk") else: cleanup_gluster = True source_name = "%s/%s" % (vol_name, disk_img) disk_params.update({'source_name': source_name, 'source_host_name': host_ip, 'source_host_port': '24007', 'source_protocol': source_protocol}) elif source_protocol == 'rbd': if disk_type == 'network': disk_path = ("rbd:%s:mon_host=%s" % (disk_src_name, mon_host)) disk_cmd = ("qemu-img convert -O %s %s %s" % (disk_format, blk_source, disk_path)) process.run(disk_cmd, ignore_status=False) disk_params.update({'source_name': disk_src_name, 'source_host_name': disk_src_host, 'source_host_port': disk_src_port, 'source_protocol': source_protocol}) elif non_release_os_url: disk_params.update({'source_file': download_file_path}) elif boot_dev == "cdrom": disk_params.update({'device_type': 'cdrom', 'source_file': boot_iso_file}) else: disk_params.update({'source_file': blk_source}) new_disk = Disk(type_name=disk_type) new_disk.xml = open(create_disk_xml(disk_params)).read() vmxml.remove_all_disk() vmxml.add_device(new_disk)