Flavors extra-specs (flavors, os-flavor-extra-specs)
Flavor 扩展属性设置, 扩展属性可以用来对虚拟机做一些额外的限制设置,具体的参数,将在后面的博客中做统一列出,这里暂时不做列出
openstack api 定义如下:
Lists, creates, deletes, and updates the extra-specs or keys for a flavor.
Refer to Compute Flavors for available built-in extra specs.
url
API为标准的restful API 风格 支持GET , POST, PUT, DELETE 方法:
/flavors/{flavor_id}/os-extra_specs
/flavors/{flavor_id}/os-extra_specs/{flavor_extra_spec_key}
命令行
nova flavor-key
对应的方法在: flavors_extraspecs = nova.api.openstack.compute.flavors_extraspecs:FlavorsExtraSpecs
FlavorsExtraSpecs定义如下:
class FlavorsExtraSpecs(extensions.V21APIExtensionBase):
"""Flavors extra specs support."""
name = 'FlavorExtraSpecs'
alias = ALIAS
version = 1
def get_resources(self):
extra_specs = extensions.ResourceExtension(
'os-extra_specs',
FlavorExtraSpecsController(),
parent=dict(member_name='flavor', collection_name='flavors'))
return [extra_specs]
get_resources 将os-extra_specs 注册到collection flavors 下, 处理方法映射到FlavorExtraSpecsController
查看FlavorExtraSpecsController 为标准的restful api处理方法
def index(self, req, flavor_id):
"""Returns the list of extra specs for a given flavor."""
context = req.environ['nova.context']
context.can(fes_policies.POLICY_ROOT % 'index')
return self._get_extra_specs(context, flavor_id)
index实际处理_get_extra_specs函数
def _get_extra_specs(self, context, flavor_id):
flavor = common.get_flavor(context, flavor_id)
return dict(extra_specs=flavor.extra_specs)
flavor.extra_specs获取扩展属性,并转换为dict
get_flavor 实际调用的是Flavor show一样的方法,这里不做重复分析
1. 创建接口:
@extensions.expected_errors((400, 404, 409))
@validation.schema(flavors_extraspecs.create)
def create(self, req, flavor_id, body):
context = req.environ['nova.context']
context.can(fes_policies.POLICY_ROOT % 'create')
specs = body['extra_specs']
self._check_extra_specs_value(specs)
flavor = common.get_flavor(context, flavor_id)
try:
flavor.extra_specs = dict(flavor.extra_specs, **specs)
flavor.save()
except exception.FlavorExtraSpecUpdateCreateFailed as e:
raise webob.exc.HTTPConflict(explanation=e.format_message())
except exception.FlavorNotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
return body
注: 创建接口只对参数的长度及字符合法性做了校验,没有做是否允许key与合法value的校验
create方法,仍然先查询flavorid 并返回Flavor
通过Flavor 调用save函数
save实际是检查对象的改变项并将其更新,或创建, 或删除
2. update 更新操作:
@extensions.expected_errors((400, 404, 409))
@validation.schema(flavors_extraspecs.update)
def update(self, req, flavor_id, id, body):
context = req.environ['nova.context']
context.can(fes_policies.POLICY_ROOT % 'update')
self._check_extra_specs_value(body)
if id not in body:
expl = _('Request body and URI mismatch')
raise webob.exc.HTTPBadRequest(explanation=expl)
flavor = common.get_flavor(context, flavor_id)
try:
flavor.extra_specs = dict(flavor.extra_specs, **body)
flavor.save()
except exception.FlavorExtraSpecUpdateCreateFailed as e:
raise webob.exc.HTTPConflict(explanation=e.format_message())
except exception.FlavorNotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
return body
这里与create大同小异, 需要注意的是: 这里是全量更新,不修改的key也需要将原来的值传入,否则将会被删除
3 delete 删除操作:
@extensions.expected_errors(404)
def delete(self, req, flavor_id, id):
"""Deletes an existing extra spec."""
context = req.environ['nova.context']
context.can(fes_policies.POLICY_ROOT % 'delete')
flavor = common.get_flavor(context, flavor_id)
try:
del flavor.extra_specs[id]
flavor.save()
except (exception.FlavorExtraSpecsNotFound,
exception.FlavorNotFound) as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
except KeyError:
msg = _("Flavor %(flavor_id)s has no extra specs with "
"key %(key)s.") % dict(flavor_id=flavor_id,
key=id)
raise webob.exc.HTTPNotFound(explanation=msg)
这里直接通过del flavor.extra_specs[id] 将Flavor对象的extra_specs中的id key删除
save函数,对比属性的更新,自动清除不存在的key,并在数据库删除对应的数据
注: novaclient中对应 Flavor操作额外属性时,不能调用delete函数,因为delete将直接删除Flavor,应该调用unset_keys 将key一个一个清除, 这里踩了个小坑
def delete(self):
"""
Delete this flavor.
:returns: An instance of novaclient.base.TupleWithMeta
"""
return self.manager.delete(self)
三. 测试:
可以通过命令功能: flavor-key 进行测试
[root@nova ~]# nova help flavor-key
usage: nova flavor-key <flavor> <action> <key=value> [<key=value> ...]
Set or unset extra_spec for a flavor.
Positional arguments:
<flavor> Name or ID of flavor.
<action> Actions: 'set' or 'unset'.
<key=value> Extra_specs to set/unset (only key is necessary on unset).
首先创建一个flavor: nova flavor-create ‘1-2-50’ ‘auto’ 2 50 1
[root@nova ~]# nova flavor-create '1-2-50' 'auto' 2 50 1
+--------------------------------------+--------+-----------+------+-----------+------+-------+-------------+-----------+
| ID | Name | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+--------------------------------------+--------+-----------+------+-----------+------+-------+-------------+-----------+
| 92c4d107-6926-4adb-9e79-cd101e4fa588 | 1-2-50 | 2 | 50 | 0 | | 1 | 1.0 | True |
+--------------------------------------+--------+-----------+------+-----------+------+-------+-------------+-----------+
设置testkey
[root@nova ~]# nova flavor-key 92c4d107-6926-4adb-9e79-cd101e4fa588 set testkey='123456'
查看是否设置成功
[root@nova ~]# nova flavor-show 92c4d107-6926-4adb-9e79-cd101e4fa588
+----------------------------+--------------------------------------+
| Property | Value |
+----------------------------+--------------------------------------+
| OS-FLV-DISABLED:disabled | False |
| OS-FLV-EXT-DATA:ephemeral | 0 |
| disk | 50 |
| extra_specs | {"testkey": "123456"} |
| id | 92c4d107-6926-4adb-9e79-cd101e4fa588 |
| name | 1-2-50 |
| os-flavor-access:is_public | True |
| ram | 2 |
| rxtx_factor | 1.0 |
| swap | |
| vcpus | 1 |
+----------------------------+--------------------------------------+
更新key
更新操作,直接调用与create一样的命令,修改value值即可
[root@nova ~]# nova flavor-key 92c4d107-6926-4adb-9e79-cd101e4fa588 set testkey='12345678'
查看是否更新成功
[root@nova ~]# nova flavor-show 92c4d107-6926-4adb-9e79-cd101e4fa588
+----------------------------+--------------------------------------+
| Property | Value |
+----------------------------+--------------------------------------+
| OS-FLV-DISABLED:disabled | False |
| OS-FLV-EXT-DATA:ephemeral | 0 |
| disk | 50 |
| extra_specs | {"testkey": "12345678"} |
| id | 92c4d107-6926-4adb-9e79-cd101e4fa588 |
| name | 1-2-50 |
| os-flavor-access:is_public | True |
| ram | 2 |
| rxtx_factor | 1.0 |
| swap | |
| vcpus | 1 |
+----------------------------+--------------------------------------+
删除testkey
[root@nova ~]# nova flavor-key 92c4d107-6926-4adb-9e79-cd101e4fa588 unset testkey
查看是否删除成功
[root@nova ~]# nova flavor-show 92c4d107-6926-4adb-9e79-cd101e4fa588
+----------------------------+--------------------------------------+
| Property | Value |
+----------------------------+--------------------------------------+
| OS-FLV-DISABLED:disabled | False |
| OS-FLV-EXT-DATA:ephemeral | 0 |
| disk | 50 |
| extra_specs | {} |
| id | 92c4d107-6926-4adb-9e79-cd101e4fa588 |
| name | 1-2-50 |
| os-flavor-access:is_public | True |
| ram | 2 |
| rxtx_factor | 1.0 |
| swap | |
| vcpus | 1 |
+----------------------------+--------------------------------------+