#!/bin/bash
#
# cvmfsexec-osg-wrapper
#
# Runs the specified command with CVMFS repos mounted (using mountrepo)
# in a temp directory; the directory will be in the command's environment
# as $CVMFS_BASE.
# Expects a cvmfsexec tarball at ~/cvmfsexec-osg.tar.gz;
# use make-cvmfsexec-tarball to create it.
# Normally bails on an error; pass `-safe` as the first argument in order
# to run the command anyway (without CVMFS).
#
# To use this in jobs, edit blah.config and set
# 
#       blah_job_wrapper=/path/to/cvmfsexec-osg-wrapper
#
# or
#
#       blah_job_wrapper=/path/to/cvmfsexec-osg-wrapper -safe
#

# The slurm submit script changes $HOME so use the real one for the location of the tarball.
# XXX Should I use $GLITE_LOCATION instead?
REALHOME=$(eval echo ~"$USER")
# TODO: Allow overriding TARBALL
TARBALL=$REALHOME/cvmfsexec-osg.tar.gz
# TODO: Allow overriding/adding to CVMFS_REPOS
CVMFS_REPOS=(config-osg.opensciencegrid.org oasis.opensciencegrid.org singularity.opensciencegrid.org gwosc.osgstorage.org)
CVMFS_HTTP_PROXY=${CVMFS_HTTP_PROXY-}

if [[ -z $CVMFS_HTTP_PROXY ]]; then
    if [[ -n $TACC_SYSTEM ]]; then
        # TODO: there's probably a different one for frontera;
        CVMFS_HTTP_PROXY=http://login5.stampede2.tacc.utexas.edu:3128/
    fi
fi


SAFE=false
if [[ $1 = -safe ]]; then
    SAFE=true
    shift
fi

job=("$@")

fail () {
    echo "$@" >&2
    if $SAFE; then
        # so it shows up in environment dumps in the job
        export CVMFSEXEC_WRAPPER_FAILURE="$*"
        echo "*** $0 failed; cvmfs will be unavailable ***" >&2
        "${job[@]}"
        exit $?
    else
        exit 1
    fi
}


add_or_replace () {
    local file="$1"
    local var="$2"
    local value="$3"

    if grep -Eq "^${var}=" "$file"; then
        sed -i -r -e "s^${var}=.*${var}=\"${value}\"" "$file"
    else
        echo "${var}=\"${value}\"" >> "$file"
    fi
}


#
# Begin
#

[[ -f $TARBALL ]] || fail "cvmfsexec tarball not found at $TARBALL"
command -v fusermount >& /dev/null || fail "Required command 'fusermount' not found"

set -o nounset
PS4='+ ${LINENO}: '
#set -x

prevdir=$(pwd)
if [[ -n ${CVMFSEXEC_WRAPPER_WORKDIR:-} ]]; then
    workdir=$CVMFSEXEC_WRAPPER_WORKDIR
    mkdir -p "$workdir"
    chmod 0700 "$workdir"
    rm -rf "$workdir"/cvmfsexec >& /dev/null || :
else
    workdir=$(mktemp -d "${OSG_WN_TMP:-${TMPDIR:-/tmp}}/$USER-cvmfsexec-XXXXXX")
fi
trap 'cd "$prevdir"; rm -rf "$workdir"' EXIT


cd "$workdir" || fail "Couldn't enter work dir $workdir"
tar xzf "$TARBALL" || fail "Couldn't extract tarball $TARBALL"
#mkdir -p cvmfs-cache

cvmfs_local_config=$workdir/cvmfsexec/dist/etc/cvmfs/default.local
if [[ -e $workdir/cvmfsexec/default.local ]]; then
    cp -f "$workdir/cvmfsexec/default.local"  "$cvmfs_local_config"
fi

if [[ -n $CVMFS_HTTP_PROXY ]]; then
    echo >&2 "Setting CVMFS_HTTP_PROXY to ${CVMFS_HTTP_PROXY}"
    add_or_replace "$cvmfs_local_config" CVMFS_HTTP_PROXY "${CVMFS_HTTP_PROXY}"
fi

"$workdir"/cvmfsexec/umountrepo -a || :

trap '"$workdir"/cvmfsexec/umountrepo -a; cd "$prevdir"; rm -rf "$workdir"' EXIT

for repo in "${CVMFS_REPOS[@]}"; do
    "$workdir"/cvmfsexec/mountrepo "$repo" || fail "Unable to mount cvmfs repo $repo"
done

export CVMFS_BASE="$workdir"/cvmfsexec/dist/cvmfs

#export SINGULARITYENV_X509_CERT_DIR=$CVMFS_BASE/oasis.opensciencegrid.org/mis/certificates/
#
## disable jemalloc virtual memory reuse
#export SINGULARITYENV_MALLOC_CONF="retain:false"
#
#export SINGULARITYENV_LD_PRELOAD=""
#export SINGULARITY_BIND="/tmp,/scratch"
#export SINGULARITYENV_MALLOC_CONF="retain:false"

export GLIDEIN_SINGULARITY_BINDPATH="$CVMFS_BASE:/cvmfs"

echo "*** cvmfs available at $CVMFS_BASE" >&2

if [[ -n $TACC_SYSTEM ]]; then
    echo >&2 "*** Adding $TACC_SYSTEM statements"
    set +o nounset
    module load tacc-singularity
fi


# Note: do not use 'exec'; cleanup won't run
"$@"
