问题描述:

I've been trying to create an OpenStack image informing the Kernel Id and Ramdisk Id, using the OpenStack Unified SDK (https://github.com/openstack/python-openstacksdk), but without success. I know this is possible, because the OpenStack CLI have this parameters, as shown on this page (http://docs.openstack.org/cli-reference/glance.html#glance-image-create), where the CLI have the "--kernel-id" and "--ramdisk-id" parameters. I've used this parameter in the terminal and confirmed they work, but I need to use them in python.

I'm trying to use the upload_method, as described here http://developer.openstack.org/sdks/python/openstacksdk/users/proxies/image.html#image-api-v2 but I can't get the attrs parameter right. Documentation only say it is suposed to be a dictionary. Here is the code I'm using

...

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)

....

And here is the error I'm getting:

 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'}

Already tried to use the update_image method, but without success, passing kernel id and ramdisk id as a strings creates the instance, but it does not boot.

Does anyone knows how to solve this?

网友答案:

what the version of the glance api you use?

I have read the code in 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)
    ...

and openstackclient/v2/shell.py,openstackclient/image/v2.images.py(and i have debuged this too)

## 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)
        ...

it seems that, you can create a image use your way in version 1.0, but in version 2.0, you should use the kernel_id and ramdisk_id as below

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

but the OpenStack SDK seems it can't trans those two argments to the url (because there is no Body define in openstack/image/v2/image.py. so you should modify the OpenStack SDK to support this.

BTW, the code of OpenStack is a little different from it's version, but many things are same.

相关阅读:
Top