感谢朋友支持本博客,欢迎共同探讨交流,由于能力和时间有限,错误之处在所难免,欢迎指正!
如果转载,请保留作者信息。
博客地址:http://blog.csdn.net/gaoxingnengjisuan
邮箱地址:dong.liu@siat.ac.cn
继续看方法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 = {}
这说明,没有运行语句:
class_quotas = db.quota_class_get_all_by_name(context, quota_class)
其实这里面的方法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指定的对象,从数据库中获取给定的资源列表中指定的资源的配额信息数据,以字典的形式返回。