'Creates the group from source.
The source can be a group snapshot or a source group.'

def create_group_from_src(self, context, group, group_snapshot=None, source_group=None):

    source_name = None
    snapshots = None
    source_vols = None
    try:
        volumes = objects.VolumeList.get_all_by_generic_group(context, group.id)
        if group_snapshot:
            try:
                group_snapshot = objects.GroupSnapshot.get_by_id(context, group_snapshot.id)
            except exception.GroupSnapshotNotFound:
                LOG.error('Create    group    from    snapshot-%(snap)s    failed:    SnapshotNotFound.', {'snap': group_snapshot.id}, resource={'type': 'group', 'id': group.id})
                raise
            source_name = (_('snapshot-%s') % group_snapshot.id)
            snapshots = objects.SnapshotList.get_all_for_group_snapshot(context, group_snapshot.id)
            for snap in snapshots:
                if (snap.status not in VALID_CREATE_GROUP_SRC_SNAP_STATUS):
                    msg = (_('Cannot    create    group    %(group)s    because    snapshot    %(snap)s    is    not    in    a    valid    state.    Valid    states    are:    %(valid)s.') % {'group': group.id, 'snap': snap['id'], 'valid': VALID_CREATE_GROUP_SRC_SNAP_STATUS})
                    raise exception.InvalidGroup(reason=msg)
        if source_group:
            try:
                source_group = objects.Group.get_by_id(context, source_group.id)
            except exception.GroupNotFound:
                LOG.error('Create    group    from    source    group-%(group)s    failed:    GroupNotFound.', {'group': source_group.id}, resource={'type': 'group', 'id': group.id})
                raise
            source_name = (_('group-%s') % source_group.id)
            source_vols = objects.VolumeList.get_all_by_generic_group(context, source_group.id)
            for source_vol in source_vols:
                if (source_vol.status not in VALID_CREATE_GROUP_SRC_GROUP_STATUS):
                    msg = (_('Cannot    create    group    %(group)s    because    source    volume    %(source_vol)s    is    not    in    a    valid    state.    Valid    states    are:    %(valid)s.') % {'group': group.id, 'source_vol': source_vol.id, 'valid': VALID_CREATE_GROUP_SRC_GROUP_STATUS})
                    raise exception.InvalidGroup(reason=msg)
        sorted_snapshots = None
        if (group_snapshot and snapshots):
            sorted_snapshots = self._sort_snapshots(volumes, snapshots)
        sorted_source_vols = None
        if (source_group and source_vols):
            sorted_source_vols = self._sort_source_vols(volumes, source_vols)
        self._notify_about_group_usage(context, group, 'create.start')
        utils.require_driver_initialized(self.driver)
        try:
            (model_update, volumes_model_update) = self.driver.create_group_from_src(context, group, volumes, group_snapshot, sorted_snapshots, source_group, sorted_source_vols)
        except NotImplementedError:
            cgsnap_type = group_types.get_default_cgsnapshot_type()
            if (group.group_type_id != cgsnap_type['id']):
                (model_update, volumes_model_update) = self._create_group_from_src_generic(context, group, volumes, group_snapshot, sorted_snapshots, source_group, sorted_source_vols)
            else:
                (cg, volumes) = self._convert_group_to_cg(group, volumes)
                (cgsnapshot, sorted_snapshots) = self._convert_group_snapshot_to_cgsnapshot(group_snapshot, sorted_snapshots, context)
                (source_cg, sorted_source_vols) = self._convert_group_to_cg(source_group, sorted_source_vols)
                (model_update, volumes_model_update) = self.driver.create_consistencygroup_from_src(context, cg, volumes, cgsnapshot, sorted_snapshots, source_cg, sorted_source_vols)
                self._remove_cgsnapshot_id_from_snapshots(sorted_snapshots)
                self._remove_consistencygroup_id_from_volumes(volumes)
                self._remove_consistencygroup_id_from_volumes(sorted_source_vols)
        if volumes_model_update:
            for update in volumes_model_update:
                self.db.volume_update(context, update['id'], update)
        if model_update:
            group.update(model_update)
            group.save()
    except Exception:
        with excutils.save_and_reraise_exception():
            group.status = fields.GroupStatus.ERROR
            group.save()
            LOG.error('Create    group    from    source    %(source)s    failed.', {'source': source_name}, resource={'type': 'group', 'id': group.id})
            self._remove_consistencygroup_id_from_volumes(volumes)
            for vol in volumes:
                vol.status = 'error'
                vol.save()
    now = timeutils.utcnow()
    status = 'available'
    for vol in volumes:
        update = {'status': status, 'created_at': now}
        self._update_volume_from_src(context, vol, update, group=group)
        self._update_allocated_capacity(vol)
    group.status = status
    group.created_at = now
    group.save()
    self._notify_about_group_usage(context, group, 'create.end')
    LOG.info('Create    group    from    source-%(source)s    completed    successfully.', {'source': source_name}, resource={'type': 'group', 'id': group.id})
    return group
