Tripleo之nova-compute 和Ironic的代码深入分析(二)

声明:

本博客欢迎转载,但请保留原作者信息!

作者:姜飞

团队:华为杭州OpenStack团队


前面讲了nova-compute启动的时候将ironic的node信息资源上报到compute-nodes,接下来讲解下Juno版本在对物理机进行部署的流程。

这里直接跳到nova-scheduler发rpc到nova-compute,nova-compute进行spawn操作说起,nova-compute的spawn操作,直接就是在compute-driver类的spawn方法:

    def spawn(self, context, instance, image_meta, injected_files,
              admin_password, network_info=None, block_device_info=None):
        
        # The compute manager is meant to know the node uuid, so missing uuid
        # is a significant issue. It may mean we've been passed the wrong data.
        node_uuid = instance.get('node')
        if not node_uuid:
            raise ironic.exc.BadRequest(
                _("Ironic node uuid not supplied to "
                  "driver for instance %s.") % instance['uuid'])
	#调用ironic的node.get方法查询node的详细信息,获取该物理机的套餐信息。
        icli = client_wrapper.IronicClientWrapper()
        node = icli.call("node.get", node_uuid)
        flavor = objects.Flavor.get_by_id(context,
                                          instance['instance_type_id'])
		
        #会将套餐里面的baremetal:deploy_kernel_id和baremetal:deploy_ramdisk_id信息更新到driver_info,将image_source、root_gb、swap_mb、ephemeral_gb、ephem        #eral_format、preserve_ephemeral信息更新到instance_info中,然后将driver_info和instance_info更新到ironic的node节点对应的属性上。
        self._add_driver_fields(node, instance, image_meta, flavor)

        # NOTE(Shrews): The default ephemeral device needs to be set for
        # services (like cloud-init) that depend on it being returned by the
        # metadata server. Addresses bug https://launchpad.net/bugs/1324286.
        if flavor['ephemeral_gb']:
            instance.default_ephemeral_device = '/dev/sda1'
            instance.save()	

        # validate we are ready to do the deploy
        #调用ironic的接口查看该节点是否存在,查看deploy和power这2个状态是否为True,只有这2个状态都为False的时候才允许部署。
        validate_chk = icli.call("node.validate", node_uuid)
        if not validate_chk.deploy or not validate_chk.power:
            # something is wrong. undo what we have done
            self._cleanup_deploy(context, node, instance, network_info)
            raise exception.ValidationError(_(
                "Ironic node: %(id)s failed to validate."
                " (deploy: %(deploy)s, power: %(power)s)")
                % {'id': node.uuid,
                   'deploy': validate_chk.deploy,
                   'power': validate_chk.power})

        # prepare for the deploy
        try:
             #先将ironic port-list出来的port不需要的port从extra的'vif_port_id'属性中删#除,这里要确保network-info的port信息要和ironic port-list的port信息              #一致,network_info的port数一定是小于等于ironic的port数,然后将port的uuid增加到该节点的node的port信息中extra的'vif_port_id'中。
            self._plug_vifs(node, instance, network_info)
	    #当前ironic用的是nova.virt.firewall.NoopFirewallDriver,所以关于这个可以不看
            self._start_firewall(instance, network_info)
        except Exception:
            with excutils.save_and_reraise_exception():
                LOG.error(_LE("Error preparing deploy for instance "
                              "%(instance)s on baremetal node %(node)s."),
                          {'instance': instance['uuid'],
                           'node': node_uuid})
                self._cleanup_deploy(context, node, instance, network_info)

        # trigger the node deploy
	#设置部署状态为ACTIVE,然后就在这里等ironic  node的provision_state为ACTIVE
        try:
            icli.call("node.set_provision_state", node_uuid,
                      ironic_states.ACTIVE)
        except Exception as e:
            with excutils.save_and_reraise_exception():
                msg = (_LE("Failed to request Ironic to provision instance "
                           "%(inst)s: %(reason)s"),
                           {'inst': instance['uuid'],
                            'reason': six.text_type(e)})
                LOG.error(msg)
                self._cleanup_deploy(context, node, instance, network_info)

        timer = loopingcall.FixedIntervalLoopingCall(self._wait_for_active,
                                                     icli, instance)
        try:
            timer.start(interval=CONF.ironic.api_retry_interval).wait()
        except Exception:
            with excutils.save_and_reraise_exception():
                LOG.error(_LE("Error deploying instance %(instance)s on "
                              "baremetal node %(node)s."),
                             {'instance': instance['uuid'],
                              'node': node_uuid})
                self.destroy(context, instance, network_info)


nova-compute的spawn的步骤就是设置ironic的provision_state为ACTIVE,然后等待ironic的node provision_state为ACTIVE就结束了。

你可能感兴趣的:(openstack,安装部署,tripleO)