'Delete a snapshot.
If volume status is \'available\', delete snapshot here in Cinder
using qemu-img.
If volume status is \'in-use\', calculate what qcow2 files need to
merge, and call to Nova to perform this operation.
:raises: InvalidVolume if status not acceptable
:raises: RemoteFSException(msg) if operation fails
:returns: None'

def _delete_snapshot(self, snapshot):

    LOG.debug('Deleting    %(type)s    snapshot    %(snap)s    of    volume    %(vol)s', {'snap': snapshot.id, 'vol': snapshot.volume.id, 'type': ('online' if (snapshot.volume.status == 'in-use') else 'offline')})
    volume_status = snapshot.volume.status
    acceptable_states = ['available', 'in-use', 'backing-up', 'deleting', 'downloading']
    self._validate_state(volume_status, acceptable_states)
    vol_path = self._local_volume_dir(snapshot.volume)
    self._ensure_share_writable(vol_path)
    info_path = self._local_path_volume_info(snapshot.volume)
    snap_info = self._read_info_file(info_path, empty_if_missing=True)
    if (snapshot.id not in snap_info):
        LOG.info('Snapshot    record    for    %s    is    not    present,    allowing    snapshot_delete    to    proceed.', snapshot.id)
        return
    snapshot_file = snap_info[snapshot.id]
    LOG.debug('snapshot_file    for    this    snap    is:    %s', snapshot_file)
    snapshot_path = os.path.join(self._local_volume_dir(snapshot.volume), snapshot_file)
    snapshot_path_img_info = self._qemu_img_info(snapshot_path, snapshot.volume.name)
    base_file = snapshot_path_img_info.backing_file
    if (base_file is None):
        LOG.warning('No    backing    file    found    for    %s,    allowing    snapshot    to    be    deleted.', snapshot_path)
        return self._delete_stale_snapshot(snapshot)
    base_path = os.path.join(vol_path, base_file)
    base_file_img_info = self._qemu_img_info(base_path, snapshot.volume.name)
    active_file = self.get_active_image_from_info(snapshot.volume)
    if (volume_status == 'in-use'):
        context = snapshot._context
        new_base_file = base_file_img_info.backing_file
        base_id = None
        for (key, value) in snap_info.items():
            if (utils.paths_normcase_equal(value, base_file) and (key != 'active')):
                base_id = key
                break
        if (base_id is None):
            LOG.debug('No    %(base_id)s    found    for    %(file)s', {'base_id': 'base_id', 'file': snapshot_file})
        online_delete_info = {'active_file': active_file, 'snapshot_file': snapshot_file, 'base_file': base_file, 'base_id': base_id, 'new_base_file': new_base_file}
        return self._delete_snapshot_online(context, snapshot, online_delete_info)
    if utils.paths_normcase_equal(snapshot_file, active_file):
        self._img_commit(snapshot_path)
        snap_info['active'] = base_file
    else:
        higher_file = self._get_higher_image_path(snapshot)
        if (higher_file is None):
            msg = (_('No    file    found    with    %s    as    backing    file.') % snapshot_file)
            raise exception.RemoteFSException(msg)
        higher_id = next((i for i in snap_info if (utils.paths_normcase_equal(snap_info[i], higher_file) and (i != 'active'))), None)
        if (higher_id is None):
            msg = (_('No    snap    found    with    %s    as    backing    file.') % higher_file)
            raise exception.RemoteFSException(msg)
        self._img_commit(snapshot_path)
        higher_file_path = os.path.join(vol_path, higher_file)
        base_file_fmt = base_file_img_info.file_format
        self._rebase_img(higher_file_path, base_file, base_file_fmt)
    del snap_info[snapshot.id]
    self._write_info_file(info_path, snap_info)
