当前位置: > 虚拟化 Virtualization > oVirt >

oVirt备份-还原磁盘快照

时间:2019-11-29 19:03来源:linux.it.net.cn 作者:IT
备份-还原磁盘快照
 
摘要
 
此功能是补充组件,用于提供备份和还原虚拟机的功能。该功能引入了对使用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)
------分隔线----------------------------