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就結束了。

發佈了51 篇原創文章 · 獲贊 48 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章