【问题标题】:OpenStack SDK - How to create image with Kernel id and Ramdisk parameters?OpenStack SDK - 如何使用内核 id 和 Ramdisk 参数创建映像?
【发布时间】:2016-09-09 19:07:39
【问题描述】:

我一直在尝试创建一个 OpenStack 映像来通知内核 ID 和 Ramdisk ID,使用 OpenStack Unified SDK (https://github.com/openstack/python-openstacksdk),但没有成功。我知道这是可能的,因为 OpenStack CLI 具有此参数,如本页 (http://docs.openstack.org/cli-reference/glance.html#glance-image-create) 所示,其中 CLI 具有“--kernel-id”和“--ramdisk-id”参数。我已经在终端中使用了这个参数并确认它们可以工作,但是我需要在 python 中使用它们。

我正在尝试使用upload_method,如http://developer.openstack.org/sdks/python/openstacksdk/users/proxies/image.html#image-api-v2 所述,但我无法正确设置attrs 参数。文档只说它应该是一本字典。这是我正在使用的代码

...
    atrib = {
        'properties': {
            'kernel_id': 'd84e1f2b-8d8c-4a4a-8858-77a8d5a93cb1',
            'ramdisk_id': 'cfef18e0-006e-477a-a098-593d43435a1e'
        } 
    } 
    with open(file) as fimage:
    image = image_service.upload_image(
        name=name,
        data=fimage,
        disk_format='qcow2',
        container_format='bare',
        **atrib)
....

这是我得到的错误:

  File "builder.py", line 121, in main
    **atrib
  File "/usr/lib/python2.7/site-packages/openstack/image/v2/_proxy.py", line 51, in upload_image
    **attrs)
  File "/usr/lib/python2.7/site-packages/openstack/proxy2.py", line 193, in _create
    return res.create(self.session)
  File "/usr/lib/python2.7/site-packages/openstack/resource2.py", line 570, in create
    json=request.body, headers=request.headers)
  File "/usr/lib/python2.7/site-packages/keystoneauth1/session.py", line 675, in post
    return self.request(url, 'POST', **kwargs)
  File "/usr/lib/python2.7/site-packages/openstack/session.py", line 52, in map_exceptions_wrapper
    http_status=e.http_status, cause=e)
openstack.exceptions.HttpException: HttpException: Bad Request, 400 Bad Request

Provided object does not match schema 'image': {u'kernel_id': u'd84e1f2b-8d8c-4a4a-8858-77a8d5a93cb1', u'ramdisk_id': u'cfef18e0-006e-477a-a098-593d43435a1e'} is not of type 'string'  Failed validating 'type' in schema['additionalProperties']:     {'type': 'string'}  On instance[u'properties']:     {u'kernel_id': u'd84e1f2b-8d8c-4a4a-8858-77a8d5a93cb1',      u'ramdisk_id': u'cfef18e0-006e-477a-a098-593d43435a1e'}

已经尝试使用 update_image 方法,但没有成功,将内核 id 和 ramdisk id 作为字符串传递会创建实例,但它不会启动。 有谁知道如何解决这个问题?

【问题讨论】:

    标签: openstack openstack-nova openstack-glance openstack-python-api openstack-api


    【解决方案1】:

    你使用的glance api是什么版本的?

    我已经阅读了openstackclient/image/v1/images.py、openstackclient/v1/shell.py 中的代码

    ## in shell.py
    def do_image_create(gc, args):
        ...
        fields = dict(filter(lambda x: x[1] is not None, vars(args).items()))
    
        raw_properties = fields.pop('property')
        fields['properties'] = {}
        for datum in raw_properties:
            key, value = datum.split('=', 1)
            fields['properties'][key] = value
        ...    
    
        image = gc.images.create(**fields)
    
    ## in images.py
    def create(self, **kwargs):
        ...
        for field in kwargs:
            if field in CREATE_PARAMS:
                fields[field] = kwargs[field]
            elif field == 'return_req_id':
                continue
            else:
                msg = 'create() got an unexpected keyword argument \'%s\''
                raise TypeError(msg % field)
    
        hdrs = self._image_meta_to_headers(fields)
        ...
        resp, body = self.client.post('/v1/images',
                                      headers=hdrs,
                                      data=image_data)
        ...
    

    openstackclient/v2/shell.py,openstackclient/image/v2.images.py(我也调试过这个)

    ## in shell.py
    def do_image_create(gc, args):
        ...
        raw_properties = fields.pop('property', [])
        for datum in raw_properties:
            key, value = datum.split('=', 1)
            fields[key] = value
        ...
        image = gc.images.create(**fields)
    
    ##in images.py
    def create(self, **kwargs):
            """Create an image.""
            url = '/v2/images'
    
            image = self.model()
            for (key, value) in kwargs.items():
                try:
                    setattr(image, key, value)
                except warlock.InvalidOperation as e:
                    raise TypeError(utils.exception_to_str(e))
    
            resp, body = self.http_client.post(url, data=image)
            ...
    

    看来,在1.0版本你可以用你自己的方式创建镜像,但在2.0版本,你应该使用如下的kernel_id和ramdisk_id

    atrib = {        
            'kernel_id': 'd84e1f2b-8d8c-4a4a-8858-77a8d5a93cb1',
            'ramdisk_id': 'cfef18e0-006e-477a-a098-593d43435a1e' 
    } 
    

    但 OpenStack SDK 似乎无法将这两个参数转换为 url(因为在 openstack/image/v2/image.py 中没有定义 Body。所以您应该修改 OpenStack SDK 以支持这一点。

    顺便说一句,OpenStack 的代码和它的版本有点不同,但很多东西都是一样的。

    【讨论】:

    • 已经尝试过您对atrib = { 'kernel_id': 'd84e1f2b-8d8c-4a4a-8858-77a8d5a93cb1', 'ramdisk_id': 'cfef18e0-006e-477a-a098-593d43435a1e' } 的建议,但SDK 似乎默默地删除了这些参数。
    • 是的,我在回答中提到了这一点。所以你应该修改openstack/image/v2/image.py中的代码,你可以尝试添加resource2.Body('kernel_id')和resource2.Body('ramdisk_id')再试一次
    • SDK 已修复此问题,您应该升级。
    • 我知道,我是在 lauchpad 中打开错误的人。忘记将此问题标记为已解决。
    猜你喜欢
    • 2016-05-10
    • 2010-10-14
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 2012-12-18
    • 2023-01-27
    • 1970-01-01
    相关资源
    最近更新 更多