'Enable bootable flag and properly handle glance metadata.
Caller should provide one and only one of snapshot_id,source_volid
and image_id. If an image_id specified, an image_meta should also be
provided, otherwise will be treated as an empty dictionary.'

def _handle_bootable_volume_glance_meta(self, context, volume, **kwargs):

    log_template = _('Copying    metadata    from    %(src_type)s    %(src_id)s    to    %(vol_id)s.')
    exception_template = _('Failed    updating    volume    %(vol_id)s    metadata    using    the    provided    %(src_type)s    %(src_id)s    metadata')
    src_type = None
    src_id = None
    self._enable_bootable_flag(context, volume)
    try:
        if kwargs.get('snapshot_id'):
            src_type = 'snapshot'
            src_id = kwargs['snapshot_id']
            snapshot_id = src_id
            LOG.debug(log_template, {'src_type': src_type, 'src_id': src_id, 'vol_id': volume.id})
            self.db.volume_glance_metadata_copy_to_volume(context, volume.id, snapshot_id)
        elif kwargs.get('source_volid'):
            src_type = 'source    volume'
            src_id = kwargs['source_volid']
            source_volid = src_id
            LOG.debug(log_template, {'src_type': src_type, 'src_id': src_id, 'vol_id': volume.id})
            self.db.volume_glance_metadata_copy_from_volume_to_volume(context, source_volid, volume.id)
        elif kwargs.get('source_replicaid'):
            src_type = 'source    replica'
            src_id = kwargs['source_replicaid']
            source_replicaid = src_id
            LOG.debug(log_template, {'src_type': src_type, 'src_id': src_id, 'vol_id': volume.id})
            self.db.volume_glance_metadata_copy_from_volume_to_volume(context, source_replicaid, volume.id)
        elif kwargs.get('image_id'):
            src_type = 'image'
            src_id = kwargs['image_id']
            image_id = src_id
            image_meta = kwargs.get('image_meta', {})
            LOG.debug(log_template, {'src_type': src_type, 'src_id': src_id, 'vol_id': volume.id})
            self._capture_volume_image_metadata(context, volume.id, image_id, image_meta)
    except exception.GlanceMetadataNotFound:
        pass
    except exception.CinderException as ex:
        LOG.exception(exception_template, {'src_type': src_type, 'src_id': src_id, 'vol_id': volume.id})
        raise exception.MetadataCopyFailure(reason=ex)
