我一直在尝试使用OpenStack Unified SDK (https://github.com/openstack/python-openstacksdk)创建一个OpenStack映像,通知内核ID和Ramdisk Id ,但没有成功。我知道这是可能的,因为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作为字符串传递会创建实例,但它无法启动。 有谁知道如何解决这个问题?
答案 0 :(得分: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似乎无法将这两个argments转换为url(因为openstack / image / v2 / image.py中没有Body定义。所以你应该修改OpenStack SDK来支持这个。
BTW,OpenStack的代码与它的版本略有不同,但很多东西是相同的。