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

本文深入分析了nova/compute/api.py中的def _create_instance方法中,如何通过_run_instance方法将运行实例的请求消息发送到远程调度器。详细解释了方法的实现逻辑,包括参数验证、数据库操作以及最终发送请求的过程。
摘要由CSDN通过智能技术生成

感谢朋友支持本博客,欢迎共同探讨交流,由于能力和时间有限,错误之处在所难免,欢迎指正!
如果转载,请保留作者信息。
博客地址:http://blog.csdn.net/gaoxingnengjisuan
邮箱地址:dong.liu@siat.ac.cn


在这篇博文中,我们将回到方法/nova/compute/api.py----def _create_instance中,继续对这个方法中发送要运行实例('run_instance')的请求消息到远程节点的功能实现部分进行解析。

首先来看方法_create_instance的实现代码:

def _create_instance(self, context, instance_type,
               image_href, kernel_id, ramdisk_id,
               min_count, max_count,
               display_name, display_description,
               key_name, key_data, security_group,
               availability_zone, user_data, metadata,
               injected_files, admin_password,
               access_ip_v4, access_ip_v6,
               requested_networks, config_drive,
               block_device_mapping, auto_disk_config,
               reservation_id=None, scheduler_hints=None):
        """
        验证所有的输入实例参数;
        为新建实例在数据库中建立新的条目;
        发送要运行实例('run_instance')的请求消息到远程调度器;
        """

        # generate_uid:随机生成一个uid值赋值给reservation_id;
        if reservation_id is None:
            reservation_id = utils.generate_uid('r')
        
        # _validate_and_provision_instance:验证所有的输入参数;
        # 返回要建立实例的各类信息;
        # 这个方法中做了很多事,稍后会好好总结;
        (instances, request_spec, filter_properties) = \
                self._validate_and_provision_instance(context, instance_type,
                        image_href, kernel_id, ramdisk_id, min_count,
                        max_count, display_name, display_description,
                        key_name, key_data, security_group, availability_zone,
                        user_data, metadata, injected_files, access_ip_v4,
                        access_ip_v6, requested_networks, config_drive,
                        block_device_mapping, auto_disk_config,
                        reservation_id, scheduler_hints)

        # 循环获取instances中每个实例action的一些相关信息(包括启动时间等);
        # _record_action_start获取要启动的实例action的一些相关信息(包括启动时间等);
        for instance in instances:
            self._record_action_start(context, instance,instance_actions.CREATE)

        # run_instance:实现了发送要运行实例('run_instance')的请求消息到远程节点;
        # 远程节点会在队列中提取这条消息,然后调用相应资源,实现运行实例的这个请求;
        # 这个方法只是实现了请求信息的发送;
        self.scheduler_rpcapi.run_instance(context,
                request_spec=request_spec,
                admin_password=admin_password, injected_files=injected_files,
                requested_networks=requested_networks, is_first_time=True,
                filter_properties=filter_properties)

        return (instances, reservation_id)
在上篇博文中,我们完成了对方法_validate_and_provision_instance的解析,这里我们继续解析下面的语句:

# 循环获取instances中每个实例action的一些相关信息(包括启动时间等);
# _record_action_start获取要启动的实例action的一些相关信息(包括启动时间等);
for instance in instances:
    self._record_action_start(context, instance,instance_actions.CREATE)
可以看到,这里循环遍历每个要启动的实例,分别调用方法_record_action_start,在这里方法_record_action_start实现了获取每个实例启动的一些信息,并在数据库中建立新的条目,把这些信息写入数据库。具体来看它的实现代码:

def _record_action_start(self, context, instance, action):
        """
        获取要启动的实例action的一些相关信息(包括启动时间等);
        把这些信息写入数据库中;
        """
        
        # pack_action_start:获取实例启动的一些信息,并以字典的形式返回;
        act = compute_utils.pack_action_start(context, instance['uuid'], action)
        # 把获取到的信息写入到数据库中;
        self.db.action_start(context, act)
先来看方法pack_action_start的实现:

def pack_action_start(context, instance_uuid, action_name):
    """
    获取实例启动的一些信息,并以字典的形式返回;
    """
    values = {'action': action_name,
              'instance_uuid': instance_uuid,
              'request_id': context.request_id,
              'user_id': context.user_id,
              'project_id': context.project_id,
              'start_time': context.timestamp}
    return values
可见这个方法以字典的形式返回了实例启动的一些信息;

再来看方法action_start:

def action_start(context, values):
    """
    获取要启动的实例action的一些相关信息,建立新的数据条目,把获取的信息写入新建的数据条目;
    """
    # convert_datetimes:转换时间格式;
    convert_datetimes(values, 'start_time')
    # InstanceAction:一个实例上用于追踪客户端的action的类;
    # 定义这个类的数据结构;
    action_ref = models.InstanceAction()
    # values传进来的是要建立的实例的一些信息,把values中的信息写入新建的数据条目action_ref当中;
    action_ref.update(values)
    action_ref.save()
    return action_ref
进一步来看类InstanceAction的代码:

class InstanceAction(BASE, NovaBase):
    """
    一个实例上用于追踪客户端的action的数据表类;
    """
    
    # 数据表名;
    __tablename__ = 'instance_actions'
    
    # 定义数据表instance_actions的字段id;
    id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
    # 定义数据表instance_actions的字段action;
    action = Column(String(255))
    # 定义数据表instance_actions的字段instance_uuid;
    instance_uuid = Column(String(36),
                           ForeignKey('instances.uuid'),
                           nullable=False)
    # 定义数据表instance_actions的字段request_id;
    request_id = Column(String(255))
    # 定义数据表instance_actions的字段user_id;
    user_id = Column(String(255))
    # 定义数据表instance_actions的字段project_id;
    project_id = Column(String(255))
    # 定义数据表instance_actions的字段start_time;
    start_time = Column(DateTime, default=timeutils.utcnow)
    # 定义数据表instance_actions的字段finish_time;
    finish_time = Column(DateTime)
    # 定义数据表instance_actions的字段message;
    message = Column(String(255))
方法action_start接下来应用语句action_ref.update(values)来实现把values中的信息写入新建的数据条目action_ref当中,再应用语句action_ref.save()来实现更新后信息数据条目action_ref的保存,最后返回数据条目action_ref。

至此方法_record_action_start解析完成。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值