当前位置: 首页 > 工具软件 > Specs > 使用案例 >

openstack-nova源码分析(五)flavor extra_specs 扩展属性

梁巴英
2023-12-01

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及命令行
  1. url
    API为标准的restful API 风格 支持GET , POST, PUT, DELETE 方法:
    /flavors/{flavor_id}/os-extra_specs
    /flavors/{flavor_id}/os-extra_specs/{flavor_extra_spec_key}

  2. 命令行
    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                                    |
+----------------------------+--------------------------------------+

 类似资料: