#!/bin/bash
# set -x
#
# Input: path to grami file (same as Globus).
# This script creates a temporary job script and runs it
DEBUG=0
echo "----- starting submit_boinc_job -----" 1>&2
joboption_lrms="boinc"
lrms_options="boinc_app_id boinc_db_host boinc_db_port boinc_db_user boinc_db_pass boinc_db_name boinc_project_dir"
# ARC1 passes first the config file.
if [ "$1" = "--config" ]; then shift; ARC_CONFIG=$1; shift; fi
GRAMI_FILE=$1
# define paths and config parser
basedir=`dirname $0`
basedir=`cd $basedir > /dev/null && pwd` || exit $?
. "${basedir}/lrms_common.sh"
# include common submit functions
. "${pkgdatadir}/submit_common.sh" || exit $?
# run common init
# * parse grami
# * parse config
# * load LRMS-specific env
# * set common variables
common_init
joboption_stdout='`pwd`/'`basename $joboption_stdout`
joboption_stderr='`pwd`/'`basename $joboption_stderr`
RUNTIME_NODE_SEES_FRONTEND=yes
##############################################################
# Zero stage of runtime environments
##############################################################
RTE_stage0
joboption_directory_orig=$joboption_directory
joboption_directory='`pwd`'
# make sure session is world-writable
chmod 777 $joboption_directory_orig
PROJECT_ROOT="$CONFIG_boinc_project_dir"
echo "project_root=$PROJECT_ROOT" 1>&2
if [ -z "$PROJECT_ROOT" ]; then
echo "No project directory configured" 1>&2
exit 1
elif [ ! -d "$PROJECT_ROOT" ]; then
echo "Project dir ${PROJECT_ROOT} does not exist" 1>&2
exit 1
elif [ ! -x "${PROJECT_ROOT}/bin/create_work" ]; then
echo "Project dir ${PROJECT_ROOT} does appear to be a BOINC project" 1>&2
exit 1
fi
cd $PROJECT_ROOT
##############################################################
# create job script
##############################################################
mktempscript
LRMS_JOB_BOINC="${LRMS_JOB_SCRIPT}.boinc"
touch $LRMS_JOB_BOINC
chmod u+x ${LRMS_JOB_SCRIPT}
##############################################################
# Start job script
##############################################################
N=0
x=$joboption_directory_orig
while [ "$x" != "/" ]
do
x=`dirname $x`
N=$((N+1))
done
echo '#!/bin/sh' > $LRMS_JOB_SCRIPT
echo "#job script built by grid-manager and input file for BOINC job" >> $LRMS_JOB_SCRIPT
echo "" >> $LRMS_JOB_SCRIPT
cat >> $LRMS_JOB_SCRIPT <<"FMARK"
set -x
export RUNTIME_CONFIG_DIR=`pwd`/
#rename root file
FMARK
echo tar --strip-components=$N -xvf *input.tar.gz >> $LRMS_JOB_SCRIPT
##############################################################
# non-parallel jobs
##############################################################
set_count
sourcewithargs_jobscript
##############################################################
# Override umask
##############################################################
echo "" >> $LRMS_JOB_SCRIPT
echo "# Overide umask of execution node (sometime values are really strange)" >> $LRMS_JOB_SCRIPT
echo "umask 077" >> $LRMS_JOB_SCRIPT
##############################################################
# Init accounting
##############################################################
accounting_init
##############################################################
# Add environment variables
##############################################################
add_user_env
##############################################################
# Check for existance of executable,
##############################################################
if [ -z "${joboption_arg_0}" ] ; then
echo 'Executable is not specified' 1>&2
exit 1
fi
setup_runtime_env
##############################################################
# Add std... to job arguments
##############################################################
include_std_streams
##############################################################
# Move files to local working directory (job is done on node only)
# RUNTIME_JOB_DIR -> RUNTIME_LOCAL_SCRATCH_DIR/job_id
##############################################################
move_files_to_node
##############################################################
# Runtime configuration
##############################################################
echo RUNTIME_JOB_DIAG='`pwd`/'`basename $joboption_directory_orig`.diag >>$LRMS_JOB_SCRIPT
RTE_stage1
echo "echo \"runtimeenvironments=\$runtimeenvironments\" >> \"\$RUNTIME_JOB_DIAG\"" >> $LRMS_JOB_SCRIPT
#####################################################
# Accounting (WN OS Detection)
#####################################################
detect_wn_systemsoftware
#####################################################
# Go to working dir and start job
#####################################################
cd_and_run
# Add nodename username@hostname and fix core count for accounting
# Add exit code here since accounting_end does it after the diag file has been tarred up
cat >> $LRMS_JOB_SCRIPT <<"FMARK"
sed -i -e '/nodename=/d' $RUNTIME_JOB_DIAG
hostname=` grep domain_name init_data.xml |awk -F '>' '{print $2}'|awk -F "<" '{print $1}'|sed -e "s# #_#g"`
username=` grep user_name init_data.xml |awk -F '>' '{print $2}'|awk -F "<" '{print $1}'|sed -e "s# #_#g"`
nodename=$username@$hostname
echo "nodename=$nodename" >> "$RUNTIME_JOB_DIAG"
[ -n "$ATHENA_PROC_NUMBER" ] && sed -i -e 's/Processors=1/Processors='"$ATHENA_PROC_NUMBER"'/' $RUNTIME_JOB_DIAG
echo "exitcode=$RESULT" >> "$RUNTIME_JOB_DIAG"
FMARK
echo "" >> $LRMS_JOB_SCRIPT
##############################################################
# Runtime (post)configuration at computing node
##############################################################
RTE_stage2
##############################################################
# Move files back to session directory (job is done on node only)
# RUNTIME_JOB_DIR -> RUNTIME_LOCAL_SCRATCH_DIR/job_id
##############################################################
#move_files_to_frontend
#############################################################
# zip the result files into 1 file zip.tar.gz
#############################################################
notnull ()
{
if [ -z $1 ];then
echo 0
else
echo 1
fi
}
result_list=
i=0
eval opt=\${joboption_outputfile_$i}
ret=`notnull $opt`
while [ $ret = "1" ]
do
output_file=$(echo $opt|sed -e "s#^/#./#")
output_file=$(echo $output_file|sed -e "s#@##")
result_list=$result_list" "$output_file
i=$((i+1))
eval opt=\${joboption_outputfile_$i}
ret=`notnull $opt`
echo "ret="$ret
done
files=$(echo $result_list|tr " " "\n")
cat >> $LRMS_JOB_SCRIPT <<'EOF'
echo "zip all output files"
flist="*.diag "
EOF
echo for f in $files >>$LRMS_JOB_SCRIPT
cat >> $LRMS_JOB_SCRIPT <<'EOF'
do
if [ -e $f ];then
flist=$flist" "$f
fi
done
EOF
#echo $flist
cat <<'EOF' >>$LRMS_JOB_SCRIPT
if [ -f output.list ];then
ol=$(awk '{print $1}' output.list)
for i in $ol
do
if [[ -f $i && ! $i =~ HITS.* ]];then
flist=$flist" "$i
fi
done
sed -i -e 's/HITS.* /HITS.pool.root.1 /' output.list
fi
EOF
echo 'tar cvf result.tar.gz $flist' >>$LRMS_JOB_SCRIPT
chmod a+r $LRMS_JOB_SCRIPT
##############################################################
# Finish accounting and exit job
##############################################################
accounting_end
#######################################
# Submit the job
#######################################
echo "job script ${LRMS_JOB_SCRIPT} built" 1>&2
JobId=`basename $joboption_directory_orig`
JobInput=$joboption_directory_orig/$JobId"_input.tar.gz"
wu=$JobId
echo "#!/bin/bash" >> $LRMS_JOB_BOINC
echo "set -x" >> $LRMS_JOB_BOINC
tflist=""
Root_basename=()
RootFile=()
## RootFile keeps the orginal path of the root files
## Root_basename keeps the basename of the root files, with adding JobID to make them unique
i=0
for file in `ls $joboption_directory_orig`
do
echo $file|grep ".root" > /dev/null
ret=$?
if [ $ret -eq 0 ]; then
echo skip root file $file
Root_basename[$i]=$JobId"_"$file
RootFile[$i]=$joboption_directory_orig/$file
sed -i -e "/#rename root file/a\mv ATLAS.root_$i $file" $LRMS_JOB_SCRIPT
let i=$i+1
continue
else
tflist=$tflist" "$joboption_directory_orig/$file
fi
done
echo tar zhcvf $JobInput $tflist
echo "tar zhcvf $JobInput $tflist" >> $LRMS_JOB_BOINC
echo "cd $PROJECT_ROOT " >>$LRMS_JOB_BOINC
JobInput_basename=`basename $JobInput`
Script_basename=`basename $LRMS_JOB_SCRIPT`
echo "cp $JobInput "'`bin/dir_hier_path '$(basename $JobInput)'`' >> $LRMS_JOB_BOINC
echo "chmod a+r "'`bin/dir_hier_path '$(basename $JobInput)'`' >> $LRMS_JOB_BOINC
echo "cp $LRMS_JOB_SCRIPT " '`bin/dir_hier_path' $(basename $LRMS_JOB_SCRIPT)'`' >>$LRMS_JOB_BOINC
echo "chmod a+r " '`bin/dir_hier_path' $(basename $LRMS_JOB_SCRIPT)'`' >>$LRMS_JOB_BOINC
[ -n "$PROJECT_DOWNLOAD_ROOT" ] && echo "cd $PROJECT_DOWNLOAD_ROOT" >> $LRMS_JOB_BOINC
## process the root files as remote files
cd $PROJECT_ROOT
echo "current directory is the project_root: "$PWD
remote_url=()
fsize=()
md5=()
i=0
while [ $i -lt ${#RootFile[@]} ]
do
[ -L ${RootFile[$i]} ] && RootFile[$i]=`ls -l ${RootFile[$i]}|awk '{print $11}'`
echo "ln -s ${RootFile[$i]} "'`bin/dir_hier_path' ${Root_basename[$i]} '`' >> $LRMS_JOB_BOINC
if [ -n "$PROJECT_DOWNLOAD_ROOT" ]; then
download_dir=`bin/dir_hier_path ${Root_basename[$i]} | awk -F/ '{print $(NF-1)}'`
remote_url[$i]="${PROJECT_DOWNLOAD_URL}/${download_dir}/${Root_basename[$i]}"
fsize[$i]=`stat -c %s ${RootFile[$i]}`
md5[$i]=`md5sum ${RootFile[$i]} | awk '{print $1}'`
echo "Using remote file ${remote_url[$i]} ${fsize[$i]} ${md5[$i]}" 1>&2
fi
let i=$i+1
done
[ -n "$PROJECT_DOWNLOAD_ROOT" ] && echo "cd $PROJECT_ROOT" >> $LRMS_JOB_BOINC
## generate the input template file
let ifileno=2+${#RootFile[@]}
i=0
intmp=""
while [ $i -lt $ifileno ]
do
intmp="$intmp
$i
"
let i=$i+1
done
intmp="$intmp
"
i=0
while [ $i -lt ${#RootFile[@]} ]
do
intmp="$intmp
$i
shared/ATLAS.root_$i
"
let i=$i+1
done
intmp="$intmp
$i
shared/input.tar.gz
"
let i=$i+1
intmp="$intmp
$i
shared/start_atlas.sh
"
intmp_res=$(cat $WU_TEMPLATE)
intmp="$intmp
$intmp_res
"
intmp="$intmp
"
WU_TEMPLATE_tmp=$(mktemp /tmp/${BOINC_APP}_XXXXXX)
cat << EOF > $WU_TEMPLATE_tmp
$intmp
EOF
#######################################
if [ -z $joboption_memory ];then
memreq=2000000000
else
memreq=$((joboption_memory*1000000))
fi
if [ -z $joboption_cputime ];then
maxcputime=$((2*3600*3000000000))
else
maxcputime=$((joboption_cputime*3000000000))
fi
priority=
if [ ! -z "$joboption_priority" ]; then
priority="--priority $joboption_priority"
fi
batchid=
if [ -f "${joboption_directory_orig}/pandaJobData.out" ]; then
taskid=$(grep -E -m1 -o "taskID=[[:digit:]]+" ${joboption_directory_orig}/pandaJobData.out|cut -d = -f 2 )
if [ ! -z "$taskid" ]; then
batchid="--batch $taskid"
fi
fi
cmd="bin/create_work \
--appname $BOINC_APP \
--wu_name $wu \
--wu_template $WU_TEMPLATE_tmp \
--result_template $RESULT_TEMPLATE \
--rsc_memory_bound $memreq \
--rsc_fpops_est $maxcputime \
$batchid \
$priority"
j=0
while [ $j -lt ${#RootFile[@]} ]
do
if [ -n "$PROJECT_DOWNLOAD_ROOT" ]; then
cmd="$cmd \
--remote_file ${remote_url[$j]} ${fsize[$j]} ${md5[$j]}"
else
cmd="$cmd \
${Root_basename[$j]}"
fi
let j=$j+1
done
cmd="$cmd \
$(basename $JobInput) \
$(basename $LRMS_JOB_SCRIPT)"
echo $cmd >> $LRMS_JOB_BOINC
echo 'ret=$?' >>$LRMS_JOB_BOINC
echo 'exit $ret' >>$LRMS_JOB_BOINC
if [ $DEBUG -eq 2 ];then
cat $LRMS_JOB_BOINC 1>&2
else
sh $LRMS_JOB_BOINC 1>&2
fi
rc=$?
if [ $rc -eq 0 ];then
echo "job $wu submitted successfully!" 1>&2
echo "joboption_jobid=$wu" >> $GRAMI_FILE
fi
echo "----- removing intermediate files ----" 1>&2
if [ $DEBUG -ne 1 ];then
rm -fr $WU_TEMPLATE_tmp
rm -fr $LRMS_JOB_BOINC $LRMS_JOB_ERR $LRMS_JOB_OUT $LRMS_JOB_SCRIPT
rm -fr $JobInput
fi
echo "----- exiting submit_boinc_job -----" 1>&2
echo "" 1>&2
exit $rc