| 
       
		备份-还原磁盘快照 
	
		摘要 
	
		此功能是补充组件,用于提供备份和还原虚拟机的功能。该功能引入了对使用REST-API下载和上传磁盘快照的支持。使用ovirt-imageio促进图像传输 
	
		使用oVirt Python-SDK可简化以下备份/还原示例。oVirt REST-API / SDK可以类似的方式使用。 
	
		后备 
	
		下载VM OVF 
	
		完整的例子 
	
		为了获取VM配置数据,应指定'all_content'标志。然后,可以将其写入一个新文件-OVF。注意:OVF包含有关磁盘和快照的足够信息,可以将VM恢复到原始状态(例如,别名/描述/日期)。但是,它不是由系统自动解析的,而是应该由SDK用户完成的。 
	
		vm_name = 'myvm' 
	
		vm = vms_service.list(search="name=%s" % vm_name, all_content=True)[0] 
	
		ovf_filename = "%s.ovf" % vm.id 
	
		with open(ovf_filename, "wb") as ovf_file: 
	
		    ovf_file.write(vm.initialization.configuration.data) 
	
		下载磁盘 
	
		完整的例子 
	
		以下示例演示了下载指定磁盘的非活动磁盘快照的过程。因此,为了也包括活动层,请预先为磁盘创建一个新的快照,或者使用“ 下载磁盘”示例下载活动磁盘快照 
	
		为了下载活跃 
	
		对于每个磁盘,遍历其磁盘快照并执行映像传输。 
	
		  # Set relevant disk and stroage domain IDs 
	
		  disk_id = 'ccdd6487-0a8f-40c8-9f45-40e0e2b30d79' 
	
		  sd_name = 'mydata' 
	
		  # Get a reference to the storage domains service: 
	
		  storage_domains_service = system_service.storage_domains_service() 
	
		  # Look up for the storage domain by name: 
	
		  storage_domain = storage_domains_service.list(search='name=%s' % sd_name)[0] 
	
		  # Get a reference to the storage domain service in which the disk snapshots reside: 
	
		  storage_domain_service = storage_domains_service.storage_domain_service(storage_domain.id) 
	
		  # Get a reference to the disk snapshots service: 
	
		  disk_snapshot_service = storage_domain_service.disk_snapshots_service() 
	
		  # Get a list of disk snapshots by a disk ID 
	
		  all_disk_snapshots = disk_snapshot_service.list() 
	
		  # Filter disk snapshots list by disk id 
	
		  disk_snapshots = [s for s in all_disk_snapshots if s.disk.id == disk_id] 
	
		  # Download disk snapshots 
	
		  for disk_snapshot in disk_snapshots: 
	
		      download_disk_snapshot(disk_snapshot) 
	
		应使用“快照”属性指定ImageTransfer对象。 
	
		  transfer = transfers_service.add( 
	
		      types.ImageTransfer( 
	
		          snapshot=types.DiskSnapshot(id=disk_snapshot_id), 
	
		          direction=types.ImageTransferDirection.DOWNLOAD, 
	
		      ) 
	
		  ) 
	
		恢复 
	
		完整的例子 
	
		组成磁盘快照链 
	
		使用保存的图像文件,创建一个磁盘快照链。通过获取每个文件的卷信息(使用qemu-img)并找到后备文件名(卷的父文件)来构建链。通过维护父卷和子卷之间的映射,我们可以从基本卷开始构建链。 
	
		    volumes_info = {}   # {filename -> vol_info} 
	
		    backing_files = {}  # {backing_file (parent) -> vol_info (child)} 
	
		    for root, dirs, file_names in os.walk(disk_path): 
	
		        for file_name in file_names: 
	
		            volume_info = get_volume_info("%s/%s" % (disk_path, file_name)) 
	
		            volumes_info[file_name] = volume_info 
	
		            if 'full-backing-filename' in volume_info: 
	
		                backing_files[volume_info['full-backing-filename']] = volume_info 
	
		    base_volume = [v for v in volumes_info.values() if 'full-backing-filename' not in v ][0] 
	
		    child = backing_files[base_volume['filename']] 
	
		    images_chain = [base_volume] 
	
		    while child != None: 
	
		        images_chain.append(child) 
	
		        parent = child 
	
		        if parent['filename'] in backing_files: 
	
		            child = backing_files[parent['filename']] 
	
		        else: 
	
		            child = None 
	
		    return images_chain 
	
		创建磁盘 
	
		对于每个磁盘,使用上一步中生成的映像链调用基本映像的磁盘创建。磁盘的内容将在以后的步骤中上载。 
	
		    base_image = images_chain[0] 
	
		    initial_size = base_image['actual-size'] 
	
		    provisioned_size = base_image['virtual-size'] 
	
		    image_id = os.path.basename(base_image['filename']) 
	
		    disk = disks_service.add( 
	
		        types.Disk( 
	
		            id=disk_id, 
	
		            image_id=image_id, 
	
		            name=disk_id, 
	
		            format=types.DiskFormat.RAW, 
	
		            provisioned_size=provisioned_size, 
	
		            initial_size=initial_size, 
	
		            storage_domains=[ 
	
		                types.StorageDomain( 
	
		                    name=sd_name 
	
		                ) 
	
		            ] 
	
		        ) 
	
		    ) 
	
		从OVF添加VM 
	
		通过在配置元素中指定ovf数据来添加保存的VM。 
	
		    ovf_file_path = 'c3a8e806-106d-4aff-b59a-3a113eabf5a9.ovf' 
	
		    ovf_data = open(ovf_file_path, 'r').read() 
	
		    vms_service = system_service.vms_service() 
	
		    vm = vms_service.add( 
	
		        types.Vm( 
	
		            cluster=types.Cluster( 
	
		                name='Default', 
	
		            ), 
	
		            initialization = types.Initialization( 
	
		                configuration = types.Configuration( 
	
		                    type = types.ConfigurationType.OVF, 
	
		                    data = ovf_data 
	
		                ) 
	
		            ), 
	
		        ), 
	
		    ) 
	
		创建快照 
	
		对于链中的每个磁盘快照,使用磁盘ID和映像ID(以及可选的已保存描述)创建快照。 
	
		    # Locate the service that manages the snapshots of the virtual machine: 
	
		    snapshots_service = vm_service.snapshots_service() 
	
		    # Add the new snapshot: 
	
		    snapshot = snapshots_service.add( 
	
		        types.Snapshot( 
	
		            description=description, 
	
		            disk_attachments=[ 
	
		                types.DiskAttachment( 
	
		                    disk=types.Disk( 
	
		                        id=disk_id, 
	
		                        image_id=image_id 
	
		                    ) 
	
		                ) 
	
		            ] 
	
		        ), 
	
		    ) 
	
		上传磁盘 
	
		对于链中的每个磁盘快照,开始上载传输。 
	
		    # Get a reference to the service that manages the image transfer: 
	
		    transfers_service = system_service.image_transfers_service() 
	
		    # Add a new image transfer: 
	
		    transfer = transfers_service.add( 
	
		        types.ImageTransfer( 
	
		            snapshot=types.DiskSnapshot(id=disk_snapshot_id), 
	
		            direction=types.ImageTransferDirection.UPLOAD, 
	
		        ) 
	
		    ) 
	
		    # Get reference to the created transfer service: 
	
		    transfer_service = transfers_service.image_transfer_service(transfer.id) 
	
		    while transfer.phase == types.ImageTransferPhase.INITIALIZING: 
	
		        time.sleep(1) 
	
		        transfer = transfer_service.get() 
	
		    try: 
	
		        proxy_url = urlparse(transfer.proxy_url) 
	
		        proxy_connection = get_proxy_connection(proxy_url) 
	
		        path = disk_path 
	
		        # Set needed headers for uploading: 
	
		        upload_headers = { 
	
		            'Authorization': transfer.signed_ticket, 
	
		        } 
	
		        with open(path, "rb") as disk: 
	
		            size = os.path.getsize(path) 
	
		            chunk_size = 1024 * 1024 * 8 
	
		            pos = 0 
	
		            while pos < size: 
	
		                # Extend the transfer session. 
	
		                transfer_service.extend() 
	
		                # Set the content range, according to the chunk being sent. 
	
		                upload_headers['Content-Range'] = "bytes %d-%d/%d" % (pos, min(pos + chunk_size, size) - 1, size) 
	
		                # Perform the request. 
	
		                proxy_connection.request( 
	
		                    'PUT', 
	
		                    proxy_url.path, 
	
		                    disk.read(chunk_size), 
	
		                    headers=upload_headers, 
	
		                ) 
	
		                # Print response 
	
		                r = proxy_connection.getresponse() 
	
		                print r.status, r.reason, "Completed", "{:.0%}".format(pos / float(size)) 
	
		                # Continue to next chunk. 
	
		                pos += chunk_size 
	
		        print "Completed", "{:.0%}".format(pos / float(size)) 
	
		    finally: 
	
		        # Finalize the session. 
	
		        transfer_service.finalize() 
	
		附录 
	
		Python SDK范例 
	
		下载VM OVF 
	
		下载磁盘快照 
	
		上传磁盘快照 
	
		下载磁盘 
	
		上传磁盘 
	(责任编辑:IT)  | 
    
