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. centos 开启http代理tinyproxy

    一.前言 就算有一些公司想到要进行压力测试也是用一些微软,官网出的一些软件,一个ip发起很多访问.等有一天黑客攻击来了发现还是顶不住.华盟君认为知此知彼才是压力测试的关键点,应当模拟黑客手法进行压力测 ...

  2. 2017.9.25 JSP内置对象的概述

    1.JSP的定义: 在JSP中是为了便于数据信息的存储.传递.获取,专门设置了九个内置对象, jsp内置对象是指他们是预先设定的,不需创建,每个对象都有自己的属性和方法. 2.JSP内置对象 对象名称 ...

  3. unity简单例子

    1. https://www.cnblogs.com/chengxuzhimei/p/4992106.html 2.https://www.cnblogs.com/GreenLeaves/p/7086 ...

  4. AVR446_Linear speed control of stepper motor步进电机曲线分析

    1.1.  单片机代码处理 // 定义定时器预分频,定时器实际时钟频率为:72MHz/(STEPMOTOR_TIMx_PRESCALER+1) #define STEPMOTOR_TIM_PRESCA ...

  5. 将matlab处理结果保存为图像文件

    imwrite(testIm, 'Data/Test/testIm.bmp', 'BMP');

  6. 旧文备份:rtlinux安装手册

    前段时间接触了几天RTLinux,折腾了好几天才总算把它安装上,得益于Prof. Chang-Gun Lee的安装建议,觉得该文档可能会对准备尝试安装RTLinux的朋友们有帮助,本人英语很烂,也比较 ...

  7. 初尝微信小程序2-基本框架

    基本框架: .wxml :页面骨架 .wxss :页面样式 .js :页面逻辑    描述一些行为 .json :页面配置 创建一个小程序之后,app.js,app.json,app.wxss是必须的 ...

  8. JS学习笔记--变量类型

    1.js数据类型分为基本数据类型和引用数据类型 基本数据类型:string.number.boolean.null.undefined.symbol(ES6中新增) 引用数据类型:object.arr ...

  9. JavaScript - 库 jQuery

    测试 JavaScript 框架库 - jQuery 引用JQuery 如需测试JavaScript库,您需要在网页中引用它. 为了引用某个库,请使用<script>标签,其src属性设置 ...

  10. scrapy--boss直聘

    Hi,大家好.有段时间没来更新scrapy爬取实例信息了,前2天同事说爬取拉勾,boss直聘等网站信息比较困难.昨天下午开始着手爬取boss直聘内Python爬虫的信息,比想象中的简单很多. 需要解决 ...