'Constructs a work flow to create a volume from snapshot.
:param volume: new volume
:param snapshot: base snapshot
This flow will do the following:
#. Create a snap mount point (SMP) for the snapshot.
#. Attach the snapshot to the SMP created in the first step.
#. Create a temporary lun prepare for migration.
(Skipped if snapcopy=\'true\')
#. Start a migration between the SMP and the temp lun.
(Skipped if snapcopy=\'true\')'

def create_volume_from_snapshot(self, volume, snapshot):

    volume_metadata = utils.get_metadata(volume)
    pool = utils.get_pool_from_host(volume.host)
    specs = common.ExtraSpecs.from_volume(volume)
    tier = specs.tier
    base_lun_name = utils.get_base_lun_name(snapshot.volume)
    rep_update = dict()
    if utils.is_snapcopy_enabled(volume):
        new_lun_id = emc_taskflow.fast_create_volume_from_snapshot(client=self.client, snap_name=snapshot.name, new_snap_name=utils.construct_snap_name(volume), lun_name=volume.name, base_lun_name=base_lun_name, pool_name=pool)
        location = self._build_provider_location(lun_type='smp', lun_id=new_lun_id, base_lun_name=base_lun_name)
        volume_metadata['snapcopy'] = 'True'
        volume_metadata['async_migrate'] = 'False'
    else:
        (async_migrate, provision) = utils.calc_migrate_and_provision(volume)
        new_snap_name = (utils.construct_snap_name(volume) if async_migrate else None)
        new_lun_id = emc_taskflow.create_volume_from_snapshot(client=self.client, src_snap_name=snapshot.name, lun_name=volume.name, lun_size=volume.size, base_lun_name=base_lun_name, pool_name=pool, provision=provision, tier=tier, new_snap_name=new_snap_name)
        location = self._build_provider_location(lun_type='lun', lun_id=new_lun_id, base_lun_name=volume.name)
        volume_metadata['snapcopy'] = 'False'
        volume_metadata['async_migrate'] = six.text_type(async_migrate)
        rep_update = self.setup_lun_replication(volume, new_lun_id)
    model_update = {'provider_location': location, 'metadata': volume_metadata}
    model_update.update(rep_update)
    return model_update
