参考:
https://docs.openstack.org/ironic/latest/contributor/states.html
https://docs.openstack.org/ironic/latest/contributor/states.html
enroll-manageable
ironic/api/controllers/v1/node.py class NodeStatesController(rest.RestController): def provision(self, node_ident, target, configdrive=None, clean_steps=None, rescue_password=None): ...... elif target in PROVISION_ACTION_STATES: pecan.request.rpcapi.do_provisioning_action( pecan.request.context, rpc_node.uuid, target, topic) ironic/conductor/manager.py class ConductorManager(base_manager.BaseConductorManager): ...... #RPC方法启动某些供应状态转换。通过状态机启动配置状态更改. def do_provisioning_action(self, context, node_id, action): ...... #如果action等于manager且provision状态为enroll,则执行验证节点 if (action == states.VERBS['manage'] and node.provision_state == states.ENROLL): task.process_event( 'manage', callback=self._spawn_worker, call_args=(self._do_node_verify, task), err_handler=utils.provisioning_error_handler) return #执行电源凭证验证的内部方法 def _do_node_verify(self, task): ...... else: try: power_state = task.driver.power.get_power_state(task) ironic/drivers/modules/ipmitool.py class IPMIPower(base.PowerInterface): ##获取任务节点的当前电源状态 def get_power_state(self, task): driver_info = _parse_driver_info(task.node)#获取ipmitool访问节点所需的参数 return _power_status(driver_info) def _parse_driver_info(node): ......#返回IPMI参数,当节点有了关于driver和相关认证等信息后,就可以通过manage请求,将状态转变为manageable状态 return { 'address': address, 'dest_port': dest_port, 'username': username, 'password': password, 'port': port, 'uuid': node.uuid, 'priv_level': priv_level, 'local_address': local_address, 'transit_channel': transit_channel, 'transit_address': transit_address, 'target_channel': target_channel, 'target_address': target_address, 'protocol_version': protocol_version, 'force_boot_device': force_boot_device, }
manageable-adopt
ironic/conductor/manager.py class ConductorManager(base_manager.BaseConductorManager): def do_provisioning_action(self, context, node_id, action): #如果action等于adopt且provision状态为MANAGEABLE,则执行验证节点 if (action == states.VERBS['adopt'] and node.provision_state in (states.MANAGEABLE, states.ADOPTFAIL)): task.process_event( 'adopt', callback=self._spawn_worker, call_args=(self._do_adoption, task), err_handler=utils.provisioning_error_handler) return #采用执行驱动程序引导验证,然后触发节点接管,这个方法的目标是为节点设置条件在没有执行的情况下,作为一个活动节点来管理部署操作 这种转换允许这些节点直接从可管理节点移动到活动节点 def _do_adoption(self, task): try: iwdi = images.is_whole_disk_image(task.context, task.node.instance_info) driver_internal_info = node.driver_internal_info driver_internal_info['is_whole_disk_image'] = iwdi node.driver_internal_info = driver_internal_info task.driver.boot.validate(task) self._do_takeover(task) LOG.info("Successfully adopted node %(node)s", {'node': node.uuid}) task.process_event('done')
manageable-clean
ironic/conductor/manager.py class ConductorManager(base_manager.BaseConductorManager): def do_provisioning_action(self, context, node_id, action): ...... ##如果action等于provide且provision状态为MANAGEABLE,则执行节点清理操作 if (action == states.VERBS['provide'] and node.provision_state == states.MANAGEABLE): task.process_event( 'provide', callback=self._spawn_worker, call_args=(self._do_node_clean, task), err_handler=utils.provisioning_error_handler) return #内部RPC方法来执行节点的清理 def _do_node_clean(self, task, clean_steps=None): #判断是否自动清理还是自定义清理 clean_type = 'manual' if manual_clean else 'automated' #如果是自动清理关闭则直接不清理变为AVAILABLE状态 if not manual_clean and not CONF.conductor.automated_clean: # Skip cleaning, move to AVAILABLE. node.clean_step = None node.save() task.process_event('done') try: #否则需要有效的电源和网络值来执行清理 task.driver.power.validate(task) task.driver.network.validate(task) try: #允许部署驱动程序再次设置ramdisk执行带内清理 prepare_result = task.driver.deploy.prepare_cleaning(task) if prepare_result == states.CLEANWAIT: target_state = states.MANAGEABLE if manual_clean else None task.process_event('wait', target_state=target_state) return try: # utils.set_node_cleaning_steps(task) except (exception.InvalidParameterValue, exception.NodeCleaningFailure) as e: msg = (_('Cannot clean node %(node)s. Error: %(msg)s') % {'node': node.uuid, 'msg': e}) #判断states的状态返回对应的结果 return utils.cleaning_error_handler(task, msg) steps = node.driver_internal_info.get('clean_steps', []) step_index = 0 if steps else None self._do_next_clean_step(task, step_index)
但谈何容易。