openstack ice resize 详解(三)
来源:互联网 发布:微博怎么链接淘宝商品 编辑:程序博客网 时间:2024/05/05 17:50
感谢朋友支持本博客,欢迎共同探讨交流,由于能力和时间有限,错误之处在所难免,欢迎指正!
如有转载,请保留源作者博客信息。
如需交流,欢迎大家博客留言。
由于篇幅较长:上接之前博文:openstack ice resize 详解(二)
三、resize完毕后的确认confirm_resize代码详解分析
1、/nova/api/openstack/compute/servers.py
@wsgi.response(202)
@wsgi.serializers(xml=FullServerTemplate)
@wsgi.deserializers(xml=ActionDeserializer)
@wsgi.action('confirmResize')
def _action_confirm_resize(self, req, id, body):
context = req.environ['nova.context']
instance = self._get_server(context, req, id) #从数据库获取实例信息
try:
self.compute_api.confirm_resize(context, instance)#跟进到2
except exception.MigrationNotFound:
msg = _("Instance has not been resized.")
raise exc.HTTPBadRequest(explanation=msg)
except exception.InstanceIsLocked as e:
raise exc.HTTPConflict(explanation=e.format_message())
except exception.InstanceInvalidState as state_error:
common.raise_http_conflict_for_instance_invalid_state(state_error,
'confirmResize')
return exc.HTTPNoContent()
2、/nova/compute/api.py
@wrap_check_policy
@check_instance_lock
@check_instance_cell
@check_instance_state(vm_state=[vm_states.RESIZED])
def confirm_resize(self, context, instance, migration=None):
"""Confirms a migration/resize and deletes the 'old' instance."""
elevated = context.elevated()
if migration is None:
migration = migration_obj.Migration.get_by_instance_and_status(
elevated, instance.uuid, 'finished')
# reserve quota only for any decrease in resource usage
deltas = self._downsize_quota_delta(context, instance)
quotas = self._reserve_quota_delta(context, deltas)
migration.status = 'confirming' #设置迁移状态为正在confirming
migration.save() #保存
# With cells, the best we can do right now is commit the reservations
# immediately...
if CONF.cells.enable:
quotas.commit(context)
self._record_action_start(context, instance, #通知实例确认resize
instance_actions.CONFIRM_RESIZE)
self.compute_rpcapi.confirm_resize(context, #跟进代码至3
instance,
migration,
migration.source_compute,
quotas.reservations or [])
3、/nova/compute/rpcapi.py
def confirm_resize(self, ctxt, instance, migration, host,
reservations=None, cast=True):
# NOTE(russellb) Havana compat
version = self._get_compat_version('3.0', '2.39')
cctxt = self.client.prepare(server=_compute_host(host, instance),
version=version)
rpc_method = cctxt.cast if cast else cctxt.call
return rpc_method(ctxt, 'confirm_resize', #rpc调用confirm_resize,跟进到4
instance=instance, migration=migration,
reservations=reservations)
4、/nova/compute/manage.py
@wrap_exception()
@wrap_instance_event
@wrap_instance_fault
def confirm_resize(self, context, instance, reservations, migration):
@utils.synchronized(instance['uuid'])
def do_confirm_resize(context, instance, migration_id):
# NOTE(wangpan): Get the migration status from db, if it has been
# confirmed, we do nothing and return here
LOG.debug(_("Going to confirm migration %s") % migration_id,
context=context, instance=instance)
try:
# TODO(russellb) Why are we sending the migration object just
# to turn around and look it up from the db again?
#从migrate表中获取该instance resize记录
migration = migration_obj.Migration.get_by_id(
context.elevated(), migration_id)
except exception.MigrationNotFound:
LOG.error(_("Migration %s is not found during confirmation") %
migration_id, context=context, instance=instance)
return
if migration.status == 'confirmed': #如果已经被确认,则不能再次确认
LOG.info(_("Migration %s is already confirmed") %
migration_id, context=context, instance=instance)
return
#如果迁移状态不是完成或者正在迁移,则数据有异常,直接return退出
elif migration.status not in ('finished', 'confirming'):
LOG.warn(_("Unexpected confirmation status '%(status)s' of "
"migration %(id)s, exit confirmation process") %
{"status": migration.status, "id": migration_id},
context=context, instance=instance)
return
# NOTE(wangpan): Get the instance from db, if it has been
# deleted, we do nothing and return here
expected_attrs = ['metadata', 'system_metadata']
try: #根据uuid获取instance信息
instance = instance_obj.Instance.get_by_uuid(context,
instance.uuid, expected_attrs=expected_attrs)
except exception.InstanceNotFound:
LOG.info(_("Instance is not found during confirmation"),
context=context, instance=instance)
return
#跟进到5
self._confirm_resize(context, instance, reservations=reservations,
migration=migration)
do_confirm_resize(context, instance, migration.id)#调用自身函数
5、/nova/compute/manage.py
def _confirm_resize(self, context, instance, reservations=None,
migration=None):
"""Destroys the source instance."""
#通知实例确认resize开始
self._notify_about_instance_usage(context, instance,
"resize.confirm.start")
with self._error_out_instance_on_exception(context, instance['uuid'],
reservations):
#删除之前保存的迁移信息,并更新instance为新的flavor数据
# NOTE(danms): delete stashed migration information
sys_meta, instance_type = self._cleanup_stored_instance_types(
migration, instance)
sys_meta.pop('old_vm_state', None)
instance.system_metadata = sys_meta
instance.save()
# NOTE(tr3buchet): tear down networks on source host
#清理源主机的网络信息
self.network_api.setup_networks_on_host(context, instance,
migration.source_compute, teardown=True)
#获取当前实例的网络信息
network_info = self._get_instance_nw_info(context, instance)
self.driver.confirm_migration(migration, instance, #跟进到代码6
network_info)
migration.status = 'confirmed' #设置迁移状态为确认完成
migration.save(context.elevated())
rt = self._get_resource_tracker(migration.source_node)
#清理resize过程中claim的migrate信息
rt.drop_resize_claim(instance, prefix='old_')
# NOTE(mriedem): The old_vm_state could be STOPPED but the user
# might have manually powered up the instance to confirm the
# resize/migrate, so we need to check the current power state
# on the instance and set the vm_state appropriately. We default
# to ACTIVE because if the power state is not SHUTDOWN, we
# assume _sync_instance_power_state will clean it up.
p_state = instance.power_state #根据迁移前虚拟机状态设置vm_state
vm_state = None
if p_state == power_state.SHUTDOWN:
vm_state = vm_states.STOPPED
LOG.debug(_("Resized/migrated instance is powered off. "
"Setting vm_state to '%s'."), vm_state,
instance=instance)
else:
vm_state = vm_states.ACTIVE
instance.vm_state = vm_state
instance.task_state = None
instance.save(expected_task_state=[None, task_states.DELETING])
self._notify_about_instance_usage( #通知实例resize确认完成
context, instance, "resize.confirm.end",
network_info=network_info)
self._quota_commit(context, reservations)#更新配额信息
6、/nova/virt/libvirt/driver.py
def confirm_migration(self, migration, instance, network_info):
"""Confirms a resize, destroying the source VM."""
self._cleanup_resize(instance, network_info)#代码跟进到7
7、/nova/virt/libvirt/driver.py
def _cleanup_resize(self, instance, network_info):
target = libvirt_utils.get_instance_path(instance) + "_resize"
if os.path.exists(target):
# Deletion can fail over NFS, so retry the deletion as required.
# Set maximum attempt as 5, most test can remove the directory
# for the second time.
#删除_resize文件夹,为了避免失败,重试5次
utils.execute('rm', '-rf', target, delay_on_retry=True,
attempts=5)
if instance['host'] != CONF.host:
#调用libvirt接口,将该虚拟机undefine
self._undefine_domain(instance)
#网络及防火墙信息、配置清理
self.unplug_vifs(instance, network_info)
self.firewall_driver.unfilter_instance(instance, network_info)
四、resize完毕后的确认revert_resize代码详解分析
1、/nova/api/openstack/compute/servers.py
@wsgi.response(202)
@wsgi.serializers(xml=FullServerTemplate)
@wsgi.deserializers(xml=ActionDeserializer)
@wsgi.action('revertResize')
def _action_revert_resize(self, req, id, body):
context = req.environ['nova.context']
instance = self._get_server(context, req, id) #从数据库获取instance信息
try:
self.compute_api.revert_resize(context, instance) #跟进到2
except exception.MigrationNotFound:
msg = _("Instance has not been resized.")
raise exc.HTTPBadRequest(explanation=msg)
except exception.FlavorNotFound:
msg = _("Flavor used by the instance could not be found.")
raise exc.HTTPBadRequest(explanation=msg)
except exception.InstanceIsLocked as e:
raise exc.HTTPConflict(explanation=e.format_message())
except exception.InstanceInvalidState as state_error:
common.raise_http_conflict_for_instance_invalid_state(state_error,
'revertResize')
return webob.Response(status_int=202)
2、/nova/compute/api.py
@wrap_check_policy
@check_instance_lock
@check_instance_cell
@check_instance_state(vm_state=[vm_states.RESIZED])
def revert_resize(self, context, instance):
"""Reverts a resize, deleting the 'new' instance in the process."""
#回滚resize,并将new实例删除
elevated = context.elevated()
#从数据库migration 表中,获取迁移信息
migration = migration_obj.Migration.get_by_instance_and_status(
elevated, instance.uuid, 'finished') #
# reverse quota reservation for increased resource usage
#回滚配额信息
deltas = self._reverse_upsize_quota_delta(context, migration)
quotas = self._reserve_quota_delta(context, deltas)
#实例状态设置为回滚
instance.task_state = task_states.RESIZE_REVERTING
try:
instance.save(expected_task_state=[None])
except Exception:
with excutils.save_and_reraise_exception():
quotas.rollback(context)
migration.status = 'reverting' #迁移信息设置为回滚
migration.save()
&.bsp; # With cells, the best we can do right now is commit the reservations
# immediate,y...
&n"sp; if CONF.cells.enable:
quotas.commit(context)
self._record_action_start(context, instance, #通知实例回滚resize
instance_actions.REVERT_RESIZE)
self.compute_rpcapi.revert_resize(context, instance, #跟进到3
migration,
migration.dest_compute,
quotas.reservations or [])
3、/nova/compute/rpcapi.py
def revert_resize(self, ctxt, instance, migration, host,
reservations=None):
# NOTE(russellb) Havana compat
version = self._get_compat_version('3.0', '2.39')
cctxt = self.client.prepare(server=_compute_host(host, instance),
version=version)
cctxt.cast(ctxt, 'revert_resize', #rpc调用,跟进到4
instance=instance, migration=migration,
reservations=reservations)
4、/nova/compute/manage.py
@wrap_exception()
@reverts_task_state
@wrap_instance_event
@wrap_instance_fault
def revert_resize(self, context, instance, migration, reservations):
"""Destroys the new instance on the destination machine.
Reverts the model changes, and powers on the old instance on the
source machine.
"""
#删除目的机器的new实例,回滚resize改变、将源主机的实例断电
# NOTE(comstud): A revert_resize is essentially a resize back to
# the old size, so we need to send a usage event here.
self.conductor_api.notify_usage_exists(
context, instance, current_period=True)
with self._error_out_instance_on_exception(context, instance['uuid'],
reservations):
# NOTE(tr3buchet): tear down networks on destination host
#目标主机的网络信息清除
self.network_api.setup_networks_on_host(context, instance,
teardown=True)
#获取原始的实例,迁移信息
instance_p = obj_base.obj_to_primitive(instance)
migration_p = obj_base.obj_to_primitive(migration)
#网络迁移开始
self.conductor_api.network_migrate_instance_start(context,
instance_p,
migration_p)
#获取实例网络及磁盘设备信息
network_info = self._get_instance_nw_info(context, instance)
bdms = (block_device_obj.BlockDeviceMappingList.
get_by_instance_uuid(context, instance.uuid))
block_device_info = self._get_instance_volume_block_device_info(
context, instance, bdms=bdms)
#销毁实例
self.driver.destroy(context, instance, network_info,
block_device_info)
#断开与卷连接
self._terminate_volume_connections(context, instance, bdms)
#设置迁移状态
migration.status = 'reverted'
migration.save(context.elevated())
rt = self._get_resource_tracker(instance.node)
rt.drop_resize_claim(instance)
%r6nbsp; #跟进到5
self.compute_rpcapi.finish_revert_resize(context, instance,
migration, migration.source_compute,
reservations=reservations)
5、/nova/compute/rpcapi.py
def finish_revert_resize(self, ctxt, instance, migration, host,
reservations=None):
# NOTE(russellb) Havana compat
version = self._get_compat_version('3.0', '2.47')
cctxt = self.client.prepare(server=host, version=version)
cctxt.cast(ctxt, 'finish_revert_resize', #rpc调用,跟进到6
instance=instance, migration=migration,
reservations=reservations)
6、/nova/compute/manage.py
@wrap_exception()
@reverts_task_state
@wrap_instance_event
@wrap_instance_fault
def finish_revert_resize(self, context, instance, reservations, migration):
"""Finishes the second half of reverting a resize.
Bring the original source instance state back (active/shutoff) and
revert the resized attributes in the database.
"""
with self._error_out_instance_on_exception(context, instance.uuid,
%2vnbsp; reservations):
network_info = self._get_instance_nw_info(context, instance)
self._notify_about_instance_usage( #通知resize回滚开始
context, instance, "resize.revert.start")
sys_meta, instance_type = self._cleanup_stored_instance_types(
migration, instance, True)
# NOTE(mriedem): delete stashed old_vm_state information; we
# default to ACTIVE for backwards compatibility if old_vm_state
# is not set
old_vm_state = sys_meta.pop('old_vm_state', vm_states.ACTIVE)
#回滚数据库实例信息
instance.system_metadata = sys_meta
instance.memory_mb = instance_type['memory_mb']
instance.vcpus = instance_type['vcpus']
instance.root_gb = instance_type['root_gb']
instance.ephemeral_gb = instance_type['ephemeral_gb']
instance.instance_type_id = instance_type['id']
instance.host = migration['source_compute']
instance.node = migration[gsource_node']
&n"sp; instance.save()
#源主机上创建网络
self.network_api.setup_networks_on_host(context, instance,
migration['source_compute'])
#获取磁盘信息
block_device_info = self._get_instance_volume_block_device_info(
context, instance, refresh_conn_info=True)
power_on = old_vm_state != vm_states.STOPPED
#完成回滚迁移,跟进到7
self.driver.finish_revert_migration(context, instance,
network_info,
block_device_info, power_on)
#设置虚拟机状态信息
instance.launched_at = timeutils.utcnow()
instance.save(expected_task_state=task_states.RESIZE_REVERTING)
instance_p = obj_base.obj_to_primitive(instance)
migration_p = obj_base.obj_to_primitive(migration)
#迁移虚拟机网络
self.conductor_api.network_migrate_instance_finish(context,
instance_p,
migration_p)
# if the original vm state was STOPPED, set it back to STOPPED
LOG.info(_("Updating instance to original state: '%s'") %
old_vm_state)
#设置虚拟机相应运行状态
if power_on:
instance.vm_state = vm_states.ACTIVE
instance.task_state = None
instance.save()
else:
instance.task_state = task_states.POWERING_OFF
instance.save()
self.stop_instance(context, instance=instance)
self._notify_about_instance_usage(#通知回滚完成
context, instance, "resize.revert.end")
self._quota_commit(context, reservations)#配额更新
7、/nova/compute/virt/libvirt/driver.py
def finish_revert_migration(self, context, instance, network_info,
block_device_info=None, power_on=True):
LOG.debug(_("Starting finish_revert_migration"),
instance=instance)
#获取实例路径及resize路径
inst_base = libvirt_utils.get_instance_path(instance)
inst_base_resize = inst_base + "_resize"
# NOTE(danms): if we're recovering from a failed migration,
# make sure we don't have a left-over same-host base directory
# that would conflict. Also, don't fail on the rename if the
# failure happened early.
if os.path.exists(inst_base_resize): #inst_base_resize 路径存在,清理
self._cleanup_failed_migration(inst_base)
utils.execute('mv', inst_base_resize, inst_base)
#获取磁盘信息
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
instance,
block_device_info)
#根据上述信息及配置,生成xml文件,创建虚拟机
xml = self.to_xml(context, instance, network_info, disk_info,
block_device_info=block_device_info)
self._create_domain_and_network(context, xml, instance, network_info,
block_device_info, power_on)
if power_on:
timer = loopingcall.FixedIntervalLoopingCall(
self._wait_for_running,
instance)
timer.start(interval=0.5).wait()
至此回滚resize分析结束。
0 0
- openstack ice resize 详解(三)
- openstack ice resize 详解(一)
- openstack ice resize 详解(二)
- openstack nova resize API 详解
- openstack ice版文档horizon整理(页面resize)
- openstack ice版文档horizon整理(页面resize)
- Openstack中虚拟机的Resize功能详解
- nova-scheduler详解 openstack-ice版
- openstack ice 生成虚拟机磁盘文件详解
- openstack ice版availability zones host aggregates 实战详解
- OpenStack 的resize功能
- Resize Instance 操作详解 - 每天5分钟玩转 OpenStack(41)
- openstack ice自定义调度算法项目详解(horizon、novaclient、api、scheduler、db、自定义数据库)
- openstack ice自定义调度算法项目详解(horizon、novaclient、api、scheduler、db、自定义数据库)
- Resize Instance 操作详解
- OpenCV.Resize详解
- 【OpenStack】Nova中的migrate/resize/live-migration
- OpenStack Nova: Live Migration & Cold Migration & Resize
- js中json字符串与json互转
- 翼支付门户架构之spring security之自定义登陆页面
- 关于设计模式之策略模式
- Inno Setup Preprocessor: Directives
- android四大组件总结
- openstack ice resize 详解(三)
- 【平衡二叉树】SBT学习笔记
- LeetCode[Linked List]: Linked List Cycle II
- eclipse快捷键使用
- spring mvc DispatcherServlet详解之前传---FrameworkServlet
- linux 串口驱动(三)
- 跨平台框架Cordova 命令行简介(CLI)
- golang中time包用法
- Arcgis for Flex中的Query查询在项目中的运用