'Creates a volume from a snapshot.'

def create_volume_from_snapshot(self, volume, snapshot, snap_name=None, vvs_name=None):

    LOG.debug('Create    Volume    from    Snapshot\n%(vol_name)s\n%(ss_name)s', {'vol_name': pprint.pformat(volume['display_name']), 'ss_name': pprint.pformat(snapshot['display_name'])})
    model_update = {}
    if (volume['size'] < snapshot['volume_size']):
        err = 'You    cannot    reduce    size    of    the    volume.        It    must    be    greater    than    or    equal    to    the    snapshot.'
        LOG.error(err)
        raise exception.InvalidInput(reason=err)
    try:
        if (not snap_name):
            snap_name = self._get_3par_snap_name(snapshot['id'])
        volume_name = self._get_3par_vol_name(volume['id'])
        extra = {'volume_id': volume['id'], 'snapshot_id': snapshot['id']}
        type_id = volume.get('volume_type_id', None)
        (hpe3par_keys, qos, _volume_type, vvs) = self.get_type_info(type_id)
        if vvs:
            vvs_name = vvs
        name = volume.get('display_name', None)
        if name:
            extra['display_name'] = name
        description = volume.get('display_description', None)
        if description:
            extra['description'] = description
        optional = {'comment': json.dumps(extra), 'readOnly': False}
        self.client.createSnapshot(volume_name, snap_name, optional)
        LOG.debug('Converting    to    base    volume    type:    %s.', volume['id'])
        model_update = self._convert_to_base_volume(volume)
        growth_size = (volume['size'] - snapshot['volume_size'])
        if (growth_size > 0):
            try:
                growth_size_mib = ((growth_size * units.Gi) / units.Mi)
                LOG.debug('Growing    volume:    %(id)s    by    %(size)s    GiB.', {'id': volume['id'], 'size': growth_size})
                self.client.growVolume(volume_name, growth_size_mib)
            except Exception as ex:
                LOG.error('Error    extending    volume    %(id)s.    Ex:    %(ex)s', {'id': volume['id'], 'ex': ex})
                self.client.deleteVolume(volume_name)
                raise exception.CinderException(ex)
        flash_cache = self.get_flash_cache_policy(hpe3par_keys)
        if (qos or vvs_name or (flash_cache is not None)):
            cpg_names = self._get_key_value(hpe3par_keys, 'cpg', self._client_conf['hpe3par_cpg'])
            try:
                self._add_volume_to_volume_set(volume, volume_name, cpg_names[0], vvs_name, qos, flash_cache)
            except Exception as ex:
                self.client.deleteVolume(volume_name)
                LOG.error('Exception:    %s', ex)
                raise exception.CinderException(ex)
        if (self._volume_of_replicated_type(volume) and self._do_volume_replication_setup(volume)):
            model_update['replication_status'] = 'enabled'
            model_update['provider_location'] = self.client.id
    except hpeexceptions.HTTPForbidden as ex:
        LOG.error('Exception:    %s', ex)
        raise exception.NotAuthorized()
    except hpeexceptions.HTTPNotFound as ex:
        LOG.error('Exception:    %s', ex)
        raise exception.NotFound()
    except Exception as ex:
        LOG.error('Exception:    %s', ex)
        raise exception.CinderException(ex)
    return model_update
