您的位置:首页 > 运维架构

OpenStack建立实例完整过程源码详细分析(7)

2013-06-25 19:55 357 查看
感谢朋友支持本博客,欢迎共同探讨交流,由于能力和时间有限,错误之处在所难免,欢迎指正!

如果转载,请保留作者信息。

博客地址: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指定的对象,从数据库中获取给定的资源列表中指定的资源的配额信息数据,以字典的形式返回。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐