]>
Commit | Line | Data |
---|---|---|
d4ab9e58 | 1 | #!/bin/bash |
2 | # | |
3 | # - script to sync a group of files on alien with a local cache | |
4 | # downloads only new and updated files | |
5 | # - by default it mirrors the directory structure in a specified local location | |
6 | # (the local chache location and paths can be manipulated.) | |
7 | # - needs a configured config file (by default alienSync.config) | |
8 | # and a working alien environment (token and at least $ALIEN_DIR or $ALIEN_ROOT set) | |
9 | # | |
10 | # origin: Mikolaj Krzewicki, mikolaj.krzewicki@cern.ch | |
11 | # | |
c1fbf113 | 12 | if [ ${BASH_VERSINFO} -lt 4 ]; then |
13 | echo "bash version >= 4 needed, you have ${BASH_VERSION}, exiting..." | |
14 | exit 1 | |
15 | fi | |
16 | ||
d4ab9e58 | 17 | main() |
18 | { | |
19 | if [[ $# -lt 1 ]]; then | |
d56eeaab | 20 | echo "Usage: ${0##*/} configFile=/path/to/config" |
823ca2e7 | 21 | echo "expert: ${0##*/} alienFindCommand=\"alien_find /some/path/ file\" [opt=value]" |
22 | echo " ${0##*/} alienFindCommand=\"alien_find /some/path/ file\" localPathPrefix=\${PWD}" | |
23 | echo | |
24 | echo "by default files are downloaded to current dir, or \${alienSync_localPathPrefix} if set." | |
25 | echo "At least specify alienFindCommand, either on command line or in the configFile." | |
d4ab9e58 | 26 | return |
27 | fi | |
2c39ca2b | 28 | |
d4ab9e58 | 29 | # try to load the config file |
d56eeaab | 30 | #[[ ! -f $1 ]] && echo "config file $1 not found, exiting..." | tee -a $logFile && exit 1 |
31 | if ! parseConfig "$@"; then return 1; fi | |
32 | ||
2c39ca2b | 33 | [[ -z ${alienFindCommand} ]] && echo "alienFindCommand not defined!" && return 1 |
d56eeaab | 34 | |
6c8c572d | 35 | #if not set, use the default group |
36 | [[ -z ${alienSyncFilesGroupOwnership} ]] && alienSyncFilesGroupOwnership=$(id -gn) | |
d4ab9e58 | 37 | |
38 | # do some accounting | |
1e600c4f | 39 | [[ ! -d $logOutputPath ]] && echo "logOutputPath not available, creating..." && mkdir -p $logOutputPath && chgrp ${alienSyncFilesGroupOwnership} ${logOutputPath} |
d4ab9e58 | 40 | [[ ! -d $logOutputPath ]] && echo "could not create log dir, exiting..." && exit 1 |
41 | dateString=$(date +%Y-%m-%d-%H-%M) | |
42 | logFile=$logOutputPath/alienSync-$dateString.log | |
43 | echo "$0 $@"|tee -a $logFile | |
44 | echo ""|tee -a $logFile | |
45 | echo log: $logFile | |
46 | ||
47 | #be nice and allow group members access as well (002 will create dirs with 775 and files with 664) | |
48 | umask 0002 | |
49 | ||
50 | #lock | |
51 | lockFile=$logOutputPath/runningNow.lock | |
52 | [[ -f $lockFile ]] && echo "locked. Another process running? ($lockFile)" | tee -a $logFile && exit 1 | |
53 | touch $lockFile | |
54 | [[ ! -f $lockFile ]] && echo "unable to create lock. exiting..." | tee -a $logFile && exit 1 | |
55 | ||
56 | #redirect all output to a log | |
57 | if [[ $allOutputToLog -eq 1 ]]; then | |
58 | exec 6>&1 | |
59 | exec 1>$logFile 2>&1 | |
60 | fi | |
2c39ca2b | 61 | |
d4ab9e58 | 62 | newFilesList=$logOutputPath/"newFiles.list" |
63 | rm -f $newFilesList | |
64 | touch $newFilesList | |
65 | redoneFilesList=$logOutputPath/"redoneFiles.list" | |
66 | rm -f $redoneFilesList | |
67 | touch $redoneFilesList | |
68 | updatedFilesList="${logOutputPath}/updatedFiles.list" | |
ec825842 | 69 | failedDownloadList="${logOutputPath}/failedDownload.list" |
70 | touch ${failedDownloadList} | |
71 | ||
d4ab9e58 | 72 | |
73 | # check the config | |
74 | [[ -z $alienFindCommand ]] && echo "alienFindCommand not defined, exiting..." && exitScript 1 | |
75 | [[ -z ${localPathPrefix} ]] && echo "localPathPrefix not defined, exiting..." && exitScript 1 | |
76 | [[ -z $logOutputPath ]] && echo "logOutputPath not defined, exiting..." && exitScript 1 | |
77 | [[ -z $secondsToSuicide ]] && echo "setting default secondsToSuicide of 10 hrs..." && secondsToSuicide=$(( 10*3600 )) | |
78 | ||
79 | # init alien | |
d4ab9e58 | 80 | [[ -z $ALIEN_ROOT && -n $ALIEN_DIR ]] && ALIEN_ROOT=$ALIEN_DIR |
81 | #if ! haveAlienToken; then | |
82 | # $ALIEN_ROOT/api/bin/alien-token-destroy | |
83 | $ALIEN_ROOT/api/bin/alien-token-init $alienUserName | |
84 | #fi | |
85 | #if ! haveAlienToken; then | |
86 | # if [[ $allOutputToLog -eq 1 ]]; then | |
87 | # exec 1>&6 6>&- | |
88 | # fi | |
89 | # echo "problems getting token! exiting..." | tee -a $logFile | |
90 | # exitScript 1 | |
91 | #fi | |
92 | #ls -ltr /tmp/gclient_env_$UID | |
93 | #cat /tmp/gclient_env_$UID | |
6c8c572d | 94 | source /tmp/gclient_env_$UID |
d4ab9e58 | 95 | |
96 | #set a default timeout for grid access | |
97 | [[ -z $copyTimeout ]] && copyTimeout=600 | |
98 | export GCLIENT_COMMAND_MAXWAIT=$copyTimeout | |
99 | ||
100 | localAlienDatabase=$logOutputPath/localAlienDatabase.list | |
101 | localFileList=$logOutputPath/localFile.list | |
102 | ||
103 | alienFileListCurrent=$logOutputPath/alienFileDatabase.list | |
104 | [[ ! -f $localFileList ]] && touch $localFileList | |
105 | candidateLocalFileDatabase=$logOutputPath/candidateLocalFileDatabase.list | |
106 | ||
107 | #here we produce the current alien file list | |
108 | if [[ -n ${useExistingAlienFileDatabase} && -f ${localAlienDatabase} ]]; then | |
109 | #we use the old one | |
110 | echo "using ${localAlienDatabase} instead of full alien search" | |
111 | echo cp -f ${localAlienDatabase} ${alienFileListCurrent} | |
112 | cp -f ${localAlienDatabase} ${alienFileListCurrent} | |
113 | else | |
114 | #we make a new one | |
115 | echo "eval $alienFindCommand > $alienFileListCurrent" | |
116 | eval "$alienFindCommand" > $alienFileListCurrent | |
117 | fi | |
118 | ||
119 | echo "number of files in the collection: $(wc -l $alienFileListCurrent)" | |
120 | #create a list of candidate destination locations | |
121 | #this is in case there are more files on alien trying to get to the same local destination | |
122 | #in which case we take the one with the youngest ctime (later in code) | |
123 | if [[ -n ${destinationModifyCommand} ]]; then | |
124 | echo eval "cat $alienFileListCurrent | ${destinationModifyCommand} | sed \"s,^,${localPathPrefix},\" > ${candidateLocalFileDatabase}" | |
125 | eval "cat $alienFileListCurrent | ${destinationModifyCommand} | sed \"s,^,${localPathPrefix},\" > ${candidateLocalFileDatabase}" | |
126 | fi | |
127 | ||
128 | #logic is: if file list is missing we force the md5 recalculation | |
129 | [[ ! -f $localAlienDatabase ]] && forceLocalMD5recalculation=1 && echo "forcing local MD5 sum recalculation" && cp -f $alienFileListCurrent $localAlienDatabase | |
130 | ||
131 | #since we grep through the files frequently, copy some stuff to tmpfs for fast access | |
132 | tmp=$(mktemp -d 2>/dev/null) | |
133 | if [[ -d $tmp ]]; then | |
134 | cp $localAlienDatabase $tmp | |
135 | cp $localFileList $tmp | |
136 | cp $alienFileListCurrent $tmp | |
137 | [[ -f ${candidateLocalFileDatabase} ]] && cp ${candidateLocalFileDatabase} ${tmp} | |
138 | else | |
139 | tmp=$logOutputPath | |
140 | fi | |
141 | ||
142 | echo "starting downloading:" | |
143 | lineNumber=0 | |
144 | alienFileCounter=0 | |
145 | localFileCounter=0 | |
146 | downloadedFileCounter=0 | |
147 | while read -r alienFile md5alien timestamp size | |
148 | do | |
149 | ((lineNumber++)) | |
150 | ||
151 | #sometimes the md5 turns out empty and is then stored as a "." to avoid problems parsing | |
152 | [[ "$md5alien" =~ "." ]] && md5alien="" | |
153 | ||
154 | [[ -n $timeStampInLog ]] && date | |
155 | [[ $SECONDS -ge $secondsToSuicide ]] && echo "$SECONDS seconds passed, exiting by suicide..." && break | |
156 | [[ "$alienFile" != "/"*"/"?* ]] && echo "WARNING: read line not path-like: $alienFile" && continue | |
157 | ((alienFileCounter++)) | |
158 | destination=${localPathPrefix}/${alienFile} | |
159 | destination=${destination//\/\///} #remove double slashes | |
160 | [[ -n ${destinationModifyCommand} ]] && destination=$( eval "echo ${destination} | ${destinationModifyCommand}" ) | |
161 | destinationdir=${destination%/*} | |
162 | [[ -n $softLinkName ]] && softlinktodestination=${destinationdir}/${softLinkName} | |
163 | tmpdestination="${destination}.aliensyncTMP" | |
164 | ||
165 | if [[ -n ${destinationModifyCommand} ]]; then | |
166 | #find the candidate in the database, in case there are more files trying to go to the same | |
167 | #place due to $destinationModifyCommand which alters the final path, find the one | |
168 | #with the largest ctime (3rd field in the database list) and check if that is the current one | |
169 | #if not - skip | |
170 | #echo grep -n ${destination} $candidateLocalFileDatabase | sed "s/:/ /" | sort -rk4 | |
171 | #grep -n ${destination} $candidateLocalFileDatabase| sed "s/:/ /" | sort -rk4 | |
172 | #this guy contains: index of the original entry, local file name, md5, ctime | |
173 | candidateDBrecord=($(grep -n ${destination} $tmp/${candidateLocalFileDatabase##*/}| sed "s/:/ /" | sort -rk4|head -n1 )) | |
174 | originalEntryIndex=${candidateDBrecord[0]} | |
175 | [[ $lineNumber -ne $originalEntryIndex ]] && continue | |
176 | fi | |
2c39ca2b | 177 | |
d4ab9e58 | 178 | redownloading="" |
179 | if [[ -f ${destination} ]]; then | |
9c9427a5 | 180 | #soft link the downloaded file (maybe to provide a consistent link to the latest version) |
181 | if [[ -n $softlinktodestination ]]; then | |
182 | echo ln -sf ${destination} ${softlinktodestination} | |
183 | ln -sf ${destination} ${softlinktodestination} | |
d4ab9e58 | 184 | fi |
185 | ((localFileCounter++)) | |
186 | ||
187 | localDBrecord=($(grep $alienFile $tmp/${localAlienDatabase##*/})) | |
188 | md5local=${localDBrecord[1]} | |
189 | ||
190 | #sometimes the md5 turns out empty and is then stored as a "." to avoid problems parsing | |
191 | [[ "$md5local" =~ "." ]] && md5local="" | |
192 | ||
193 | if [[ $forceLocalMD5recalculation -eq 1 || -z $md5local ]]; then | |
c1fbf113 | 194 | md5recalculated=$(checkMD5sum ${destination}) |
d4ab9e58 | 195 | [[ "$md5local" != "$md5recalculated" ]] && echo "WARNING: local copy change ${destination}" |
196 | md5local=${md5recalculated} | |
197 | fi | |
198 | if [[ "$md5local" == "$md5alien" && -n $md5alien ]]; then | |
199 | echo "OK ${destination} $md5alien" | |
200 | if ! grep -q ${destination} $tmp/${localFileList##*/}; then | |
201 | echo ${destination} >> $localFileList | |
202 | fi | |
203 | continue | |
204 | fi | |
205 | if [[ -z $md5alien ]]; then | |
206 | if ! grep -q ${destination} $tmp/${localFileList##*/}; then | |
207 | echo ${destination} >> $localFileList | |
208 | fi | |
209 | echo "WARNING: missing alien md5, leaving the local file as it is" | |
210 | continue | |
211 | fi | |
212 | echo "WARNING: md5 mismatch ${destination}" | |
213 | echo " $md5local $md5alien" | |
214 | redownloading=1 | |
215 | fi | |
216 | ||
217 | [[ -f $tmpdestination ]] && echo "WARNING: stale $tmpdestination, removing" && rm $tmpdestination | |
218 | ||
1e600c4f | 219 | mkdir -p ${destinationdir} && chgrp ${alienSyncFilesGroupOwnership} ${destinationdir} |
d4ab9e58 | 220 | [[ ! -d $destinationdir ]] && echo cannot access $destinationdir && continue |
221 | ||
222 | #check token | |
223 | #if ! haveAlienToken; then | |
224 | # $ALIEN_ROOT/api/bin/alien-token-init $alienUserName | |
225 | # #source /tmp/gclient_env_$UID | |
226 | #fi | |
2c39ca2b | 227 | |
d4ab9e58 | 228 | export copyMethod |
229 | export copyScript | |
230 | export copyTimeout | |
231 | export copyTimeoutHard | |
232 | echo copyFromAlien "$alienFile" "$tmpdestination" | |
233 | [[ $pretend -eq 1 ]] && continue | |
234 | copyFromAlien $alienFile $tmpdestination | |
235 | chgrp ${alienSyncFilesGroupOwnership} $tmpdestination | |
236 | ||
237 | # if we didn't download remove the destination in case we tried to redownload | |
238 | # a corrupted file | |
239 | [[ ! -f $tmpdestination ]] && echo "file not downloaded" && rm -f ${destination} && continue | |
240 | ||
241 | downloadOK=0 | |
242 | #verify the downloaded md5 if available, validate otherwise... | |
243 | if [[ -n $md5alien ]]; then | |
c1fbf113 | 244 | md5recalculated=$(checkMD5sum ${tmpdestination}) |
245 | if [[ ${md5alien} == ${md5recalculated} ]]; then | |
d4ab9e58 | 246 | echo "OK md5 after download" |
247 | downloadOK=1 | |
248 | else | |
6c8c572d | 249 | echo "failed verifying md5 $md5alien of $tmpdestination" |
d4ab9e58 | 250 | fi |
251 | else | |
252 | downloadOK=1 | |
253 | fi | |
254 | ||
255 | #handle zip files - check the checksums | |
256 | if [[ $alienFile =~ '.zip' && $downloadOK -eq 1 ]]; then | |
257 | echo "checking integrity of zip archive $tmpdestination" | |
258 | if unzip -t $tmpdestination; then | |
259 | downloadOK=1 | |
260 | else | |
261 | downloadOK=0 | |
262 | fi | |
263 | fi | |
264 | ||
265 | if [[ $downloadOK -eq 1 ]]; then | |
266 | echo mv $tmpdestination ${destination} | |
267 | mv $tmpdestination ${destination} | |
268 | chgrp ${alienSyncFilesGroupOwnership} ${destination} | |
269 | ((downloadedFileCounter++)) | |
270 | if [[ -n $softlinktodestination ]]; then | |
271 | echo ln -s ${destination} $softlinktodestination | |
272 | ln -s ${destination} $softlinktodestination | |
273 | fi | |
274 | [[ -z $redownloading ]] && echo ${destination} >> $newFilesList | |
275 | [[ -n $redownloading ]] && echo ${destination} >> $redoneFilesList | |
276 | if ! grep -q ${destination} $tmp/${localFileList##*/}; then | |
277 | echo ${destination} >> $localFileList | |
278 | fi | |
279 | [[ -n ${postCommand} ]] && ( cd ${destinationdir}; eval "${postCommand}" ) | |
ec825842 | 280 | if grep -q ${alienFile} ${failedDownloadList}; then |
281 | echo "removing ${alienFile} from ${failedDownloadList}" | |
282 | grep -v ${alienFile} ${failedDownloadList} >tmpUpdatedFailed | |
283 | mv tmpUpdatedFailed ${failedDownloadList} | |
284 | fi | |
d4ab9e58 | 285 | else |
286 | echo "download not validated, NOT moving to ${destination}..." | |
6c8c572d | 287 | echo "removing $tmpdestination" |
d4ab9e58 | 288 | rm -f $tmpdestination |
ec825842 | 289 | echo ${alienFile} >> ${failedDownloadList} |
d4ab9e58 | 290 | continue |
291 | fi | |
292 | ||
293 | if [[ $unzipFiles -eq 1 ]]; then | |
200fd0c8 | 294 | echo unzip -o ${destination} -d ${destinationdir} |
295 | unzip -o ${destination} -d ${destinationdir} | |
d4ab9e58 | 296 | fi |
297 | ||
298 | echo | |
299 | done < ${alienFileListCurrent} | |
300 | ||
301 | [[ $alienFileCounter -gt 0 ]] && mv -f $alienFileListCurrent $localAlienDatabase | |
2c39ca2b | 302 | |
303 | echo "${0##*/} DONE" | |
d4ab9e58 | 304 | |
305 | if [[ $allOutputToLog -eq 1 ]]; then | |
306 | exec 1>&6 6>&- | |
307 | fi | |
308 | ||
309 | cat ${newFilesList} ${redoneFilesList} > ${updatedFilesList} | |
2c39ca2b | 310 | |
d4ab9e58 | 311 | echo alienFindCommand: |
312 | echo " $alienFindCommand" | |
313 | echo | |
314 | echo "files on alien: $alienFileCounter" | |
315 | echo "local files before: $localFileCounter" | |
316 | echo "files downloaded: $downloadedFileCounter" | |
317 | echo | |
318 | echo "new files:" | |
319 | echo | |
320 | cat $newFilesList | |
321 | echo | |
322 | echo "redone files:" | |
323 | echo | |
324 | cat $redoneFilesList | |
ec825842 | 325 | echo |
326 | echo | |
327 | ||
328 | #output the list of failed files to stdout, so the cronjob can mail it | |
329 | echo '###############################' | |
330 | echo "failed to download from alien:" | |
331 | echo | |
332 | local tmpfailed=$(mktemp) | |
333 | [[ "$(cat ${failedDownloadList} | wc -l)" -gt 0 ]] && sort ${failedDownloadList} | uniq -c | awk 'BEGIN{print "#tries\t file" }{print $1 "\t " $2}' | tee ${tmpfailed} | |
334 | ||
335 | [[ -n ${MAILTO} ]] && echo $logFile | mail -s "alienSync ${alienFindCommand} done" ${MAILTO} | |
d4ab9e58 | 336 | |
ec825842 | 337 | echo |
338 | echo | |
339 | echo '###############################' | |
340 | echo "eval ${executeEnd}" | |
341 | eval "${executeEnd}" | |
d4ab9e58 | 342 | |
343 | exitScript 0 | |
344 | } | |
345 | ||
346 | exitScript() | |
347 | { | |
348 | echo | |
349 | echo removing $lockFile | |
350 | rm -f $lockFile | |
351 | echo removing $tmp | |
352 | rm -rf $tmp | |
353 | exit $1 | |
354 | } | |
355 | ||
356 | alien_find() | |
357 | { | |
358 | # like a regular alien_find command | |
c1fbf113 | 359 | # output is a list with md5 sums and ctimes |
d4ab9e58 | 360 | executable="$ALIEN_ROOT/api/bin/gbbox find" |
361 | [[ ! -x ${executable% *} ]] && echo "### error, no $executable..." && return 1 | |
362 | [[ -z $logOutputPath ]] && logOutputPath="./" | |
363 | ||
364 | maxCollectionLength=10000 | |
365 | ||
366 | export GCLIENT_COMMAND_MAXWAIT=600 | |
367 | export GCLIENT_COMMAND_RETRY=20 | |
368 | export GCLIENT_SERVER_RESELECT=4 | |
369 | export GCLIENT_SERVER_RECONNECT=2 | |
370 | export GCLIENT_RETRY_DAMPING=1.2 | |
371 | export GCLIENT_RETRY_SLEEPTIME=2 | |
372 | ||
373 | iterationNumber=0 | |
374 | numberOfFiles=$maxCollectionLength | |
375 | rm -f $logOutputPath/alien_find.err | |
376 | while [[ $numberOfFiles -ge $maxCollectionLength && $iterationNumber -lt 100 ]]; do | |
377 | numberOfFiles=0 | |
378 | offset=$((maxCollectionLength*iterationNumber-1)); | |
379 | [[ $offset -lt 0 ]] && offset=0; | |
380 | $executable -x coll -l ${maxCollectionLength} -o ${offset} "$@" 2>>$logOutputPath/alien_find.err \ | |
381 | | while read -a fields; | |
382 | do | |
383 | nfields=${#fields[*]} | |
384 | turl="" | |
385 | md5="" | |
386 | ctime="" | |
387 | size="" | |
388 | for ((x=1;x<=${nfields};x++)); do | |
389 | field=${fields[${x}]} | |
390 | if [[ "${field}" == "md5="* ]]; then | |
391 | eval ${field} | |
392 | fi | |
393 | if [[ "${field}" == "turl="* ]]; then | |
394 | eval ${field} | |
395 | fi | |
396 | if [[ "${field}" == "ctime="* ]]; then | |
397 | eval ${field}" "${fields[((x+1))]} | |
398 | fi | |
399 | if [[ "${field}" == "size="* ]]; then | |
400 | eval ${field}" "${fields[((x+1))]} | |
401 | fi | |
402 | done | |
403 | ctime=$( date -d "${ctime}" +%s 2>/dev/null) | |
404 | [[ -z $md5 ]] && md5="." | |
405 | [[ -n "$turl" ]] && echo "${turl//"alien://"/} ${md5} ${ctime} ${size}" && ((numberOfFiles++)) | |
406 | done | |
407 | ((iterationNumber++)) | |
408 | done | |
409 | return 0 | |
410 | } | |
411 | ||
412 | alien_find_split() | |
413 | { | |
414 | #split the search in sub searches in the subdirectories of the base path | |
415 | basePath=${1} | |
416 | searchTerm=${2} | |
417 | subPathSelection=${3} | |
418 | [[ -z ${subPathSelection} ]] && subPathSelection=".*" | |
419 | gbbox ls ${basePath} 2>/dev/null | \ | |
420 | while read subPath; do | |
421 | [[ ! ${subPath} =~ ${subPathSelection} ]] && continue | |
422 | alien_find ${basePath}/${subPath} ${searchTerm} | |
423 | done | |
424 | } | |
425 | ||
426 | listCollectionContents() | |
427 | { | |
428 | #find the xml collections and print the list of filenames and hashes | |
429 | while read -a fields; do | |
430 | nfields=${#fields[*]} | |
431 | turl="" | |
432 | md5="" | |
433 | ctime="" | |
434 | for ((x=1;x<=${nfields};x++)); do | |
435 | field=${fields[${x}]} | |
436 | if [[ "${field}" == "md5="* ]]; then | |
437 | eval ${field} | |
438 | fi | |
439 | if [[ "${field}" == "turl="* ]]; then | |
440 | eval ${field} | |
441 | fi | |
442 | if [[ "${field}" == "ctime="* ]]; then | |
443 | eval "${field} ${fields[((x+1))]}" | |
444 | fi | |
445 | done | |
446 | ctime=$( date -d "${ctime}" +%s 2>/dev/null) | |
447 | [[ -n "$turl" ]] && echo "${turl//"alien://"/} ${md5} ${ctime}" | |
448 | done < <(catCollections $1 $2 2>/dev/null) | |
449 | } | |
450 | ||
451 | catCollections() | |
452 | { | |
453 | #print the contents of collection(s) | |
454 | if [[ $# -eq 2 ]]; then | |
455 | while read collection; do | |
456 | [[ $collection != "/"*"/"?* ]] && continue | |
457 | gbbox cat $collection | |
458 | done < <(alien_find $1 $2) | |
459 | elif [[ $# -eq 1 ]]; then | |
460 | gbbox cat $1 | |
461 | fi | |
462 | } | |
463 | ||
464 | haveAlienToken() | |
465 | { | |
466 | #only get a new token if the old one expires soon | |
467 | maxExpireTime=$1 | |
468 | [[ -z $maxExpireTime ]] && maxExpireTime=4000 | |
469 | [[ -z $ALIEN_ROOT ]] && echo "no ALIEN_ROOT!" && return 1 | |
470 | now=$(date "+%s") | |
471 | tokenExpirationTime=$($ALIEN_ROOT/api/bin/alien-token-info|grep Expires) | |
472 | tokenExpirationTime=$(date -d "${tokenExpirationTime#*:}" "+%s") | |
473 | secondsToExpire=$(( tokenExpirationTime-now )) | |
474 | if [[ $secondsToExpire -lt $maxExpireTime ]]; then | |
475 | return 1 | |
476 | else | |
477 | echo "token valid for another $secondsToExpire seconds" | |
478 | return 0 | |
479 | fi | |
480 | } | |
481 | ||
482 | copyFromAlien() | |
483 | { | |
484 | #copy the file $1 to $2 using a specified method | |
6c8c572d | 485 | #uses the "timeout" command to make sure the |
d4ab9e58 | 486 | #download processes will not hang forever. |
487 | # | |
d4ab9e58 | 488 | [[ -z $copyTimeout ]] && copyTimeout=600 |
489 | [[ -z $copyTimeoutHard ]] && copyTimeoutHard=1200 | |
490 | src=${1//"alien://"/} | |
491 | src="alien://${src}" | |
492 | dst=$2 | |
493 | if [[ "$copyMethod" == "tfilecp" ]]; then | |
1e600c4f | 494 | if which timeout &>/dev/null; then |
495 | echo timeout $copyTimeout root -b -q "$copyScript(\"$src\",\"$dst\")" | |
496 | timeout $copyTimeout root -b -q "$copyScript(\"$src\",\"$dst\")" | |
497 | else | |
498 | echo root -b -q "$copyScript(\"$src\",\"$dst\")" | |
499 | root -b -q "$copyScript(\"$src\",\"$dst\")" | |
500 | fi | |
d4ab9e58 | 501 | else |
1e600c4f | 502 | if which timeout &>/dev/null; then |
503 | echo timeout $copyTimeout $ALIEN_ROOT/api/bin/alien_cp $src $dst | |
504 | timeout $copyTimeout $ALIEN_ROOT/api/bin/alien_cp $src $dst | |
505 | else | |
506 | echo $ALIEN_ROOT/api/bin/alien_cp $src $dst | |
507 | $ALIEN_ROOT/api/bin/alien_cp $src $dst | |
508 | fi | |
d4ab9e58 | 509 | fi |
510 | } | |
511 | ||
d56eeaab | 512 | parseConfig() |
513 | { | |
514 | #config file | |
515 | configFile="" | |
516 | alienFindCommand="" | |
517 | secondsToSuicide=$(( 10*3600 )) | |
518 | localPathPrefix="${PWD}" | |
4c2b79c1 | 519 | #define alienSync_localPathPrefix in your env to have a default central location |
2c39ca2b | 520 | [[ -n ${alienSync_localPathPrefix} ]] && localPathPrefix=${alienSync_localPathPrefix} |
4c2b79c1 | 521 | logOutputPath="${localPathPrefix}/alienSyncLogs" |
d56eeaab | 522 | unzipFiles=0 |
110208cb | 523 | allOutputToLog=0 |
d56eeaab | 524 | |
525 | args=("$@") | |
526 | ||
527 | #first, check if the config file is configured | |
528 | #is yes - source it so that other options can override it | |
529 | #if any | |
530 | for opt in "${args[@]}"; do | |
531 | if [[ ${opt} =~ configFile=.* ]]; then | |
532 | eval "${opt}" | |
533 | [[ ! -f ${configFile} ]] && echo "configFile ${configFile} not found, exiting..." && return 1 | |
534 | echo "using config file: ${configFile}" | |
535 | source "${configFile}" | |
536 | break | |
537 | fi | |
538 | done | |
539 | ||
540 | #then, parse the options as they override the options from file | |
541 | for opt in "${args[@]}"; do | |
542 | if [[ ! "${opt}" =~ .*=.* ]]; then | |
543 | echo "badly formatted option ${var}, should be: option=value, stopping..." | |
544 | return 1 | |
545 | fi | |
546 | local var="${opt%%=*}" | |
547 | local value="${opt#*=}" | |
548 | echo "${var} = ${value}" | |
549 | export ${var}="${value}" | |
550 | done | |
551 | } | |
552 | ||
c1fbf113 | 553 | checkMD5sum() |
554 | { | |
555 | local file="${1}" | |
556 | local md5="" | |
ce1d3292 | 557 | [[ ! -f ${file} ]] && return 1 |
c1fbf113 | 558 | if which md5sum &>/dev/null; then |
559 | local tmp=($(md5sum ${file})) | |
560 | md5=${tmp[0]} | |
561 | elif which md5 &>/dev/null; then | |
562 | local tmp=($(md5 ${file})) | |
563 | md5=${tmp[3]} | |
564 | fi | |
565 | echo ${md5} | |
566 | } | |
567 | ||
d4ab9e58 | 568 | main "$@" |