1、用户调用Nova的rescue函数

nova/virt/ironic/driver.py
class IronicDriver(virt_driver.ComputeDriver):
......
......
#导入ironicclient模块
def __init__(self, virtapi, read_only=False):
super(IronicDriver, self).__init__(virtapi)
global ironic
if ironic is None:
ironic = importutils.import_module('ironicclient')
......
self.ironicclient = client_wrapper.IronicClientWrapper() def spawn(self, context, instance, image_meta, injected_files,
admin_password, allocations, network_info=None,
block_device_info=None):
......
#调用ironicclient.call方法,触发节点部署
try:
self.ironicclient.call("node.set_provision_state", node_uuid,
ironic_states.ACTIVE,
configdrive=configdrive_value)
......
try:
##Virt驱动程序在等待provision_state更改时循环,并根据需要更新Nova状态
timer.start(interval=CONF.ironic.api_retry_interval).wait()
LOG.info('Successfully provisioned Ironic node %s',
node.uuid, instance=instance)
ironic/api/controllers/v1/node.py
#ronic API接收set_provision_state调用,并执行do_node_rescue RPC调用
class NodeStatesController(rest.RestController):
def provision(self, node_ident, target, configdrive=None,
clean_steps=None, rescue_password=None):
.....
elif (target == ir_states.VERBS['rescue']):
if not (rescue_password and rescue_password.strip()):
msg = (_('A non-empty "rescue_password" is required when '
'setting target provision state to %s') %
ir_states.VERBS['rescue'])
raise wsme.exc.ClientSideError(
msg, status_code=http_client.BAD_REQUEST)
pecan.request.rpcapi.do_node_rescue(
pecan.request.context, rpc_node.uuid, rescue_password, topic)
ironic/conductor/manager.py
class ConductorManager(base_manager.BaseConductorManager):
......
def do_node_rescue(self, context, node_id, rescue_password):
......
#保存节点的救援密码
instance_info = node.instance_info
instance_info['rescue_password'] = rescue_password
node.instance_info = instance_info
node.save()#Ironic conductor在instance_info中设置了救援密码并将通知给相应的驱动 try:
task.driver.power.validate(task)
task.driver.rescue.validate(task)
task.driver.network.validate(task) try:
task.process_event(
'rescue',
callback=self._spawn_worker,
call_args=(self._do_node_rescue, task),#内部RPC方法来救援现有的节点部署
err_handler=utils.spawn_rescue_error_handler) def _do_node_rescue(self, task):
......
try:
next_state = task.driver.rescue.rescue(task) if next_state == states.RESCUEWAIT:
task.process_event('wait')
elif next_state == states.RESCUE:
task.process_event('done')
ironic/drivers/modules/agent.py
class AgentRescue(base.RescueInterface):
.....
#在节点上启动一个救援ramdisk
def rescue(self, task):
#重置电源状态
manager_utils.node_power_action(task, states.POWER_OFF)
#清理实例
task.driver.boot.clean_up_instance(task)
#取消节点的租户网络
task.driver.network.unconfigure_tenant_networks(task)
#为每个端口创建neutron端口以启动救援虚拟磁盘
task.driver.network.add_rescuing_network(task)
if CONF.agent.manage_agent_boot:
ramdisk_opts = deploy_utils.build_agent_options(task.node)
#使用PXE准备Ironic ramdisk的引导
task.driver.boot.prepare_ramdisk(task, ramdisk_opts)
#重置电源状态为POWER_ON
manager_utils.node_power_action(task, states.POWER_ON) return states.RESCUEWAIT
ironic/drivers/modules/pxe.py
class PXEBoot(base.BootInterface):
......
def prepare_ramdisk(self, task, ramdisk_params):
node = task.node
mode = deploy_utils.rescue_or_deploy_mode(node) if CONF.pxe.ipxe_enabled:
#将iPXE引导脚本呈现到HTTP根目录
pxe_utils.create_ipxe_boot_script()
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)#检索DHCP PXE启动选项
provider = dhcp_factory.DHCPFactory()
provider.update_dhcp(task, dhcp_opts)#发送或更新此节点的DHCP BOOT选项
pxe_info = _get_image_info(node, mode=mode)#为救援镜像生成TFTP文件的路径 manager_utils.node_set_boot_device(task, boot_devices.PXE,
persistent=persistent) if CONF.pxe.ipxe_enabled and CONF.pxe.ipxe_use_swift:
kernel_label = '%s_kernel' % mode
ramdisk_label = '%s_ramdisk' % mode
pxe_info.pop(kernel_label, None)
pxe_info.pop(ramdisk_label, None) if pxe_info:
_cache_ramdisk_kernel(task.context, node, pxe_info)

ipa和ironic-conductor交互,Agent ramdisk启动后,回调/v1/lookup获取节点信息, 发送心跳

ironic/drivers/modules/agent_base_vendor.py
class HeartbeatMixin(object):
......
def heartbeat(self, task, callback_url, agent_version):
......
try:
.....
elif (node.provision_state == states.RESCUEWAIT):
msg = _('Node failed to perform rescue operation.')
self._finalize_rescue(task) def _finalize_rescue(self, task):
node = task.node
try:
result = self._client.finalize_rescue(node)
ironic/drivers/modules/agent_client.py
class AgentClient(object):
#指示虚拟磁盘完成救援模式的进入
def finalize_rescue(self, node):
#根据config drive和rescue password调用finalize_rescue(RESCUEWAIT -> RESCUING),向ipa传入rescue_password
rescue_pass = node.instance_info.get('rescue_password')
params = {'rescue_password': rescue_pass}
return self._command(node=node,
method='rescue.finalize_rescue',
params=params) def _command(self, node, method, params, wait=False):
#向ipa发送命令
url = self._get_command_url(node)
body = self._get_command_body(method, params)
request_params = {
'wait': str(wait).lower()
try:
response = self.session.post(url, params=request_params, data=body)
ironic_python_agent/extensions/rescue.py
PASSWORD_FILE = '/etc/ipa-rescue-config/ipa-rescue-password'
class RescueExtension(base.BaseAgentExtension):
def finalize_rescue(self, rescue_password=""):
self.write_rescue_password(rescue_password)
self.agent.serve_api = False #关闭api接口
return def write_rescue_password(self, rescue_password=""):
LOG.debug('Writing hashed rescue password to %s', PASSWORD_FILE)
salt = self.make_salt()
hashed_password = crypt.crypt(rescue_password, salt)
try:
with open(PASSWORD_FILE, 'w') as f:
f.write(hashed_password)#把救援密码写入到/etc/ipa-rescue-config/ipa-rescue-password
ironic/drivers/modules/agent_base_vendor.py
class HeartbeatMixin(object):
#调用ramdisk来准备救援模式并验证结果
def _finalize_rescue(self, task):
node = task.node
try:
result = self._client.finalize_rescue(node)
task.process_event('resume')#恢复node的状态
task.driver.rescue.clean_up(task)#清理此节点的部署环境
task.driver.network.configure_tenant_networks(task)#将网络调整到之前的租户网络
task.process_event('done')#返回task状态为done

ironic baremetal rescue process的更多相关文章

  1. ironic baremetal node rescue/unrescue mode

    环境ironic-api ironic-conductor,ironicclient均升级为Queens版本 官网说明API版本为1.38才支持rescue/unrescue,所以修改下openrc文 ...

  2. Ironic 的 Rescue 救援模式实现流程

    目录 文章目录 目录 救援模式 实现 UML 图 救援模式 以往只有虚拟机支持救援模式,裸机是不支持的.直到 Queen 版本 Ironic 实现了这个功能.救援模式下,用户可以完成修复.Troubl ...

  3. ironic baremetal node status

    参考: https://docs.openstack.org/ironic/latest/contributor/states.html https://docs.openstack.org/iron ...

  4. ironic rescue standard rescue and unrescue process

    翻译官网救援/取消救援标准流程 1.用户在节点上调用Nova rescue 2.Nova ComputeManager调用virt驱动程序的rescue()方法,传入rescue_password作为 ...

  5. packstack安装ironic

    KVM Centos7.3虚机 安装openstack Pike版本, 其它版本安装方法类似. packstack目前对NetworkManager 还不支持,我们修改下配置: systemctl d ...

  6. 手动集成 Ironic 裸金属管理服务(Rocky)

    目录 文章目录 目录 前文列表 横向扩展裸金属管理服务节点 配置基础设施 安装 Ironic(BareMetal) 安装 Nova Compute(BareMetal) 配置 Neutron 提供 P ...

  7. Data Center Manager Leveraging OpenStack

    这是去年的一个基于OpenStack的数据中心管理软件的想法. Abstract OpenStack facilates users to provision and manage cloud ser ...

  8. packstack-ironic

    安装openstack Pike版本, 其它版本安装方法类似. centos7.6 packstack目前对NetworkManager 还不支持,我们修改下配置: systemctl disable ...

  9. Ironic , Openstack Baremetal Hypervisor

    Ironic , Openstack Baremetal Hypervisor,首发于UnitedStack Inc.. 转自: http://ju.outofmemory.cn/entry/4876 ...

随机推荐

  1. 2017.11.7 JavaWeb------Servlet过滤器

    JavaWeb------Servlet过滤器 (1)过滤器是web服务器上的组件,它们对客户和资源之间的请求和响应进行过滤.Servlet 过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响 ...

  2. 第39章 ETH—Lwip以太网通信—零死角玩转STM32-F429系列

    第39章     ETH—Lwip以太网通信 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/ ...

  3. SpringMVC3中返回json字符串时500 Internal Server Error的处理方案

    搭建 Spring3+MyBatis+Rest+BootStrap+JBPM项目环境后,测试发现了一个操蛋的问题.使用Spring MVC的自动类型转换为JSON时,后台数据List/Map获取完全正 ...

  4. WebAppBuilder独立于Portal之arcgis for js应用框架研究

    1.前言 最近在做项目过程中,用到了WAB,先做一下总结和归类.Webappbuilder(简称WAB)是运行在portal或者online的一款webGIS开发应用程序,其代码开源并且具有优秀的设计 ...

  5. Mantle--国外程序员最常用的iOS模型&字典转换框架

    Mantle简介 Mantle是iOS和Mac平台下基于Objective-C编写的一个简单高效的模型层框架. Mantle能做什么 Mantle可以轻松把JSON数据.字典(Dictionary)和 ...

  6. EAIntroView–高度可定制的iOS应用欢迎页通用解决方案

    简介 高度可定制的应用欢迎页通用解决方案,可高度定制,不要仅限于现有的demo. 项目主页: EAIntroView 最新示例: 点击下载 入门 安装 安装后,引入” EAIntroView.h”并设 ...

  7. BootStrap中常用样式类

    网格选项 row:行 col--:列(第一个可以为xs[超小]/sm[小型]/md[中型]/lg[大型]:第二个必须为12以内的[列数]) col--offset-:列偏移(第一个同上,第二个范围为1 ...

  8. 【例题收藏】◇例题·I◇ Snuke's Subway Trip

    ◇例题·I◇ Snuke's Subway Trip 题目来源:Atcoder Regular 061 E题(beta版) +传送门+ 一.解析 (1)最短路实现 由于在同一家公司的铁路上移动是不花费 ...

  9. centos7 多网卡修改默认路由

    最近在virtualbox里搭了一个centos7的虚拟机,但是网络这一块总是有问题. 单网卡下的问题: 1.当我配置连接方式为NAT网络地址转换的时候,虚拟机可以访问外网.但是在网络地址转换的情况下 ...

  10. 判断移动端和pc端最简单的方法

    <!DOCTYPE html><html><head> <title></title> <script type="text ...