'Shutdown an instance on this host.
:param:context: security context
:param:instance: a nova.objects.Instance object
:param:bdms: the block devices for the instance to be torn
down
:param:requested_networks: the networks on which the instance
has ports
:param:notify: true if a final usage notification should be
emitted
:param:try_deallocate_networks: false if we should avoid
trying to teardown networking'

def _shutdown_instance(self, context, instance, bdms, requested_networks=None, notify=True, try_deallocate_networks=True):

    context = context.elevated()
    LOG.info('Terminating    instance', instance=instance)
    if notify:
        self._notify_about_instance_usage(context, instance, 'shutdown.start')
        compute_utils.notify_about_instance_action(context, instance, self.host, action=fields.NotificationAction.SHUTDOWN, phase=fields.NotificationPhase.START)
    network_info = instance.get_network_info()
    vol_bdms = [bdm for bdm in bdms if bdm.is_volume]
    block_device_info = self._get_instance_block_device_info(context, instance, bdms=bdms)
    timer = timeutils.StopWatch()
    try:
        LOG.debug('Start    destroying    the    instance    on    the    hypervisor.', instance=instance)
        timer.start()
        self.driver.destroy(context, instance, network_info, block_device_info)
        LOG.info('Took    %0.2f    seconds    to    destroy    the    instance    on    the    hypervisor.', timer.elapsed(), instance=instance)
    except exception.InstancePowerOffFailure:
        with excutils.save_and_reraise_exception():
            pass
    except Exception:
        with excutils.save_and_reraise_exception():
            if try_deallocate_networks:
                self._try_deallocate_network(context, instance, requested_networks)
    if try_deallocate_networks:
        self._try_deallocate_network(context, instance, requested_networks)
    timer.restart()
    for bdm in vol_bdms:
        try:
            if bdm.attachment_id:
                self.volume_api.attachment_delete(context, bdm.attachment_id)
            else:
                connector = self.driver.get_volume_connector(instance)
                self.volume_api.terminate_connection(context, bdm.volume_id, connector)
                self.volume_api.detach(context, bdm.volume_id, instance.uuid)
        except exception.VolumeAttachmentNotFound as exc:
            LOG.debug('Ignoring    VolumeAttachmentNotFound:    %s', exc, instance=instance)
        except exception.DiskNotFound as exc:
            LOG.debug('Ignoring    DiskNotFound:    %s', exc, instance=instance)
        except exception.VolumeNotFound as exc:
            LOG.debug('Ignoring    VolumeNotFound:    %s', exc, instance=instance)
        except (cinder_exception.EndpointNotFound, keystone_exception.EndpointNotFound) as exc:
            LOG.warning('Ignoring    EndpointNotFound    for    volume    %(volume_id)s:    %(exc)s', {'exc': exc, 'volume_id': bdm.volume_id}, instance=instance)
        except cinder_exception.ClientException as exc:
            LOG.warning('Ignoring    unknown    cinder    exception    for    volume    %(volume_id)s:    %(exc)s', {'exc': exc, 'volume_id': bdm.volume_id}, instance=instance)
        except Exception as exc:
            LOG.warning('Ignoring    unknown    exception    for    volume    %(volume_id)s:    %(exc)s', {'exc': exc, 'volume_id': bdm.volume_id}, instance=instance)
    if vol_bdms:
        LOG.info('Took    %(time).2f    seconds    to    detach    %(num)s    volumes    for    instance.', {'time': timer.elapsed(), 'num': len(vol_bdms)}, instance=instance)
    if notify:
        self._notify_about_instance_usage(context, instance, 'shutdown.end')
        compute_utils.notify_about_instance_action(context, instance, self.host, action=fields.NotificationAction.SHUTDOWN, phase=fields.NotificationPhase.END)
