condor_start_project.sh
Go to the documentation of this file.
1 #! /bin/bash
2 #------------------------------------------------------------------
3 #
4 # Purpose: A batch worker script for starting a sam project.
5 #
6 # Usage:
7 #
8 # condor_start_project.sh [options]
9 #
10 # --sam_user <arg> - Specify sam user (default $GRID_USER).
11 # --sam_group <arg> - Specify sam group (required).
12 # --sam_station <arg> - Specify sam station (required).
13 # --sam_defname <arg> - Sam dataset definition name (required).
14 # --sam_project <arg> - Sam project name (required).
15 # --logdir <arg> - Specify log directory (optional).
16 # -g, --grid - No effect (allowed for compatibility).
17 # --recur - Recursive input dataset (force snapshot).
18 # --init <path> - Absolute path of environment initialization script (optional).
19 # --max_files <n> - Specify the maximum number of files to include in this project.
20 # --prestage_fraction - Fraction of files that should be prestaged.
21 # Specify as floating point number between 0 and 1.
22 #
23 # End options.
24 #
25 # Created: H. Greenlee, 29-Aug-2012
26 #
27 #------------------------------------------------------------------
28 
29 # Parse arguments.
30 
31 SAM_USER=$GRID_USER
32 SAM_GROUP=""
33 SAM_STATION=""
34 SAM_DEFNAME=""
35 SAM_PROJECT=""
36 LOGDIR=""
37 RECUR=0
38 INIT=""
39 MAX_FILES=0
40 PRESTAGE_FRACTION=0
41 IFDH_OPT=""
42 
43 while [ $# -gt 0 ]; do
44  case "$1" in
45 
46  # Help.
47  -h|--help )
48  awk '/^# Usage:/,/^# End options/{print $0}' $0 | cut -c3- | head -n -2
49  exit
50  ;;
51 
52  # Sam user.
53  --sam_user )
54  if [ $# -gt 1 ]; then
55  SAM_USER=$2
56  shift
57  fi
58  ;;
59 
60  # Sam group.
61  --sam_group )
62  if [ $# -gt 1 ]; then
63  SAM_GROUP=$2
64  shift
65  fi
66  ;;
67 
68  # Sam station.
69  --sam_station )
70  if [ $# -gt 1 ]; then
71  SAM_STATION=$2
72  shift
73  fi
74  ;;
75 
76  # Sam dataset definition name.
77  --sam_defname )
78  if [ $# -gt 1 ]; then
79  SAM_DEFNAME=$2
80  shift
81  fi
82  ;;
83 
84  # Sam project name.
85  --sam_project )
86  if [ $# -gt 1 ]; then
87  SAM_PROJECT=$2
88  shift
89  fi
90  ;;
91 
92  # Log directory.
93  --logdir )
94  if [ $# -gt 1 ]; then
95  LOGDIR=$2
96  shift
97  fi
98  ;;
99 
100  # Grid flag.
101  -g|--grid )
102  ;;
103 
104  # Recursive flag.
105  --recur )
106  RECUR=1
107  ;;
108 
109  # Specify environment initialization script path.
110  --init )
111  if [ $# -gt 1 ]; then
112  INIT=$2
113  shift
114  fi
115  ;;
116 
117  # Specify the maximum number of files for this project.
118  --max_files )
119  if [ $# -gt 1 ]; then
120  MAX_FILES=$2
121  shift
122  fi
123  ;;
124 
125  # Specify fraction of files that should be prestaged.
126  --prestage_fraction )
127  if [ $# -gt 1 ]; then
128  PRESTAGE_FRACTION=$2
129  shift
130  fi
131  ;;
132 
133  # Other.
134  * )
135  echo "Unknown option $1"
136  exit 1
137  esac
138  shift
139 done
140 
141 # Done with arguments.
142 
143 echo "Nodename: `hostname`"
144 
145 # Check and print configuraiton options.
146 
147 echo "Sam user: $SAM_USER"
148 echo "Sam group: $SAM_GROUP"
149 echo "Sam station: $SAM_STATION"
150 echo "Sam dataset definition: $SAM_DEFNAME"
151 echo "Sam project name: $SAM_PROJECT"
152 echo "Recursive flag: $RECUR"
153 echo "Prestage fraction: $PRESTAGE_FRACTION"
154 
155 # Complain if SAM_STATION is not defined.
156 
157 if [ x$SAM_STATION = x ]; then
158  echo "Sam station was not specified (use option --sam_station)."
159  exit 1
160 fi
161 
162 # Complain if SAM_GROUP is not defined.
163 
164 if [ x$SAM_GROUP = x ]; then
165  echo "Sam group was not specified (use option --sam_group)."
166  exit 1
167 fi
168 
169 # Complain if SAM_DEFNAME is not defined.
170 
171 if [ x$SAM_DEFNAME = x ]; then
172  echo "Sam dataset was not specified (use option --sam_defname)."
173  exit 1
174 fi
175 
176 # Complain if SAM_PROJECT is not defined.
177 
178 if [ x$SAM_PROJECT = x ]; then
179  echo "Sam project name was not specified (use option --sam_project)."
180  exit 1
181 fi
182 
183 # Initialize ups products and mrb.
184 
185 echo "Initializing ups and mrb."
186 
187 if [ x$INIT != x ]; then
188  if [ ! -f $INIT ]; then
189  echo "Environment initialization script $INIT not found."
190  exit 1
191  fi
192  echo "Sourcing $INIT"
193  source $INIT
194 else
195  echo "Sourcing setup_experiment.sh"
196  source ${CONDOR_DIR_INPUT}/setup_experiment.sh
197 fi
198 
199 echo PRODUCTS=$PRODUCTS
200 
201 # Ifdh may already be setup by jobsub wrapper.
202 # If not, set it up here.
203 
204 echo "IFDHC_DIR=$IFDHC_DIR"
205 if [ x$IFDHC_DIR = x ]; then
206  echo "Setting up ifdhc, because jobsub did not set it up."
207  setup ifdhc
208 fi
209 echo "IFDHC_DIR=$IFDHC_DIR"
210 
211 # Setup sam_web_client, if not already done.
212 
213 if [ x$SAM_WEB_CLIENT_DIR = x ]; then
214  echo "Setting up sam_web_client."
215  setup sam_web_client
216 fi
217 echo "SAM_WEB_CLIENT_DIR=$SAM_WEB_CLIENT_DIR"
218 
219 # Set options for ifdh.
220 
221 echo "IFDH_OPT=$IFDH_OPT"
222 
223 # Create the scratch directory in the condor scratch diretory.
224 # Copied from condor_lBdetMC.sh.
225 # Scratch directory path is stored in $TMP.
226 # Scratch directory is automatically deleted when shell exits.
227 
228 # Do not change this section.
229 # It creates a temporary working directory that automatically cleans up all
230 # leftover files at the end.
231 TMP=`mktemp -d ${_CONDOR_SCRATCH_DIR}/working_dir.XXXXXXXXXX`
232 TMP=${TMP:-${_CONDOR_SCRATCH_DIR}/working_dir.$$}
233 
234 { [[ -n "$TMP" ]] && mkdir -p "$TMP"; } || \
235  { echo "ERROR: unable to create temporary directory!" 1>&2; exit 1; }
236 trap "[[ -n \"$TMP\" ]] && { rm -rf \"$TMP\"; }" 0
237 cd $TMP
238 # End of the section you should not change.
239 
240 echo "Scratch directory: $TMP"
241 
242 # Save the project name in a file.
243 
244 echo $SAM_PROJECT > sam_project.txt
245 
246 # Test whether project is already started.
247 
248 samweb project-summary $SAM_PROJECT > /dev/null 2> /dev/null
249 started=$?
250 
251 # Following section only if project is not already started.
252 
253 if [ $started -ne 0 ]; then
254 
255  # Do some preliminary tests on the input dataset definition.
256  # If dataset definition returns zero files at this point, abort the job.
257  # If dataset definition returns too many files compared to --max_files, create
258  # a new dataset definition by adding a "with limit" clause.
259 
260  nf=`ifdh translateConstraints "defname: $SAM_DEFNAME" | wc -l`
261  if [ $nf -eq 0 ]; then
262  echo "Input dataset $SAM_DEFNAME is empty."
263  exit 1
264  else
265  echo "Input dataset contains $nf files."
266  fi
267  if [ $MAX_FILES -ne 0 -a $nf -gt $MAX_FILES ]; then
268  limitdef=${SAM_PROJECT}_limit_$MAX_FILES
269 
270  # Check whether limit def already exists.
271  # Have to parse command output because ifdh returns wrong status.
272 
273  existdef=`ifdh describeDefinition $limitdef 2>/dev/null | grep 'Definition Name:' | wc -l`
274  if [ $existdef -gt 0 ]; then
275  echo "Using already created limited dataset definition ${limitdef}."
276  else
277  ifdh createDefinition $limitdef "defname: $SAM_DEFNAME with limit $MAX_FILES" $SAM_USER $SAM_GROUP
278 
279  # Assume command worked, because it returns the wrong status.
280 
281  echo "Created limited dataset definition ${limitdef}."
282  fi
283 
284  # If we get to here, we know that we want to user $limitdef instead of $SAM_DEFNAME
285  # as the input sam dataset definition.
286 
287  SAM_DEFNAME=$limitdef
288  nf=$MAX_FILES
289  fi
290 
291  # If recursive flag, force snapshot of input dataset.
292 
293  forcedef=$SAM_DEFNAME
294  if [ $RECUR -ne 0 ]; then
295  echo "Forcing snapshot"
296  forcedef=${SAM_DEFNAME}:force
297  fi
298 
299  # Start the project.
300 
301  echo "Starting project ${SAM_PROJECT}."
302  ifdh startProject $SAM_PROJECT $SAM_STATION $forcedef $SAM_USER $SAM_GROUP
303  if [ $? -eq 0 ]; then
304  echo "Project successfully started."
305  started=0
306  else
307  echo "Start project error status $?"
308  fi
309 fi
310 
311 # Create a dataset definition corresponding to the project snapshot.
312 
313 snapshotdefname=snapshot_${SAM_PROJECT}
314 ifdh createDefinition $snapshotdefname "snapshot_for_project_name $SAM_PROJECT" $SAM_USER $SAM_GROUP
315 if [ $? -ne 0 ]; then
316  echo "Failed to create snapshot dataset definition ${snapshotdefname}."
317  exit 1
318 fi
319 echo "Created snapshot dataset definition ${snapshotdefname}."
320 
321 # Check the project snapshot.
322 
323 nf=0
324 if [ $started -eq 0 ]; then
325  nf=`ifdh translateConstraints "defname: $snapshotdefname" | wc -l`
326  echo "Project snapshot contains $nf files."
327 fi
328 
329 # Abort if snapshot contains zero files. Stop project and eventually exit with error status.
330 
331 if [ $started -eq 0 -a $nf -eq 0 ]; then
332  echo "Stopping project."
333  started=1
334  PURL=`ifdh findProject $SAM_PROJECT $SAM_STATION`
335  if [ x$PURL != x ]; then
336  echo "Project url: $PURL"
337  ifdh endProject $PURL
338  if [ $? -eq 0 ]; then
339  echo "Project successfully stopped."
340  fi
341  fi
342 fi
343 
344 # Calculate the number of files to prestage.
345 
346 npre=`echo "$PRESTAGE_FRACTION * $nf / 1" | bc`
347 echo "Will attempt to prestage $npre files."
348 
349 # If number of prestage files is greater than zero, do prestage here.
350 
351 if [ $npre -gt 0 ]; then
352 
353  # Generate name of prestage project.
354  # Here we use a safe name that won't drain recursive datasets (unlike "samweb prestage-dataset").
355 
356  prjname=prestage_${SAM_PROJECT}
357  echo "Prestage project: $prjname"
358 
359  # Start prestage project.
360 
361  ifdh startProject $prjname $SAM_STATION ${snapshotdefname}:latest $SAM_USER $SAM_GROUP
362  if [ $? -ne 0 ]; then
363  echo "Failed to start prestage project."
364  exit 1
365  fi
366  echo "Prestage project started."
367 
368  # Get prestage project url.
369 
370  prjurl=`ifdh findProject $prjname $SAM_STATION`
371  if [ x$prjurl = x ]; then
372  echo "Unable to find url for project ${prjname}."
373  exit 1
374  fi
375 
376  # Start consumer process.
377 
378  node=`hostname`
379  appfamily=prestage
380  appname=prestage
381 
382  # Make description, which is conventionally the jobsub job id.
383  # This can not be empty.
384 
385  DESC=$JOBSUBJOBID
386  if [ x$DESC = x ]; then
387  DESC="Prestage"
388  fi
389 
390  echo "Starting consumer process."
391  cpid=`ifdh establishProcess $prjurl $appname 1 $node $SAM_USER $appfamily $DESC $npre`
392  if [ x$cpid = x ]; then
393  echo "Unable to start consumer process for project ${prjname}."
394  exit 1
395  fi
396  echo "Prestage consumer process ${cpid} started."
397 
398  # Loop over files.
399 
400  n=0
401  while true; do
402 
403  # Get next file.
404  # When this command returns, the file is prestaged.
405 
406  fileurl=`ifdh getNextFile $prjurl $cpid`
407  if [ $? -ne 0 -o x$fileurl = x ]; then
408  echo "No more files."
409  echo "$n files prestaged."
410  break
411  fi
412  filename=`basename $fileurl`
413  echo "$filename is prestaged."
414  n=$(( $n + 1 ))
415 
416  # Release file.
417 
418  ifdh updateFileStatus $prjurl $cpid $filename consumed
419 
420  done
421 
422  # End consumer process.
423 
424  ifdh endProcess $prjurl $cpid
425  echo "Prestage consumer process stopped."
426 
427  # End prestage project.
428 
429  ifdh endProject $prjurl
430  echo "Prestage project stopped."
431 
432 fi
433 
434 # Stash all of the files we want to save in a local
435 # directory with a unique name. Then copy this directory
436 # and its contents recursively.
437 
438 if [ x$LOGDIR != x ]; then
439  LOGDIR=`echo $LOGDIR | sed 's/@s/sam/'`
440  OUTPUT_SUBDIR=${CLUSTER}_start
441  mkdir $OUTPUT_SUBDIR
442  for outfile in *; do
443  if [ $outfile != $OUTPUT_SUBDIR ]; then
444  mv $outfile $OUTPUT_SUBDIR
445  fi
446  done
447  echo "ifdh cp -r $IFDH_OPT $OUTPUT_SUBDIR ${LOGDIR}/$OUTPUT_SUBDIR"
448  ifdh cp -r $IFDH_OPT $OUTPUT_SUBDIR ${LOGDIR}/$OUTPUT_SUBDIR
449  if [ $? -ne 0 ]; then
450  echo "ifdh cp failed with status ${stat}."
451  exit $stat
452  fi
453 fi
454 
455 # Done. Set exit status to reflect whether project was started (0=success).
456 
457 exit $started