问题导读:
1、Quota类是如何定义的?
今天,我们继续接着昨天的内容,进行OpenStack建立实例完整过程源码的分析
好了,步如正题了
继续看方法get_project_quotas:
- def get_project_quotas(self, context, resources, project_id,
- quota_class=None, defaults=True,
- usages=True):
- """
- 根据给定的资源列表,对于给定的对象进行磁盘配额检索;返回磁盘配额;
- """
-
- quotas = {}
-
- # 对于一个给定的项目,检索它的所有的磁盘配额;
- # 根据project_id查询数据库中相应项目的数据库信息,获取其中的hard_limit值,也就是获取规定的资源最大限额值;
- project_quotas = db.quota_get_all_by_project(context, project_id)
-
- # 检索一个给定资源的当前的所有相关的使用情况;
- if usages:
- project_usages = db.quota_usage_get_all_by_project(context,project_id)
-
- # 通过适当的类获取配额信息。如果project ID匹配context中的一个,那么使用context中的quota_class类,否则,使用所提供的quota_class类(如果有的话)。
- # 选取合适的类,为后面做准备;
- if project_id == context.project_id:
- quota_class = context.quota_class
- if quota_class:
- class_quotas = db.quota_class_get_all_by_name(context, quota_class)
- else:
- class_quotas = {}
-
- for resource in resources.values():
- # Omit default/quota class values
- if not defaults and resource.name not in project_quotas:
- continue
-
- quotas[resource.name] = dict(
- limit=project_quotas.get(resource.name, class_quotas.get(resource.name, resource.default)),
- )
-
- # Include usages if desired. This is optional because one
- # internal consumer of this interface wants to access the
- # usages directly from inside a transaction.
- if usages:
- usage = project_usages.get(resource.name, {})
- quotas[resource.name].update(
- in_use=usage.get('in_use', 0),
- reserved=usage.get('reserved', 0),
- )
-
- return quotas
复制代码
调用这个方法时传入的参数值:
- context = <nova.context.RequestContext object at 0x4e06d90>
- sub_resources = {'instances': <nova.quota.ReservableResource object at 0x2f1e610>, 'ram': <nova.quota.ReservableResource object at 0x2f1e690>, 'cores': <nova.quota.ReservableResource object at 0x2f1e650>}
- project_id = 0e492e86f22e4d19bd523f1e7ca64566
- context.quota_class = None
复制代码
首先看语句:
- project_quotas = db.quota_get_all_by_project(context, project_id)
复制代码
主要实现了根据指定project_id查询数据库,获取规定的各种资源的限定值,以字典的形式返回给project_quotas。进入方法quota_get_all_by_project:
- def quota_get_all_by_project(context, project_id):
- """
- 根据project_id查询数据库中相应项目的数据库信息,获取其中的hard_limit值,也就是获取规定的某一资源最大限额值;
- """
- nova.context.authorize_project_context(context, project_id)
-
- rows = model_query(context, models.Quota, read_deleted="no").\
- filter_by(project_id=project_id).\
- all()
-
- result = {'project_id': project_id}
- for row in rows:
- result[row.resource] = row.hard_limit
-
- return result
复制代码
再看类Quota的定义:
- class Quota(BASE, NovaBase):
- """
- 表示针对一个project的配额信息类;
- """
-
- __tablename__ = 'quotas'
- id = Column(Integer, primary_key=True)
-
- project_id = Column(String(255), index=True)
-
- resource = Column(String(255))
- hard_limit = Column(Integer, nullable=True)
复制代码
我们可以知道quota_get_all_by_project返回给project_quotas的结果result是一个字典,它的结果是这种形式:
- result = {'project_id': project_id, 'resource1':hard_limit1, 'resource2':hard_limit2,'resource3':hard_limit3, ......}
-
- project_quotas ={'project_id': project_id, 'resource1':hard_limit1, 'resource2':hard_limit2, 'resource3':hard_limit3, ......}
复制代码
再来看语句:
- if usages:
- project_usages = db.quota_usage_get_all_by_project(context,project_id)
复制代码
对于usages这个变量,源码中是这样解释的,如果其值设置为True,则当前的in_use和reserved counts也将会被获取并返回;
来看看方法quota_usage_get_all_by_project:
- def quota_usage_get_all_by_project(context, project_id):
- """
- 根据project_id查询数据库,获取各种资源的in_use和reserved配额数据信息;
- """
- nova.context.authorize_project_context(context, project_id)
-
- rows = model_query(context, models.QuotaUsage, read_deleted="no").\
- filter_by(project_id=project_id).\
- all()
-
- result = {'project_id': project_id}
- for row in rows:
- result[row.resource] = dict(in_use=row.in_use, reserved=row.reserved)
-
- return result
复制代码
再来看类QuotaUsage的定义:
- class QuotaUsage(BASE, NovaBase):
- """
- 表示一个给定资源当前的使用情况;
- """
-
- __tablename__ = 'quota_usages'
- id = Column(Integer, primary_key=True)
-
- project_id = Column(String(255), index=True)
- resource = Column(String(255))
-
- in_use = Column(Integer)
- reserved = Column(Integer)
-
- @property
- def total(self):
- return self.in_use + self.reserved
-
- until_refresh = Column(Integer, nullable=True)
复制代码
我们可以知道quota_usage_get_all_by_project返回给project_usages的结果result是一个字典,它的结果是这种形式:
- result = {'project_id': project_id, 'resource1':hard_limit1, 'resource2':hard_limit2, 'resource3':hard_limit3, ......}
复制代码
即:
- project_quotas ={'project_id': project_id,
-
- 'resource1':{'in_use1':in_use1,'reserved1':reserved1},
-
- 'resource2':{'in_use2':in_use2,'reserved2':reserved2},
-
- ......}
复制代码
再看下面这段代码:
- if project_id == context.project_id:
- quota_class = context.quota_class
- if quota_class:
- class_quotas = db.quota_class_get_all_by_name(context, quota_class)
- else:
- class_quotas = {}
复制代码
这里运调试运行了一下,得到了几个变量的值,如下:
context.quota_class = None
quota_class = None
class_quotas = {}
这说明,没有运行语句:
- <span style="font-family:KaiTi_GB2312;font-size:18px;">class_quotas = db.quota_class_get_all_by_name(context, quota_class)</span>
复制代码
其实这里面的方法quota_class_get_all_by_name和之前分析的两个方法是类似的,只不过之前两个方法都是依据project_id来匹配数据库的,而这里是根据quota_class,而且这里查询的是QuotaClass类,具体为什么会这么设计,目前还没有弄清楚。
接下来看语句:
- for resource in resources.values():
- # Omit default/quota class values
- if not defaults and resource.name not in project_quotas:
- continue
-
- quotas[resource.name] = dict(
- limit=project_quotas.get(resource.name, class_quotas.get(resource.name, resource.default)),
- )
-
- if usages:
- usage = project_usages.get(resource.name, {})
- quotas[resource.name].update(
- in_use=usage.get('in_use', 0),
- reserved=usage.get('reserved', 0),
- )
复制代码
其实这部分代码完成的是从字典project_quotas和project_usages中,为资源instances、ram和cores读取limit(从project_quotas中)以及in_use和reserved(从project_usages中,根据usages的值判断是否获取)等配额的值;
因为这个方法传入的usages参数值是False,所以没有获取in_use和reserved配额值;
所以调试运行了一下,得到如下获取的配额值limit的结果:
- resource.name = instances
- limit:10
- resource.name = ram
- limit:51200
- resource.name = cores
- limit:20
复制代码
方法get_project_quotas的最后,返回从数据库中获取的指定配额信息的值,以字典的形式;
这个方法完成的就是为project_id指定的对象,从数据库中获取给定的资源列表中指定的资源的配额信息数据,以字典的形式返回。
本文,接上一篇内容:
OpenStack建立实例完整过程源码详细分析(6)
下一篇:
OpenStack建立实例完整过程源码详细分析(8)
|