def _clone_image_volume(self, ctx, volume, image_meta):
    volume_type_id = volume.get('volume_type_id')
    reserve_opts = {'volumes': 1, 'gigabytes': volume.size}
    QUOTAS.add_volume_type_opts(ctx, reserve_opts, volume_type_id)
    reservations = QUOTAS.reserve(ctx, **reserve_opts)
    try:
        new_vol_values = {k: volume[k] for k in (set(volume.keys()) - self._VOLUME_CLONE_SKIP_PROPERTIES)}
        new_vol_values['volume_type_id'] = volume_type_id
        new_vol_values['attach_status'] = 'detached'
        new_vol_values['status'] = 'creating'
        new_vol_values['project_id'] = ctx.project_id
        new_vol_values['display_name'] = ('image-%s' % image_meta['id'])
        new_vol_values['source_volid'] = volume.id
        LOG.debug('Creating image volume entry: %s.', new_vol_values)
        image_volume = objects.Volume(context=ctx, **new_vol_values)
        image_volume.create()
    except Exception as ex:
        LOG.exception(_LE('Create clone_image_volume: %(volume_id)sfor image %(image_id)s, failed (Exception: %(except)s)'), {'volume_id': volume.id, 'image_id': image_meta['id'], 'except': ex})
        QUOTAS.rollback(ctx, reservations)
        return
    QUOTAS.commit(ctx, reservations, project_id=new_vol_values['project_id'])
    try:
        self.create_volume(ctx, image_volume.id, allow_reschedule=False, volume=image_volume)
        image_volume = self.db.volume_get(ctx, image_volume.id)
        if (image_volume.status != 'available'):
            raise exception.InvalidVolume(_('Volume is not available.'))
        self.db.volume_admin_metadata_update(ctx.elevated(), image_volume.id, {'readonly': 'True'}, False)
        return image_volume
    except exception.CinderException:
        LOG.exception(_LE('Failed to clone volume %(volume_id)s for image %(image_id)s.'), {'volume_id': volume.id, 'image_id': image_meta['id']})
        try:
            self.delete_volume(ctx, image_volume.id)
        except exception.CinderException:
            LOG.exception(_LE('Could not delete the image volume %(id)s.'), {'id': volume.id})
        return
def _clone_image_volume(self, ctx, volume, image_meta):
    volume_type_id = volume.get('volume_type_id')
    reserve_opts = {'volumes': 1, 'gigabytes': volume.size}
    QUOTAS.add_volume_type_opts(ctx, reserve_opts, volume_type_id)
    reservations = QUOTAS.reserve(ctx, **reserve_opts)
    try:
        new_vol_values = {k: volume[k] for k in (set(volume.keys()) - self._VOLUME_CLONE_SKIP_PROPERTIES)}
        new_vol_values['volume_type_id'] = volume_type_id
        new_vol_values['attach_status'] = 'detached'
        new_vol_values['status'] = 'creating'
        new_vol_values['project_id'] = ctx.project_id
        new_vol_values['display_name'] = ('image-%s' % image_meta['id'])
        new_vol_values['source_volid'] = volume.id
        LOG.debug('Creating image volume entry: %s.', new_vol_values)
        image_volume = objects.Volume(context=ctx, **new_vol_values)
        image_volume.create()
    except Exception as ex:
        LOG.exception(_LE('Create clone_image_volume: %(volume_id)sfor image %(image_id)s, failed (Exception: %(except)s)'), {'volume_id': volume.id, 'image_id': image_meta['id'], 'except': ex})
        QUOTAS.rollback(ctx, reservations)
        return
    QUOTAS.commit(ctx, reservations, project_id=new_vol_values['project_id'])
    try:
        self.create_volume(ctx, image_volume.id, allow_reschedule=False, volume=image_volume)
        image_volume = self.db.volume_get(ctx, image_volume.id)
        if (image_volume.status != 'available'):
            raise exception.InvalidVolume(_('Volume is not available.'))
        self.db.volume_admin_metadata_update(ctx.elevated(), image_volume.id, {'readonly': 'True'}, False)
        return image_volume
    except exception.CinderException:
        LOG.exception(_LE('Failed to clone volume %(volume_id)s for image %(image_id)s.'), {'volume_id': volume.id, 'image_id': image_meta['id']})
        try:
            self.delete_volume(ctx, image_volume.id)
        except exception.CinderException:
            LOG.exception(_LE('Could not delete the image volume %(id)s.'), {'id': volume.id})
        return