感谢朋友支持本博客,欢迎共同探讨交流,由于能力和时间有限,错误之处在所难免,欢迎指正!
如果转载,请保留作者信息。
博客地址: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解析完成。