之前的文章我们分析完了_validate_and_provision_instance方法,回到_create_instance方法,我们来回顾一下这个方法
class API(base.Base):
def _create_instance(self,context,instance_type,
...):
...
#验证客户端传入参数,做虚拟机创建前的准备工作
(instances,request_spec,filter_properties) = self._validate_and_provision_instance(context,
instance_type,
...)
for instance in instances:
#更新InstanceAction表记录
self._record_action_start(context,instance,instance_actions.CREATE)
#向Nova Scheduler服务发送RPC请求,创建虚拟机
self.scheduler_rpcapi.run_instance(context,...)
return (instances,reservation_id)
这个方法包括三个步骤:1.调用_validate_and_provision_instance方法完成虚拟机创建的准备工作。2.调用_record_action_start方法更新数据库中InstanceAction表的记录,将虚拟机状态改为“开始创建”。3.调用scheduler_rpcapi.run_instance方法,向Nova Scheduler服务发送RPC请求,将虚拟机创建请求交给Nova Scheduler服务处理。
这篇文章我们来分析
3. self.scheduler_rpcapi.run_instance(context,...)
class SchedulerAPI(nova.openstack.common.rpc.proxy.RpcProxy):
def run_instance(self, ctxt, request_spec, admin_password,
injected_files, requested_networks, is_first_time,
filter_properties):
return self.cast(ctxt, self.make_msg('run_instance',
request_spec=request_spec, admin_password=admin_password,
injected_files=injected_files,
requested_networks=requested_networks,
is_first_time=is_first_time,
filter_properties=filter_properties))
这个方法向Nova Scheduler服务发送RPC请求,将虚拟机创建请求交给Nova Scheduler处理。该方法位于nova/nova/scheduler/rpcapi.py,它会调用前面”RPC通信“中介绍过的cast方法发送RPC请求。
和其它RPC服务一样,在Nova Scheduler服务中,处理RPC请求的方法都定义在Nova Scheduler服务的manager类中,该类位于nova/nova/scheduler/manager.py。来看一下这个类下的run_instance方法。
class SchedulerManager(manager.Manager):
def run_instance(self, context, request_spec, admin_password,
injected_files, requested_networks, is_first_time,
filter_properties):
instance_uuids = request_spec['instance_uuids']
#更新InstanceAction数据库表
with compute_utils.EventReporter(context, conductor_api.LoadAPI(),
'scheduler', *instance_uuids):
try:
#将虚拟机创建请求交给driver进一步处理
return self.driver.schedule_run_instance(context,
request_spec, admin_password, injected_files,
requested_networks, is_first_time, filter_properties)
...
except Exception as ex:
with excutils.save_and_reraise_exception():
self._set_vm_state_and_notify('run_instance',
{'vm_state': vm_states.ERROR,
'task_state': None},
context, ex, request_spec)
run_instance方法定义了一个with语句块。EventReporter类实现了使用with语句需要实现的__enter__方法和__exit__方法。当程序进入with语句块时,会调用EventReporter对象的__enter__方法,将虚拟机InstanceAction表记录设置为“开始调度”状态。当with语句块执行完成后,会调用EventReporter对象的__exit__方法,将虚拟机InstanceAction表记录设置为“结束调度”的状态。
在with语句块中,调用了driver变量的scheduler_run_instance方法进一步处理虚拟机的创建请求,driver变量可以通过nova.conf配置文件的scheduler_driver配置项配置,默认值为FilterScheduler类。后面我们将进入Nova Scheduler服务的调度算法,我下面用两篇文章来详细的分析一下~~