def _destroy(self, instance):
    try:
        virt_dom = self._lookup_by_name(instance['name'])
    except exception.InstanceNotFound:
        virt_dom = None
    old_domid = (- 1)
    if (virt_dom is not None):
        try:
            old_domid = virt_dom.ID()
            virt_dom.destroy()
            if (CONF.libvirt.virt_type == 'lxc'):
                self._teardown_container(instance)
        except libvirt.libvirtError as e:
            is_okay = False
            errcode = e.get_error_code()
            if (errcode == libvirt.VIR_ERR_OPERATION_INVALID):
                state = LIBVIRT_POWER_STATE[virt_dom.info()[0]]
                if (state == power_state.SHUTDOWN):
                    is_okay = True
            elif (errcode == libvirt.VIR_ERR_OPERATION_TIMEOUT):
                LOG.warn(_LW('Cannot destroy instance, operation time out'), instance=instance)
                reason = _('operation time out')
                raise exception.InstancePowerOffFailure(reason=reason)
            if (not is_okay):
                with excutils.save_and_reraise_exception():
                    LOG.error(_LE('Error from libvirt during destroy. Code=%(errcode)s Error=%(e)s'), {'errcode': errcode, 'e': e}, instance=instance)

    def _wait_for_destroy(expected_domid):
        'Called at an interval until the VM is gone.'
        try:
            dom_info = self.get_info(instance)
            state = dom_info['state']
            new_domid = dom_info['id']
        except exception.InstanceNotFound:
            LOG.warning(_LW('During wait destroy, instance disappeared.'), instance=instance)
            raise loopingcall.LoopingCallDone()
        if (state == power_state.SHUTDOWN):
            LOG.info(_LI('Instance destroyed successfully.'), instance=instance)
            raise loopingcall.LoopingCallDone()
        if (new_domid != expected_domid):
            LOG.info(_LI('Instance may be started again.'), instance=instance)
            kwargs['is_running'] = True
            raise loopingcall.LoopingCallDone()
    kwargs = {'is_running': False}
    timer = loopingcall.FixedIntervalLoopingCall(_wait_for_destroy, old_domid)
    timer.start(interval=0.5).wait()
    if kwargs['is_running']:
        LOG.info(_LI('Going to destroy instance again.'), instance=instance)
        self._destroy(instance)
def _destroy(self, instance):
    try:
        virt_dom = self._lookup_by_name(instance['name'])
    except exception.InstanceNotFound:
        virt_dom = None
    old_domid = (- 1)
    if (virt_dom is not None):
        try:
            old_domid = virt_dom.ID()
            virt_dom.destroy()
            if (CONF.libvirt.virt_type == 'lxc'):
                self._teardown_container(instance)
        except libvirt.libvirtError as e:
            is_okay = False
            errcode = e.get_error_code()
            if (errcode == libvirt.VIR_ERR_OPERATION_INVALID):
                state = LIBVIRT_POWER_STATE[virt_dom.info()[0]]
                if (state == power_state.SHUTDOWN):
                    is_okay = True
            elif (errcode == libvirt.VIR_ERR_OPERATION_TIMEOUT):
                LOG.warn(_LW('Cannot destroy instance, operation time out'), instance=instance)
                reason = _('operation time out')
                raise exception.InstancePowerOffFailure(reason=reason)
            if (not is_okay):
                with excutils.save_and_reraise_exception():
                    LOG.error(_LE('Error from libvirt during destroy. Code=%(errcode)s Error=%(e)s'), {'errcode': errcode, 'e': e}, instance=instance)

    def _wait_for_destroy(expected_domid):
        'Called at an interval until the VM is gone.'
        try:
            dom_info = self.get_info(instance)
            state = dom_info['state']
            new_domid = dom_info['id']
        except exception.InstanceNotFound:
            LOG.warning(_LW('During wait destroy, instance disappeared.'), instance=instance)
            raise loopingcall.LoopingCallDone()
        if (state == power_state.SHUTDOWN):
            LOG.info(_LI('Instance destroyed successfully.'), instance=instance)
            raise loopingcall.LoopingCallDone()
        if (new_domid != expected_domid):
            LOG.info(_LI('Instance may be started again.'), instance=instance)
            kwargs['is_running'] = True
            raise loopingcall.LoopingCallDone()
    kwargs = {'is_running': False}
    timer = loopingcall.FixedIntervalLoopingCall(_wait_for_destroy, old_domid)
    timer.start(interval=0.5).wait()
    if kwargs['is_running']:
        LOG.info(_LI('Going to destroy instance again.'), instance=instance)
        self._destroy(instance)