0

我一直在尝试使用 OpenStack Unified SDK ( https://github.com/openstack/python-openstacksdk ) 创建一个通知内核 ID 和 Ramdisk ID 的 OpenStack 映像,但没有成功。我知道这是可能的,因为 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 作为字符串传递会创建实例,但它不会启动。有谁知道如何解决这个问题?

4

1 回答 1

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 的代码与它的版本有点不同,但很多东西都是一样的。

于 2016-09-12T03:41:45.900 回答