OpenStack SDK — Как создать образ с параметрами ID ядра и Ramdisk?

Я пытался создать образ OpenStack, сообщающий идентификатор ядра и идентификатор Ramdisk, используя OpenStack Unified SDK (https://github.com/openstack/python-openstacksdk), но безуспешно. Я знаю, что это возможно, поскольку интерфейс командной строки OpenStack имеет эти параметры, как показано на этой странице (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, но безуспешно, передача идентификатора ядра и идентификатора ramdisk в виде строк создает экземпляр, но он не загружается. Кто-нибудь знает, как это решить?


person Vini.g.fer    schedule 09.09.2016    source источник


Ответы (1)


какую версию 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 немного отличается от его версии, но многое осталось прежним.

person findmyway    schedule 12.09.2016
comment
Уже попробовал ваше предложение для atrib = { 'kernel_id': 'd84e1f2b-8d8c-4a4a-8858-77a8d5a93cb1', 'ramdisk_id': 'cfef18e0-006e-477a-a098-593d43435a1e' }, но SDK, похоже, молча отбрасывает эти параметры. - person Vini.g.fer; 12.09.2016
comment
да, я упомянул об этом в своем ответе. поэтому вам следует изменить код в openstack/image/v2/image.py, вы можете попробовать добавить resource2.Body('kernel_id') и resource2.Body('ramdisk_id') и повторить попытку - person findmyway; 13.09.2016
comment
SDK исправил это, вам следует обновиться. - person findmyway; 23.11.2016
comment
Я знаю, я тот, кто открыл ошибку в lauchpad. Забыл отметить этот вопрос как решенный. - person Vini.g.fer; 23.11.2016