nova resize时候的确认和取消操作

来源:互联网 发布:序列号生成算法 编辑:程序博客网 时间:2024/05/22 06:53
在执行resize的时候最后会让用户确实是否真的要resize还是要revert当前resize的操作。这种确认操作在在nova api中都有对应的操作先看如果要取消resize的操作。其入口代码在nova/api/openstack/compute/servers.py,方法是_action_revert_resize,如下 @wsgi.response(202)    @extensions.expected_errors((400, 404, 409))    @wsgi.action('revertResize')    def _action_revert_resize(self, req, id, body):        context = req.environ['nova.context']        context.can(server_policies.SERVERS % 'revert_resize')        instance = self._get_server(context, req, id)        try:            self.compute_api.revert_resize(context, instance)        except exception.InstanceUnknownCell as e:            raise exc.HTTPNotFound(explanation=e.format_message()) 这里主要调用compute_api.revert_resize这里直接调用到compute/api.py 中的    def revert_resize(self, context, instance):        """Reverts a resize, deleting the 'new' instance in the process."""          self.compute_rpcapi.revert_resize(context, instance,                                          migration,                                          migration.dest_compute,                                          quotas.reservations or [])根据rpc调用原则,首先调用compute/rpcapi.py中的revert_resize,其又调用compute/manager.py 中的revert_resize。我们这里直接看compute/manager.py 中的revert_resize    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.        """            self.compute_rpcapi.finish_revert_resize(context, instance,                    migration, migration.source_compute,                    quotas.reservations)和上面的类似,首先调用compute/rpcapi.py中的finish_revert_resize,这里有转到compute/manager.py的 finish_revert_resize。这里直接看compute/manager.py的 finish_revert_resize    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.        """           self.driver.finish_revert_migration(context, instance,                                       network_info,                                       block_device_info, power_on)可以看到最终还是调用到driver的finish_revert_migrationnova/virt/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)        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):            self._cleanup_failed_migration(inst_base)            utils.execute('mv', inst_base_resize, inst_base)        root_disk = self.image_backend.image(instance, 'disk')//如果instance 有disk的话,最终要remove snapshot        if root_disk.exists():            try:                root_disk.rollback_to_snap(libvirt_utils.RESIZE_SNAPSHOT_NAME)            except exception.SnapshotNotFound:                LOG.warning(_LW("Failed to rollback snapshot (%s)"),                            libvirt_utils.RESIZE_SNAPSHOT_NAME)            finally:                root_disk.remove_snap(libvirt_utils.RESIZE_SNAPSHOT_NAME,                                      ignore_errors=True)        disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,                                            instance,                                            instance.image_meta,                                            block_device_info)        xml = self._get_guest_xml(context, instance, network_info, disk_info,                                  instance.image_meta,                                  block_device_info=block_device_info)        self._create_domain_and_network(context, xml, instance, network_info,                                        disk_info,                                        block_device_info=block_device_info,                                        power_on=power_on,                                        vifs_already_plugged=True)//最后通过FixedIntervalLoopingCall 来设置一个0.5s后定时运行的timer,其回调函数是_wait_for_running        if power_on:            timer = loopingcall.FixedIntervalLoopingCall(                                                    self._wait_for_running,                                                    instance)            timer.start(interval=0.5).wait()        LOG.debug("finish_revert_migration finished successfully.",                  instance=instance)    def _wait_for_running(self, instance):        state = self.get_info(instance).state        if state == power_state.RUNNING:            LOG.info(_LI("Instance running successfully."), instance=instance)            raise loopingcall.LoopingCallDone()在timer的回调函数中会检查instance的power的状态,如果instance已经running的话,就通过raise一个timer异常来结束这个timer 与_action_revert_resize对应的就是确认本次resize操作,其入口函数nova/api/openstack/compute/servers.py,方法是_action_confirm_resize,如下     @wsgi.response(204)    @extensions.expected_errors((400, 404, 409))    @wsgi.action('confirmResize')    def _action_confirm_resize(self, req, id, body):        context = req.environ['nova.context']        context.can(server_policies.SERVERS % 'confirm_resize')        instance = self._get_server(context, req, id)        try:            self.compute_api.confirm_resize(context, instance)        except exception.InstanceUnknownCell as e:            raise exc.HTTPNotFound(explanation=e.format_message())    调用的flow和刚才类似,最终调用到driver的confirm_migration    def _confirm_resize(self, context, instance, quotas,                        migration=None):            self.driver.confirm_migration(migration, instance,                                          network_info)nova/virt/driver.py 中的    def confirm_migration(self, migration, instance, network_info):        """Confirms a resize, destroying the source VM."""        self._cleanup_resize(instance, network_info)可见继续调用nova/virt/driver.py 的_cleanup_resize   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.            utils.execute('rm', '-rf', target, delay_on_retry=True,                          attempts=5)        root_disk = self.image_backend.image(instance, 'disk')     //如果这个instance有disk的话,就删掉这个disk的snapshot,因为size 已经变了,原来的snapshot 肯定不能用了        if root_disk.exists():            root_disk.remove_snap(libvirt_utils.RESIZE_SNAPSHOT_NAME,                                  ignore_errors=True)        if instance.host != CONF.host:            self._undefine_domain(instance)            self.unplug_vifs(instance, network_info)            self.unfilter_instance(instance, network_info)

原创粉丝点击