使用 OpenStack Image

在使用 Image 服务之前,您需要通过遵循 连接 用户指南来创建与您的 OpenStack 云的连接。这将为您提供在以下示例中使用的 conn 变量。

Image 服务的首要资源是镜像。

列出镜像

镜像是用于创建或重建服务器的特定操作系统的文件集合。OpenStack 提供 预构建镜像。您还可以从已启动的服务器创建自定义镜像或快照。镜像有不同的格式,有时也称为虚拟机镜像。

def list_images(conn):
    print("List Images:")

    for image in conn.image.images():
        print(image)

完整示例:镜像资源列表

创建镜像

通过上传其数据并设置其属性来创建镜像。

def upload_image(conn):
    print("Upload Image:")

    # Load fake image data for the example.
    data = 'This is fake image data.'

    # Build the image attributes and upload the image.
    image_attrs = {
        'name': EXAMPLE_IMAGE_NAME,
        'data': data,
        'disk_format': 'raw',
        'container_format': 'bare',
        'visibility': 'public',
    }
    conn.image.upload_image(**image_attrs)

完整示例:镜像资源创建

通过可互操作镜像导入流程创建镜像

创建镜像,然后使用可互操作镜像导入流程从 Web URL 下载数据。

有关镜像导入流程的更多信息,请查看 可互操作镜像导入

def import_image(conn):
    print("Import Image:")

    # Url where glance can download the image
    uri = (
        'https://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img'
    )

    # Build the image attributes and import the image.
    image_attrs = {
        'name': EXAMPLE_IMAGE_NAME,
        'disk_format': 'qcow2',
        'container_format': 'bare',
        'visibility': 'public',
    }
    image = conn.image.create_image(**image_attrs)
    conn.image.import_image(image, method="web-download", uri=uri)

完整示例:镜像资源导入

使用 stream=True 下载镜像

由于镜像通常是大量数据,因此将其全部存储在应用程序的内存中可能不太理想。更有效的方法可能是迭代响应数据流。

通过选择流式传输响应内容,您可以确定适合您需求的 chunk_size,这意味着每次循环迭代仅读取那么多字节的数据,直到消耗完所有数据。有关更多信息,请参阅 requests.Response.iter_content()

当您选择流式传输镜像下载时,openstacksdk 将不再能够为您计算响应数据的校验和。本示例演示了您如何以类似于库计算非流式响应校验和的方式自行执行此操作。

def download_image_stream(conn):
    print("Download Image via streaming:")

    # Find the image you would like to download.
    image = conn.image.find_image("myimage")

    # As the actual download now takes place outside of the library
    # and in your own code, you are now responsible for checking
    # the integrity of the data. Create an MD5 has to be computed
    # after all of the data has been consumed.
    md5 = hashlib.md5(usedforsecurity=False)

    with open("myimage.qcow2", "wb") as local_image:
        response = conn.image.download_image(image, stream=True)

        # Read only 1 MiB of memory at a time until
        # all of the image data has been consumed.
        for chunk in response.iter_content(chunk_size=1024 * 1024):
            # With each chunk, add it to the hash to be computed.
            md5.update(chunk)

            local_image.write(chunk)

        # Now that you've consumed all of the data the response gave you,
        # ensure that the checksums of what the server offered and
        # what you downloaded are the same.
        if response.headers["Content-MD5"] != md5.hexdigest():
            raise Exception("Checksum mismatch in downloaded content")

使用 stream=False 下载镜像

如果您希望一次性将镜像内容全部下载到内存中,只需设置 stream=False,这是默认设置。

def download_image(conn):
    print("Download Image:")

    # Find the image you would like to download.
    image = conn.image.find_image("myimage")

    with open("myimage.qcow2", "w") as local_image:
        response = conn.image.download_image(image)

        # Response will contain the entire contents of the Image.
        local_image.write(response)

完整示例:镜像资源下载

删除镜像

删除镜像。

def delete_image(conn):
    print("Delete Image:")

    example_image = conn.image.find_image(EXAMPLE_IMAGE_NAME)

    conn.image.delete_image(example_image, ignore_missing=False)

完整示例:镜像资源删除