Project

General

Profile

glidein_startup.sh

glidein_startup - Marco Mambelli, 07/11/2019 02:09 PM

 
1
#!/bin/bash
2
#
3
# Project:
4
#   glideinWMS
5
#
6
# File Version: 
7
#
8

    
9
# default IFS, to protect against unusual environment, better than "unset IFS" because works with restoring old one
10
IFS=$' \t\n'
11

    
12
global_args="$@"
13
# GWMS_STARTUP_SCRIPT=$0
14
GWMS_STARTUP_SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")"
15

    
16
export LANG=C
17

    
18
function trap_with_arg {
19
    func="$1" ; shift
20
    for sig ; do
21
        trap "$func $sig" "$sig"
22
    done
23
}
24

    
25
#function to handle passing signals to the child processes
26
# no need to re-raise sigint, caller does unconditional exit (https://www.cons.org/cracauer/sigint.html)
27
function on_die {
28
    echo "Received kill signal... shutting down child processes (forwarding $1 signal)" 1>&2
29
    ON_DIE=1
30
    kill -s $1 %1
31
}
32

    
33
GWMS_MULTIGLIDEIN_CHILDS=
34
function on_die_multi {
35
    echo "Multi-Glidein received signal... shutting down child glideins (forwarding $1 signal to $GWMS_MULTIGLIDEIN_CHILDS)" 1>&2
36
    ON_DIE=1
37
    for i in $GWMS_MULTIGLIDEIN_CHILDS; do
38
        kill -s $1 $i
39
    done
40
}
41

    
42
function ignore_signal {
43
    echo "Ignoring SIGHUP signal... Use SIGTERM or SIGQUIT to kill processes" 1>&2
44
}
45

    
46
function warn {
47
    echo `date` "$@" 1>&2
48
}
49

    
50
# Functions to start multiple glideins
51
function copy_all {
52
   # 1:prefix (of the files to skip), 2:directory
53
   # should it copy also hidden files?
54
   mkdir "$2"
55
   for ii in `ls`; do
56
       if [[ "$ii" = ${1}* ]]; then
57
           continue
58
       fi
59
       cp -r "$ii" "$2"/
60
   done
61
}
62

    
63
function do_start_all {
64
    # 1:number of glideins
65
    # GLIDEIN_MULTIGLIDEIN_LAUNCHALL - if set. command to start all Glideins at once (multirestart 0)
66
    # GLIDEIN_MULTIGLIDEIN_LAUNCHER - if set, command to start the individual Glideins
67
    local num_glideins=$1
68
    local initial_dir="$(pwd)"
69
    local startup_script="$GWMS_STARTUP_SCRIPT"
70
    if [[ -n "$GLIDEIN_MULTIGLIDEIN_LAUNCHALL" ]]; then
71
        echo "Starting multi-glidein using launcher: $GLIDEIN_MULTIGLIDEIN_LAUNCHALL"
72
        "$GLIDEIN_MULTIGLIDEIN_LAUNCHALL" "$startup_script" -multirestart 0 $global_args &
73
        GWMS_MULTIGLIDEIN_CHILDS="$GWMS_MULTIGLIDEIN_CHILDS $!"
74
    else
75
        if [[ "$initial_dir" == "$(dirname "$startup_script")" ]]; then
76
            startup_script="./$(basename "$startup_script")"
77
        fi
78
        for i in `seq 1 $num_glideins`; do
79
            g_dir="glidein_dir$i"
80
            copy_all glidein_dir "$g_dir"
81
            echo "Starting glidein $i in $g_dir ${GLIDEIN_MULTIGLIDEIN_LAUNCHER:+"with launcher $GLIDEIN_MULTIGLIDEIN_LAUNCHER"}"
82
            pushd "$g_dir"
83
            chmod +x "$startup_script"
84
            "$GLIDEIN_MULTIGLIDEIN_LAUNCHER" "$startup_script" -multirestart $i $global_args &
85
            GWMS_MULTIGLIDEIN_CHILDS="$GWMS_MULTIGLIDEIN_CHILDS $!"
86
            popd
87
        done
88
    fi
89
}
90

    
91
function usage {
92
    echo "Usage: glidein_startup.sh <options>"
93
    echo "where <options> is:"
94
    echo "  -factory <name>             : name of this factory"
95
    echo "  -name <name>                : name of this glidein"
96
    echo "  -entry <name>               : name of this glidein entry"
97
    echo "  -clientname <name>          : name of the requesting client"
98
    echo "  -clientgroup <name>         : group name of the requesting client"
99
    echo "  -web <baseURL>              : base URL from where to fetch"
100
    echo "  -proxy <proxyURL>           : URL of the local proxy"
101
    echo "  -dir <dirID>                : directory ID (supports ., Condor, CONDOR, OSG, TMPDIR, AUTO)"
102
    echo "  -sign <sign>                : signature of the signature file"
103
    echo "  -signtype <id>              : type of signature (only sha1 supported for now)"
104
    echo "  -signentry <sign>           : signature of the entry signature file"
105
    echo "  -cluster <ClusterID>        : condorG ClusterId"
106
    echo "  -subcluster <ProcID>        : condorG ProcId"
107
    echo "  -submitcredid <CredentialID>: Credential ID of this condorG job"
108
    echo "  -schedd <name>              : condorG Schedd Name"
109
    echo "  -descript <fname>           : description file name"
110
    echo "  -descriptentry <fname>      : description file name for entry"
111
    echo "  -clientweb <baseURL>        : base URL from where to fetch client files"
112
    echo "  -clientwebgroup <baseURL>   : base URL from where to fetch client group files"
113
    echo "  -clientsign <sign>          : signature of the client signature file"
114
    echo "  -clientsigntype <id>        : type of client signature (only sha1 supported for now)"
115
    echo "  -clientsigngroup <sign>     : signature of the client group signature file"
116
    echo "  -clientdescript <fname>     : client description file name"
117
    echo "  -clientdescriptgroup <fname>: client description file name for group"
118
    echo "  -slotslayout <type>         : how Condor will set up slots (fixed, partitionable)"
119
    echo "  -v <id>                     : operation mode (std, nodebug, fast, check supported)"
120
    echo "  -multiglidein <num>         : spawn multiple (<num>) glideins (unless also multirestart is set)"
121
    echo "  -multirestart <num>         : started as one of multiple glideins (glidein number <num>)"
122
    echo "  -param_* <arg>              : user specified parameters"
123
    exit 1
124
}
125

    
126

    
127
# params will contain the full list of parameters
128
# -param_XXX YYY will become "XXX YYY"
129
params=""
130

    
131
while [ $# -gt 0 ]
132
do case "$1" in
133
    -factory)    glidein_factory="$2";;
134
    -name)       glidein_name="$2";;
135
    -entry)      glidein_entry="$2";;
136
    -clientname) client_name="$2";;
137
    -clientgroup) client_group="$2";;
138
    -web)        repository_url="$2";;
139
    -proxy)      proxy_url="$2";;
140
    -dir)        work_dir="$2";;
141
    -sign)       sign_id="$2";;
142
    -signtype)   sign_type="$2";;
143
    -signentry)  sign_entry_id="$2";;
144
    -cluster)    condorg_cluster="$2";;
145
    -subcluster) condorg_subcluster="$2";;
146
    -submitcredid) glidein_cred_id="$2";;
147
    -schedd)     condorg_schedd="$2";;
148
    -descript)   descript_file="$2";;
149
    -descriptentry)   descript_entry_file="$2";;
150
    -clientweb)             client_repository_url="$2";;
151
    -clientwebgroup)        client_repository_group_url="$2";;
152
    -clientsign)            client_sign_id="$2";;
153
    -clientsigntype)        client_sign_type="$2";;
154
    -clientsigngroup)       client_sign_group_id="$2";;
155
    -clientdescript)        client_descript_file="$2";;
156
    -clientdescriptgroup)   client_descript_group_file="$2";;
157
    -slotslayout)           slots_layout="$2";;
158
    -v)          operation_mode="$2";;
159
    -multiglidein)  multi_glidein="$2";;
160
    -multirestart)  multi_glidein_restart="$2";;
161
    -param_*)    params="$params `echo $1 | awk '{print substr($0,8)}'` $2";;
162
    *)  (warn "Unknown option $1"; usage) 1>&2; exit 1
163
esac
164
shift
165
shift
166
done
167

    
168
# make sure we have a valid slots_layout
169
if (echo "x$slots_layout" | grep -i fixed) >/dev/null 2>&1 ; then
170
    slots_layout="fixed"
171
else
172
    slots_layout="partitionable"
173
fi
174

    
175
function python_b64uuencode {
176
    echo "begin-base64 644 -"
177
    python -c 'import binascii,sys;fd=sys.stdin;buf=fd.read();size=len(buf);idx=0
178
while size>57:
179
 print binascii.b2a_base64(buf[idx:idx+57]),;
180
 idx+=57;
181
 size-=57;
182
print binascii.b2a_base64(buf[idx:]),'
183
    echo "===="
184
}
185

    
186
function base64_b64uuencode {
187
    echo "begin-base64 644 -"
188
    base64 -
189
    echo "===="
190
}
191

    
192
# not all WNs have all the tools installed
193
function b64uuencode {
194
    which uuencode >/dev/null 2>&1
195
    if [ $? -eq 0 ]; then
196
        uuencode -m -
197
    else
198
        which base64 >/dev/null 2>&1
199
        if [ $? -eq 0 ]; then
200
            base64_b64uuencode
201
        else
202
            python_b64uuencode
203
        fi
204
    fi
205
}
206

    
207
function construct_xml {
208
  result="$1"
209

    
210
  glidein_end_time=`date +%s`
211

    
212
  echo "<?xml version=\"1.0\"?>
213
<OSGTestResult id=\"glidein_startup.sh\" version=\"4.3.1\">
214
  <operatingenvironment>
215
    <env name=\"cwd\">$start_dir</env>
216
  </operatingenvironment>
217
  <test>
218
    <cmd>$0 ${global_args}</cmd>
219
    <tStart>`date --date=@${startup_time} +%Y-%m-%dT%H:%M:%S%:z`</tStart>
220
    <tEnd>`date --date=@${glidein_end_time} +%Y-%m-%dT%H:%M:%S%:z`</tEnd>
221
  </test>
222
$result
223
</OSGTestResult>"
224
}
225

    
226

    
227
function extract_parent_fname {
228
  exitcode=$1
229

    
230
  if [ -s otrx_output.xml ]; then
231
      # file exists and is not 0 size
232
      last_result=`cat otrx_output.xml`
233
 
234
      if [ "$exitcode" -eq 0 ]; then
235
          echo "SUCCESS"
236
      else
237
          last_script_name=`echo "$last_result" |awk '/<OSGTestResult /{split($0,a,"id=\""); split(a[2],b,"\""); print b[1];}'`
238
          echo ${last_script_name}
239
      fi
240
  else
241
      echo "Unknown" 
242
  fi
243
}
244

    
245
function extract_parent_xml_detail {
246
  exitcode=$1
247
  glidein_end_time=`date +%s`
248

    
249
  if [ -s otrx_output.xml ]; then
250
      # file exists and is not 0 size
251
      last_result=`cat otrx_output.xml`
252
 
253
      if [ "$exitcode" -eq 0 ]; then
254
          echo "  <result>"
255
          echo "    <status>OK</status>"
256
          # propagate metrics as well
257
          echo "$last_result" | grep '<metric '
258
          echo "  </result>"
259
      else
260
          last_script_name=`echo "$last_result" |awk '/<OSGTestResult /{split($0,a,"id=\""); split(a[2],b,"\""); print b[1];}'`
261

    
262
          last_script_reason=`echo "$last_result" | awk 'BEGIN{fr=0;}/<[/]detail>/{fr=0;}{if (fr==1) print $0}/<detail>/{fr=1;}'`
263
          my_reason="     Validation failed in $last_script_name.
264

    
265
$last_script_reason"
266

    
267
          echo "  <result>"
268
          echo "    <status>ERROR</status>
269
    <metric name=\"TestID\" ts=\"`date --date=@${glidein_end_time} +%Y-%m-%dT%H:%M:%S%:z`\" uri=\"local\">$last_script_name</metric>"
270
          # propagate metrics as well (will include the failure metric)
271
          echo "$last_result" | grep '<metric '
272
          echo "  </result>"
273
          echo "  <detail>
274
${my_reason}
275
  </detail>"
276
      fi
277
  else
278
      # create a minimal XML file, else
279
      echo "  <result>"
280
      if [ "$exitcode" -eq 0 ]; then
281
          echo "    <status>OK</status>"
282
      else
283
          echo "    <status>ERROR</status>"
284
          echo "    <metric name=\"failure\" ts=\"`date --date=@${glidein_end_time} +%Y-%m-%dT%H:%M:%S%:z`\" uri=\"local\">Unknown</metric>"
285
      fi
286
      echo "  </result>
287
  <detail>
288
    No detail. Could not find source XML file.
289
  </detail>"
290
  fi
291
}
292

    
293
function basexml2simplexml {
294
  final_result="$1"
295

    
296
  # augment with node info
297
  echo "${final_result}" | awk 'BEGIN{fr=1;}{if (fr==1) print $0}/<operatingenvironment>/{fr=0;}'
298

    
299
  echo "    <env name=\"client_name\">$client_name</env>"
300
  echo "    <env name=\"client_group\">$client_group</env>"
301

    
302
  echo "    <env name=\"user\">`id -un`</env>"
303
  echo "    <env name=\"arch\">`uname -m`</env>"
304
  if [ -e '/etc/redhat-release' ]; then
305
      echo "    <env name=\"os\">`cat /etc/redhat-release`</env>"
306
  fi
307
  echo "    <env name=\"hostname\">`uname -n`</env>"
308

    
309
  echo "${final_result}" | awk 'BEGIN{fr=0;}{if (fr==1) print $0}/<operatingenvironment>/{fr=1;}'
310
}
311

    
312
function simplexml2longxml {
313
  final_result_simple="$1"
314
  global_result="$2"
315

    
316
  echo "${final_result_simple}" | awk 'BEGIN{fr=1;}{if (fr==1) print $0}/<OSGTestResult /{fr=0;}'
317

    
318
  if [ "${global_result}" != "" ]; then
319
      # subtests first, so it is more readable, when tailing
320
      echo '  <subtestlist>'
321
      echo '    <OSGTestResults>'
322
      echo "${global_result}" | awk '{print "      " $0}'
323
      echo '    </OSGTestResults>'
324
      echo '  </subtestlist>'
325
  fi
326

    
327
  echo "${final_result_simple}" | awk 'BEGIN{fr=0;}{if (fr==1) print $0}/<OSGTestResult /{fr=1;}/<operatingenvironment>/{fr=0;}'
328

    
329
  echo "    <env name=\"glidein_factory\">$glidein_factory</env>"
330
  echo "    <env name=\"glidein_name\">$glidein_name</env>"
331
  echo "    <env name=\"glidein_entry\">$glidein_entry</env>"
332
  echo "    <env name=\"condorg_cluster\">$condorg_cluster</env>"
333
  echo "    <env name=\"condorg_subcluster\">$condorg_subcluster</env>"
334
  echo "    <env name=\"glidein_credential_id\">$glidein_cred_id</env>"
335
  echo "    <env name=\"condorg_schedd\">$condorg_schedd</env>"
336

    
337
  echo "${final_result_simple}" | awk 'BEGIN{fr=0;}{if (fr==1) print $0}/<operatingenvironment>/{fr=1;}'
338
}
339

    
340
function print_tail {
341
  exit_code=$1
342
  final_result_simple="$2"
343
  final_result_long="$3"
344

    
345
  glidein_end_time=`date +%s`
346
  let total_time=$glidein_end_time-$startup_time
347
  echo "=== Glidein ending `date` ($glidein_end_time) with code ${exit_code} after $total_time ==="
348
 
349
  echo ""
350
  echo "=== XML description of glidein activity ==="
351
  echo  "${final_result_simple}" | grep -v "<cmd>"
352
  echo "=== End XML description of glidein activity ==="
353

    
354
  echo "" 1>&2
355
  echo "=== Encoded XML description of glidein activity ===" 1>&2
356
  echo "${final_result_long}" | gzip --stdout - | b64uuencode 1>&2
357
  echo "=== End encoded XML description of glidein activity ===" 1>&2
358
}
359

    
360
####################################
361
# Cleaup, print out message and exit
362
work_dir_created=0
363
glide_local_tmp_dir_created=0
364

    
365
# use this for early failures, when we cannot assume we can write to disk at all
366
# too bad we end up with some repeated code, but difficult to do better
367
function early_glidein_failure {
368
  error_msg="$1"
369

    
370
  warn "${error_msg}"
371

    
372
  sleep $sleep_time 
373
  # wait a bit in case of error, to reduce lost glideins
374

    
375
  glidein_end_time=`date +%s`
376
  result="    <metric name=\"failure\" ts=\"`date --date=@${glidein_end_time} +%Y-%m-%dT%H:%M:%S%:z`\" uri=\"local\">WN_RESOURCE</metric>
377
    <status>ERROR</status>
378
    <detail>
379
     $error_msg
380
    </detail>"
381

    
382
  final_result=`construct_xml "$result"`
383
  final_result_simple=`basexml2simplexml "${final_result}"`
384
  # have no global section
385
  final_result_long=`simplexml2longxml "${final_result_simple}" ""`
386
  
387
  cd "$start_dir"
388
  if [ "$work_dir_created" -eq "1" ]; then
389
    rm -fR "$work_dir"
390
  fi
391
  if [ "$glide_local_tmp_dir_created" -eq "1" ]; then
392
    rm -fR "$glide_local_tmp_dir"
393
  fi
394

    
395
  print_tail 1 "${final_result_simple}" "${final_result_long}"
396

    
397
  exit 1
398
}
399

    
400

    
401
# use this one once the most basic ops have been done
402
function glidein_exit {
403
  # lock file for whole machine 
404
  if [ "x$lock_file" != "x" ]; then
405
    rm -f $lock_file
406
  fi
407

    
408
  global_result=""
409
  if [ -f otr_outlist.list ]; then
410
      global_result=`cat otr_outlist.list`
411
      chmod u+w otr_outlist.list
412
  fi
413

    
414
  ge_last_script_name=`extract_parent_fname $1`
415
  result=`extract_parent_xml_detail $1`
416
  final_result=`construct_xml "$result"`
417

    
418
  # augment with node info
419
  final_result_simple=`basexml2simplexml "${final_result}"`
420

    
421
  # Create a richer version, too
422
  final_result_long=`simplexml2longxml "${final_result_simple}" "${global_result}"`
423

    
424
  if [ $1 -ne 0 ]; then
425
      report_failed=`grep -i "^GLIDEIN_Report_Failed " "$glidein_config" | cut -d ' ' -f 2-`
426

    
427
      if [ -z "$report_failed" ]; then
428
          report_failed="NEVER"
429
      fi
430

    
431
      factory_report_failed=`grep -i "^GLIDEIN_Factory_Report_Failed " "$glidein_config" | cut -d ' ' -f 2-`
432

    
433
      if [ -z "$factory_report_failed" ]; then
434
          factory_collector=`grep -i "^GLIDEIN_Factory_Collector " "$glidein_config" | cut -d ' ' -f 2-`
435
          if [ -z "$factory_collector" ]; then
436
              # no point in enabling it if there are no collectors
437
              factory_report_failed="NEVER"
438
          else
439
              factory_report_failed="ALIVEONLY"
440
          fi
441
      fi
442

    
443
      do_report=0
444
      if [ "$report_failed" != "NEVER" ] || [ "$factory_report_failed" != "NEVER" ]; then
445
          do_report=1
446
      fi
447

    
448

    
449
      # wait a bit in case of error, to reduce lost glideins
450
      let "dl=`date +%s` + $sleep_time"
451
      dlf=`date --date="@$dl"`
452
      add_config_line "GLIDEIN_ADVERTISE_ONLY" "1"
453
      add_config_line "GLIDEIN_Failed" "True"
454
      add_config_line "GLIDEIN_EXIT_CODE" "$1"
455
      add_config_line "GLIDEIN_ToDie" "$dl"
456
      add_config_line "GLIDEIN_Expire" "$dl"
457
      add_config_line "GLIDEIN_LAST_SCRIPT" "${ge_last_script_name}"
458
      add_config_line "GLIDEIN_ADVERTISE_TYPE" "Retiring"
459

    
460
      add_config_line "GLIDEIN_FAILURE_REASON" "Glidein failed while running ${ge_last_script_name}. Keeping node busy until $dl ($dlf)."
461

    
462
      condor_vars_file="`grep -i "^CONDOR_VARS_FILE " "$glidein_config" | cut -d ' ' -f 2-`"
463
      if [ -n "${condor_vars_file}" ]; then
464
         # if we are to advertise, this should be available... else, it does not matter anyhow
465
         add_condor_vars_line "GLIDEIN_ADVERTISE_ONLY" "C" "True" "+" "Y" "Y" "-"
466
         add_condor_vars_line "GLIDEIN_Failed" "C" "True" "+" "Y" "Y" "-"
467
         add_condor_vars_line "GLIDEIN_EXIT_CODE" "I" "-" "+" "Y" "Y" "-"
468
         add_condor_vars_line "GLIDEIN_ToDie" "I" "-" "+" "Y" "Y" "-"
469
         add_condor_vars_line "GLIDEIN_Expire" "I" "-" "+" "Y" "Y" "-"
470
         add_condor_vars_line "GLIDEIN_LAST_SCRIPT" "S" "-" "+" "Y" "Y" "-"
471
         add_condor_vars_line "GLIDEIN_FAILURE_REASON" "S" "-" "+" "Y" "Y" "-"
472
      fi
473
      main_work_dir=`get_work_dir main`
474

    
475
      for ((t=`date +%s`; $t<$dl;t=`date +%s`))
476
      do
477
        if [ -e "${main_work_dir}/$last_script" ] && [ "$do_report" = "1" ] ; then
478
            # if the file exists, we should be able to talk to the collectors
479
            # notify that things went badly and we are waiting
480
            if [ "$factory_report_failed" != "NEVER" ]; then
481
                add_config_line "GLIDEIN_ADVERTISE_DESTINATION" "Factory"
482
                warn "Notifying Factory of error"
483
                "${main_work_dir}/$last_script" glidein_config
484
            fi
485
            if [ "$report_failed" != "NEVER" ]; then
486
                add_config_line "GLIDEIN_ADVERTISE_DESTINATION" "VO"
487
                warn "Notifying VO of error"
488
                "${main_work_dir}/$last_script" glidein_config
489
            fi
490
        fi
491

    
492
        # sleep for about 5 mins... but randomize a bit
493
        let "ds=250+$RANDOM%100"
494
        let "as=`date +%s` + $ds"
495
        if [ $as -gt $dl ]; then
496
            # too long, shorten to the deadline
497
            let "ds=$dl - `date +%s`"
498
        fi
499
        warn "Sleeping $ds"
500
        sleep $ds
501
      done
502

    
503
      if [ -e "${main_work_dir}/$last_script" ] && [ "$do_report" = "1" ]; then
504
          # notify that things went badly and we are going away
505
          if [ "$factory_report_failed" != "NEVER" ]; then
506
              add_config_line "GLIDEIN_ADVERTISE_DESTINATION" "Factory"
507
              if [ "$factory_report_failed" = "ALIVEONLY" ]; then
508
                  add_config_line "GLIDEIN_ADVERTISE_TYPE" "INVALIDATE"
509
              else
510
                  add_config_line "GLIDEIN_ADVERTISE_TYPE" "Killing"
511
                  add_config_line "GLIDEIN_FAILURE_REASON" "Glidein failed while running ${ge_last_script_name}. Terminating now. ($dl) ($dlf)"
512
              fi
513
              "${main_work_dir}/$last_script" glidein_config
514
              warn "Last notification sent to Factory"
515
          fi
516
          if [ "$report_failed" != "NEVER" ]; then
517
              add_config_line "GLIDEIN_ADVERTISE_DESTINATION" "VO"
518
              if [ "$report_failed" = "ALIVEONLY" ]; then
519
                  add_config_line "GLIDEIN_ADVERTISE_TYPE" "INVALIDATE"
520
              else
521
                  add_config_line "GLIDEIN_ADVERTISE_TYPE" "Killing"
522
                  add_config_line "GLIDEIN_FAILURE_REASON" "Glidein failed while running ${ge_last_script_name}. Terminating now. ($dl) ($dlf)"
523
              fi
524
              "${main_work_dir}/$last_script" glidein_config
525
              warn "Last notification sent to VO"
526
          fi
527
      fi
528
  fi
529

    
530
  cd "$start_dir"
531
  if [ "$work_dir_created" -eq "1" ]; then
532
    rm -fR "$work_dir"
533
  fi
534
  if [ "$glide_local_tmp_dir_created" -eq "1" ]; then
535
    rm -fR "$glide_local_tmp_dir"
536
  fi
537

    
538
  print_tail $1 "${final_result_simple}" "${final_result_long}"
539

    
540
  exit $1
541
}
542

    
543
####################################################
544
# automatically determine and setup work directories
545
function automatic_work_dir {
546
    targets="$_CONDOR_SCRATCH_DIR $OSG_WN_TMP $TG_NODE_SCRATCH $TG_CLUSTER_SCRATCH $SCRATCH $TMPDIR $TMP $PWD"
547
    unset TMPDIR
548

    
549
    # kb
550
    disk_required=1000000
551

    
552
    for d in $targets; do
553

    
554
        echo "Checking $d for potential use as work space... " 1>&2
555

    
556
        # does the target exist?
557
        if [ ! -e $d ]; then
558
            echo "  Workdir: $d does not exist" 1>&2
559
            continue
560
        fi
561

    
562
        # make sure there is enough available diskspace
563
        #cd $d
564
        free=`df -kP $d | awk '{if (NR==2) print $4}'`
565
        if [ "x$free" = "x" -o $free -lt $disk_required ]; then
566
            echo "  Workdir: not enough disk space available in $d" 1>&2
567
            continue
568
        fi
569

    
570
        if touch $d/.dirtest.$$ >/dev/null 2>&1; then
571
            echo "  Workdir: $d selected" 1>&2
572
            rm -f $d/.dirtest.$$ >/dev/null 2>&1
573
            work_dir=$d
574
            return 0
575
        fi
576
        echo "  Workdir: not allowed to write to $d" 1>&2
577
    done
578
    return 1
579
}
580

    
581

    
582
# Create a script that defines add_config_line
583
#   and add_condor_vars_line
584
# This way other depending scripts can use it
585
# Scripts are executed one at the time (also in schedd_cron)
586
# If this changes, these functions would have to add a locking mechanism
587
function create_add_config_line {
588
    cat > "$1" << EOF
589

    
590
function warn {
591
 echo \`date\` \$@ 1>&2
592
}
593

    
594
###################################
595
# Add a line to the config file
596
# Arg: line to add, first element is the id
597
# Uses global variable glidein_config
598
function add_config_line {
599
    grep -q "^\${*}$" \$glidein_config
600
    if [ \$? -ne 0 ]; then
601
        rm -f \${glidein_config}.old #just in case one was there
602
        mv \$glidein_config \${glidein_config}.old
603
        if [ \$? -ne 0 ]; then
604
            warn "Error renaming \$glidein_config into \${glidein_config}.old"
605
            exit 1
606
        fi
607
        grep -v "^\$1 " \${glidein_config}.old > \$glidein_config
608
        # NOTE that parameters are flattened if not quoted, if there are blanks they are separated by single space
609
        echo "\$@" >> \$glidein_config
610
        rm -f \${glidein_config}.old
611
    fi
612
}
613

    
614
##################################################
615
# Add a line to the config file using a lock file
616
# Replace add_config_line in script_wrapper where multiple instances run in parallel
617
# Uses FD 200, fails after a timeout of 300 sec
618
function add_config_line_safe {
619
    grep -q "^\${*}$" \$glidein_config
620
    if [ \$? -ne 0 ]; then
621
        # when fd is closed the lock is released, no need to trap and remove the file
622
        (
623
        flock -w 300 -e 200 || (warn "Error acquiring lock for glidein_config"; exit 1)
624
        add_config_line "\$@"
625
        ) 200>\${glidein_config}.lock
626
    fi
627
}
628

    
629

    
630

    
631
####################################
632
# Add a line to the condor_vars file
633
# Arg: line to add, first element is the id
634
# Uses global variable condor_vars_file
635
function add_condor_vars_line {
636
    id=\$1
637

    
638
    rm -f \${condor_vars_file}.old #just in case one was there
639
    mv \$condor_vars_file \${condor_vars_file}.old
640
    if [ \$? -ne 0 ]; then
641
        warn "Error renaming \$condor_vars_file into \${condor_vars_file}.old"
642
        exit 1
643
    fi
644
    grep -v "^\$id\b" \${condor_vars_file}.old > \$condor_vars_file
645
    echo "\$@" >> \$condor_vars_file
646
    rm -f \${condor_vars_file}.old
647
}
648
EOF
649
}
650

    
651
# Create a script that defines various id based functions 
652
# This way other depending scripts can use it
653
function create_get_id_selectors {
654
    cat > "$1" << EOF
655
############################################
656
# Get entry/client/group work dir
657
# Arg: type (main/entry/client/client_group)
658
function get_work_dir {
659
    if [ "\$1" = "main" ]; then
660
        grep "^GLIDEIN_WORK_DIR " "\${glidein_config}" | cut -d ' ' -f 2-
661
        return \$?
662
    elif [ "\$1" = "entry" ]; then
663
        grep "^GLIDEIN_ENTRY_WORK_DIR " "\${glidein_config}" | cut -d ' ' -f 2-
664
        return \$?
665
    elif [ "\$1" = "client" ]; then
666
        grep "^GLIDECLIENT_WORK_DIR " "\${glidein_config}" | cut -d ' ' -f 2-
667
        return \$?
668
    elif [ "\$1" = "client_group" ]; then
669
        grep "^GLIDECLIENT_GROUP_WORK_DIR " "\${glidein_config}" | cut -d ' ' -f 2-
670
        return \$?
671
    fi
672
    echo "[get_work_dir] Invalid id: \$1" 1>&2
673
    return 1
674
}
675

    
676
################################################
677
# Get entry/client/group description file name
678
# Arg: type (main/entry/client/client_group)
679
function get_descript_file {
680
    if [ "\$1" = "main" ]; then
681
        grep "^DESCRIPTION_FILE " "\${glidein_config}" | cut -d ' ' -f 2-
682
        return \$?
683
    elif [ "\$1" = "entry" ]; then
684
        grep "^DESCRIPTION_ENTRY_FILE " "\${glidein_config}" | cut -d ' ' -f 2-
685
        return \$?
686
    elif [ "\$1" = "client" ]; then
687
        grep "^GLIDECLIENT_DESCRIPTION_FILE " "\${glidein_config}" | cut -d ' ' -f 2-
688
        return \$?
689
    elif [ "\$1" = "client_group" ]; then
690
        grep "^GLIDECLIENT_DESCRIPTION_GROUP_FILE " "\${glidein_config}" | cut -d ' ' -f 2-
691
        return \$?
692
    fi
693
    echo "[get_descript_file] Invalid id: \$1" 1>&2
694
    return 1
695
}
696

    
697
############################################
698
# Get entry/client/group signature
699
# Arg: type (main/entry/client/client_group)
700
function get_signature {
701
    if [ "\$1" = "main" ]; then
702
        grep "^GLIDEIN_Signature " "\${glidein_config}" | cut -d ' ' -f 2-
703
        return \$?
704
    elif [ "\$1" = "entry" ]; then
705
        grep "^GLIDEIN_Entry_Signature " "\${glidein_config}" | cut -d ' ' -f 2-
706
        return \$?
707
    elif [ "\$1" = "client" ]; then
708
        grep "^GLIDECLIENT_Signature " "\${glidein_config}" | cut -d ' ' -f 2-
709
        return \$?
710
    elif [ "\$1" = "client_group" ]; then
711
        grep "^GLIDECLIENT_Group_Signature " "\${glidein_config}" | cut -d ' ' -f 2-
712
        return \$?
713
    fi
714
    echo "[get_signature] Invalid id: \$1" 1>&2
715
    return 1
716
}
717

    
718
############################################
719
# Get entry/client/group prefix
720
# Arg: type (main/entry/client/client_group)
721
function get_prefix {
722
    if [ "\$1" = "main" ]; then
723
        echo ""
724
    elif [ "\$1" = "entry" ]; then
725
        echo "ENTRY_"
726
    elif [ "\$1" = "client" ]; then
727
        echo "GLIDECLIENT_"
728
    elif [ "\$1" = "client_group" ]; then
729
        echo "GLIDECLIENT_GROUP_"
730
    else
731
        echo "[get_prefix] Invalid id: \$1" 1>&2
732
        return 1
733
    fi
734
}
735

    
736
EOF
737
}
738

    
739
function params_get_simple {
740
    # Retrieve a simple parameter (no special characters in its value) from the param list
741
    # 1:param, 2:param_list (quoted string w/ spaces)
742
    [[ ${2} = *\ ${1}\ * ]] || return
743
    local retval="${2##*\ ${1}\ }"
744
    echo ${retval%%\ *}
745
}
746

    
747
###################################
748
# Put parameters into the config file
749
function params2file {
750
    param_list=""
751

    
752
    while [ $# -gt 0 ]
753
    do
754
       pfval=`echo "$2" | sed\
755
 -e 's/\.nbsp,/ /g'\
756
 -e 's/\.semicolon,/;/g'\
757
 -e 's/\.colon,/:/g'\
758
 -e 's/\.tilde,/~/g'\
759
 -e 's/\.not,/!/g'\
760
 -e 's/\.question,/?/g'\
761
 -e 's/\.star,/*/g'\
762
 -e 's/\.dollar,/$/g'\
763
 -e 's/\.comment,/#/g'\
764
 -e 's/\.sclose,/]/g'\
765
 -e 's/\.sopen,/[/g'\
766
 -e 's/\.gclose,/}/g'\
767
 -e 's/\.gopen,/{/g'\
768
 -e 's/\.close,/)/g'\
769
 -e 's/\.open,/(/g'\
770
 -e 's/\.gt,/>/g'\
771
 -e 's/\.lt,/</g'\
772
 -e 's/\.minus,/-/g'\
773
 -e 's/\.plus,/+/g'\
774
 -e 's/\.eq,/=/g'\
775
 -e "s/\.singquot,/'/g"\
776
 -e 's/\.quot,/"/g'\
777
 -e 's/\.fork,/\`/g'\
778
 -e 's/\.pipe,/|/g'\
779
 -e 's/\.backslash,/\\\/g'\
780
 -e 's/\.amp,/\&/g'\
781
 -e 's/\.comma,/,/g'\
782
 -e 's/\.dot,/./g'`
783
        add_config_line "$1 $pfval"
784
        if [ $? -ne 0 ]; then
785
            glidein_exit 1
786
        fi
787
        if [ -z "$param_list" ]; then
788
            param_list="$1"
789
        else
790
            param_list="${param_list},$1"
791
        fi
792
        shift;shift
793
    done
794
    echo "PARAM_LIST ${param_list}"
795
    return 0
796
}
797

    
798

    
799
################
800
# Parse and verify arguments
801

    
802
# allow some parameters to change arguments
803
# multiglidein GLIDEIN_MULTIGLIDEIN -> multi_glidein
804
tmp_par=`params_get_simple GLIDEIN_MULTIGLIDEIN "$params"`
805
[ -n "$tmp_par" ] &&  multi_glidein=$tmp_par
806

    
807

    
808
set_debug=1
809
sleep_time=1199
810
if [ "$operation_mode" = "nodebug" ]; then
811
 set_debug=0
812
elif [ "$operation_mode" = "fast" ]; then
813
 sleep_time=150
814
 set_debug=1
815
elif [ "$operation_mode" = "check" ]; then
816
 sleep_time=150
817
 set_debug=2
818
fi
819
 
820
if [ -z "$descript_file" ]; then
821
    warn "Missing descript fname." 1>&2
822
    usage
823
fi
824

    
825
if [ -z "$descript_entry_file" ]; then
826
    warn "Missing descript fname for entry." 1>&2
827
    usage
828
fi
829

    
830
if [ -z "$glidein_name" ]; then
831
    warn "Missing gliden name." 1>&2
832
    usage
833
fi
834

    
835
if [ -z "$glidein_entry" ]; then
836
    warn "Missing glidein entry name." 1>&2
837
    usage
838
fi
839

    
840

    
841
if [ -z "$repository_url" ]; then
842
    warn "Missing Web URL." 1>&2
843
    usage
844
fi
845

    
846
repository_entry_url="${repository_url}/entry_${glidein_entry}"
847

    
848
if [ -z "$proxy_url" ]; then
849
  proxy_url="None"
850
fi
851

    
852
if [ "$proxy_url" = "OSG" ]; then
853
  if [ -z "$OSG_SQUID_LOCATION" ]; then
854
     # if OSG does not define a Squid, then don't use any
855
     proxy_url="None"
856
     warn "OSG_SQUID_LOCATION undefined, not using any Squid URL" 1>&2
857
  else
858
     proxy_url=`echo $OSG_SQUID_LOCATION |awk -F ':' '{if ($2 =="") {print $1 ":3128"} else {print $0}}'`
859
  fi
860
fi
861

    
862
if [ -z "$sign_id" ]; then
863
    warn "Missing signature." 1>&2
864
    usage
865
fi
866

    
867
if [ -z "$sign_entry_id" ]; then
868
    warn "Missing entry signature." 1>&2
869
    usage
870
fi
871

    
872
if [ -z "$sign_type" ]; then
873
    sign_type="sha1"
874
fi
875

    
876
if [ "$sign_type" = "sha1" ]; then
877
    sign_sha1="$sign_id"
878
    sign_entry_sha1="$sign_entry_id"
879
else
880
    warn "Unsupported signtype $sign_type found." 1>&2
881
    usage
882
fi
883
    
884
if [ -n "$client_repository_url" ]; then
885
  # client data is optional, user url as a switch
886
  if [ -z "$client_sign_type" ]; then
887
      client_sign_type="sha1"
888
  fi
889

    
890
  if [ "$client_sign_type" = "sha1" ]; then
891
    client_sign_sha1="$client_sign_id"
892
  else
893
    warn "Unsupported clientsigntype $client_sign_type found." 1>&2
894
    usage
895
  fi
896
    
897
  if [ -z "$client_descript_file" ]; then
898
    warn "Missing client descript fname." 1>&2
899
    usage
900
  fi
901

    
902
  if [ -n "$client_repository_group_url" ]; then
903
      # client group data is optional, user url as a switch
904
      if [ -z "$client_group" ]; then
905
          warn "Missing client group name." 1>&2
906
          usage
907
      fi
908

    
909
      if [ -z "$client_descript_group_file" ]; then
910
          warn "Missing client descript fname for group." 1>&2
911
          usage
912
      fi
913

    
914
      if [ "$client_sign_type" = "sha1" ]; then
915
          client_sign_group_sha1="$client_sign_group_id"
916
      else
917
          warn "Unsupported clientsigntype $client_sign_type found." 1>&2
918
          usage
919
      fi
920
  fi
921
fi
922

    
923
function md5wrapper {
924
    # $1 - file name
925
    # $2 - option (quiet)
926
    local ONLY_SUM
927
    if [ "x$2" = "xquiet" ]; then
928
        ONLY_SUM=yes
929
    fi
930
    local executable=md5sum
931
    which $executable 1>/dev/null 2>&1
932
    if [ "$?" -ne 0 ]; then
933
        executable=md5
934
        which $executable 1>/dev/null 2>&1
935
        if [ "$?" -ne 0 ]; then
936
            echo "???"
937
            return 1
938
        fi
939
        [ -n "$ONLY_SUM" ] && executable="md5 -q \"$1\"" || executable="md5 \"$1\""
940
    else
941
        [ -n "$ONLY_SUM" ] && executable="md5sum \"$1\" | cut -d ' ' -f 1" ||  executable="md5sum \"$1\""
942
    fi
943
    local res
944
    # Flagged by some checkers but OK
945
    res="$(eval "$executable" 2>/dev/null)"
946
    if [ $? -ne 0 ]; then
947
        echo "???"
948
        return 1
949
    fi
950
    echo "$res"  
951
}
952

    
953

    
954
startup_time=`date +%s`
955
echo "Starting glidein_startup.sh at `date` ($startup_time)"
956
echo "script_checksum   = '`md5wrapper "$0"`'"
957
echo "debug_mode        = '$operation_mode'"
958
echo "condorg_cluster   = '$condorg_cluster'"
959
echo "condorg_subcluster= '$condorg_subcluster'"
960
echo "condorg_schedd    = '$condorg_schedd'"
961
echo "glidein_credential_id = '$glidein_cred_id'"
962
echo "glidein_factory   = '$glidein_factory'"
963
echo "glidein_name      = '$glidein_name'"
964
echo "glidein_entry     = '$glidein_entry'"
965
if [ -n "$client_name" ]; then
966
    # client name not required as it is not used for anything but debug info
967
    echo "client_name       = '$client_name'"
968
fi
969
if [ -n "$client_group" ]; then
970
    echo "client_group       = '$client_group'"
971
fi
972
echo "work_dir          = '$work_dir'"
973
echo "web_dir           = '$repository_url'"
974
echo "sign_type         = '$sign_type'"
975
echo "proxy_url         = '$proxy_url'"
976
echo "descript_fname    = '$descript_file'"
977
echo "descript_entry_fname = '$descript_entry_file'"
978
echo "sign_id           = '$sign_id'"
979
echo "sign_entry_id     = '$sign_entry_id'"
980
if [ -n "$client_repository_url" ]; then
981
    echo "client_web_dir              = '$client_repository_url'"
982
    echo "client_descript_fname       = '$client_descript_file'"
983
    echo "client_sign_type            = '$client_sign_type'"
984
    echo "client_sign_id              = '$client_sign_id'"
985
    if [ -n "$client_repository_group_url" ]; then
986
        echo "client_web_group_dir        = '$client_repository_group_url'"
987
        echo "client_descript_group_fname = '$client_descript_group_file'"
988
        echo "client_sign_group_id        = '$client_sign_group_id'"
989
    fi
990
fi
991
echo
992
echo "Running on `uname -n`"
993
echo "System: `uname -a`"
994
if [ -e '/etc/redhat-release' ]; then
995
 echo "Release: `cat /etc/redhat-release 2>&1`"
996
fi
997
echo "As: `id`"
998
echo "PID: $$"
999
echo
1000

    
1001
if [ $set_debug -ne 0 ]; then
1002
  echo "------- Initial environment ---------------"  1>&2
1003
  env 1>&2
1004
  echo "------- =================== ---------------" 1>&2
1005
fi
1006

    
1007
# Before anything else, spawn multiple glideins and wait, if asked to do so
1008
if [[ -n "$multi_glidein" ]] && [[ -z "$multi_glidein_restart" ]] && [[ "$multi_glidein" -gt 1 ]]; then
1009
    # start multiple glideins
1010
    ON_DIE=0
1011
    trap 'ignore_signal' SIGHUP
1012
    trap_with_arg 'on_die_multi' SIGTERM SIGINT SIGQUIT
1013
    do_start_all $multi_glidein
1014
    # Wait for all glideins and exit 0
1015
    # TODO: Summarize exit codes and status from all child glideins
1016
    wait
1017
    exit 0
1018
fi
1019

    
1020
########################################
1021
# make sure nobody else can write my files
1022
# In the Grid world I cannot trust anybody
1023
umask 0022
1024
if [ $? -ne 0 ]; then
1025
    early_glidein_failure "Failed in umask 0022"
1026
fi
1027

    
1028
########################################
1029
# Setup OSG and/or Globus
1030
if [ -r "$OSG_GRID/setup.sh" ]; then
1031
    . "$OSG_GRID/setup.sh"
1032
else
1033
  if [ -r "${GLITE_LOCAL_CUSTOMIZATION_DIR}/cp_1.sh" ]; then
1034
    . "${GLITE_LOCAL_CUSTOMIZATION_DIR}/cp_1.sh"
1035
  fi
1036
fi
1037

    
1038
if [ -z "$GLOBUS_PATH" ]; then
1039
  if [ -z "$GLOBUS_LOCATION" ]; then
1040
    # if GLOBUS_LOCATION not defined, try to guess it
1041
    if [ -r "/opt/globus/etc/globus-user-env.sh" ]; then
1042
       GLOBUS_LOCATION=/opt/globus
1043
    elif  [ -r "/osgroot/osgcore/globus/etc/globus-user-env.sh" ]; then
1044
       GLOBUS_LOCATION=/osgroot/osgcore/globus
1045
    else
1046
       warn "GLOBUS_LOCATION not defined and could not guess it." 1>&2
1047
       warn "Looked in:" 1>&2
1048
       warn ' /opt/globus/etc/globus-user-env.sh' 1>&2
1049
       warn ' /osgroot/osgcore/globus/etc/globus-user-env.sh' 1>&2
1050
       warn 'Continuing like nothing happened' 1>&2
1051
    fi
1052
  fi
1053

    
1054
  if [ -r "$GLOBUS_LOCATION/etc/globus-user-env.sh" ]; then
1055
    . "$GLOBUS_LOCATION/etc/globus-user-env.sh"
1056
  else
1057
    warn "GLOBUS_PATH not defined and $GLOBUS_LOCATION/etc/globus-user-env.sh does not exist." 1>&2
1058
    warn 'Continuing like nothing happened' 1>&2
1059
  fi
1060
fi
1061

    
1062
function set_proxy_fullpath {
1063
    # Set the X509_USER_PROXY path to full path to the file
1064
    fullpath="`readlink -f $X509_USER_PROXY`"
1065
    if [ $? -eq 0 ]; then
1066
        echo "Setting X509_USER_PROXY $X509_USER_PROXY to canonical path $fullpath" 1>&2
1067
        export X509_USER_PROXY="$fullpath"
1068
    else
1069
        echo "Unable to get canonical path for X509_USER_PROXY, using $X509_USER_PROXY" 1>&2
1070
    fi
1071
}
1072

    
1073

    
1074
[ -n "$X509_USER_PROXY" ] && set_proxy_fullpath
1075

    
1076
########################################
1077
# prepare and move to the work directory
1078
if [ "$work_dir" = "Condor" ]; then
1079
    work_dir="$_CONDOR_SCRATCH_DIR"
1080
elif [ "$work_dir" = "CONDOR" ]; then
1081
    work_dir="$_CONDOR_SCRATCH_DIR"
1082
elif [ "$work_dir" = "OSG" ]; then
1083
    work_dir="$OSG_WN_TMP"
1084
elif [ "$work_dir" = "TMPDIR" ]; then
1085
    work_dir="$TMPDIR"
1086
elif [ "$work_dir" = "AUTO" ]; then
1087
    automatic_work_dir
1088
elif [ "$work_dir" = "." ]; then
1089
    work_dir=`pwd`
1090
elif [ -z "$work_dir" ]; then
1091
    work_dir=`pwd`
1092
fi
1093

    
1094
if [ -z "$work_dir" ]; then
1095
    early_glidein_failure "Unable to identify Startup dir for the glidein."
1096
fi
1097

    
1098
if [ -e "$work_dir" ]; then
1099
    echo >/dev/null
1100
else
1101
    early_glidein_failure "Startup dir $work_dir does not exist."
1102
fi
1103

    
1104
start_dir=`pwd`
1105
echo "Started in $start_dir"
1106

    
1107
def_work_dir="$work_dir/glide_XXXXXX"
1108
work_dir=`mktemp -d "$def_work_dir"`
1109
if [ $? -ne 0 ]; then
1110
    early_glidein_failure "Cannot create temp '$def_work_dir'"
1111
else
1112
    cd "$work_dir"
1113
    if [ $? -ne 0 ]; then
1114
        early_glidein_failure "Dir '$work_dir' was created but I cannot cd into it."
1115
    else
1116
        echo "Running in $work_dir"
1117
    fi
1118
fi
1119
work_dir_created=1
1120

    
1121
# mktemp makes it user readable by definition (ignores umask)
1122
chmod a+rx "$work_dir"
1123
if [ $? -ne 0 ]; then
1124
    early_glidein_failure "Failed chmod '$work_dir'"
1125
fi
1126

    
1127
def_glide_local_tmp_dir="/tmp/glide_`id -u -n`_XXXXXX"
1128
glide_local_tmp_dir=`mktemp -d "$def_glide_local_tmp_dir"`
1129
if [ $? -ne 0 ]; then
1130
    early_glidein_failure "Cannot create temp '$def_glide_local_tmp_dir'"
1131
fi
1132
glide_local_tmp_dir_created=1
1133

    
1134
# the tmpdir should be world writable
1135
# This way it will work even if the user spawned by the glidein is different
1136
# than the glidein user
1137
chmod 1777 "$glide_local_tmp_dir"
1138
if [ $? -ne 0 ]; then
1139
    early_glidein_failure "Failed chmod '$glide_local_tmp_dir'"
1140
fi
1141

    
1142
glide_tmp_dir="${work_dir}/tmp"
1143
mkdir "$glide_tmp_dir"
1144
if [ $? -ne 0 ]; then
1145
    early_glidein_failure "Cannot create '$glide_tmp_dir'"
1146
fi
1147
# the tmpdir should be world writable
1148
# This way it will work even if the user spawned by the glidein is different
1149
# than the glidein user
1150
chmod 1777 "$glide_tmp_dir"
1151
if [ $? -ne 0 ]; then
1152
    early_glidein_failure "Failed chmod '$glide_tmp_dir'"
1153
fi
1154

    
1155
short_main_dir=main
1156
main_dir="${work_dir}/${short_main_dir}"
1157
mkdir "$main_dir"
1158
if [ $? -ne 0 ]; then
1159
    early_glidein_failure "Cannot create '$main_dir'"
1160
fi
1161

    
1162
short_entry_dir=entry_${glidein_entry}
1163
entry_dir="${work_dir}/${short_entry_dir}"
1164
mkdir "$entry_dir"
1165
if [ $? -ne 0 ]; then
1166
    early_glidein_failure "Cannot create '$entry_dir'"
1167
fi
1168

    
1169
if [ -n "$client_repository_url" ]; then
1170
    short_client_dir=client
1171
    client_dir="${work_dir}/${short_client_dir}"
1172
    mkdir "$client_dir"
1173
    if [ $? -ne 0 ]; then
1174
        early_glidein_failure "Cannot create '$client_dir'"
1175
    fi
1176

    
1177
    if [ -n "$client_repository_group_url" ]; then
1178
        short_client_group_dir=client_group_${client_group}
1179
        client_group_dir="${work_dir}/${short_client_group_dir}"
1180
        mkdir "$client_group_dir"
1181
        if [ $? -ne 0 ]; then
1182
            early_glidein_failure "Cannot create '$client_group_dir'"
1183
        fi
1184
    fi
1185
fi
1186

    
1187
create_add_config_line add_config_line.source
1188
source add_config_line.source
1189

    
1190
create_get_id_selectors get_id_selectors.source
1191
source get_id_selectors.source
1192

    
1193
wrapper_list="$PWD/wrapper_list.lst"
1194
touch "$wrapper_list"
1195

    
1196
# create glidein_config
1197
glidein_config="$PWD/glidein_config"
1198
echo > "$glidein_config"
1199
if [ $? -ne 0 ]; then
1200
    early_glidein_failure "Could not create '$glidein_config'"
1201
fi
1202
echo "# --- glidein_startup vals ---" >> glidein_config
1203
echo "GLIDEIN_Factory $glidein_factory" >> glidein_config
1204
echo "GLIDEIN_Name $glidein_name" >> glidein_config
1205
echo "GLIDEIN_Entry_Name $glidein_entry" >> glidein_config
1206
if [ -n "$client_name" ]; then
1207
    # client name not required as it is not used for anything but debug info
1208
    echo "GLIDECLIENT_Name $client_name" >> glidein_config
1209
fi
1210
if [ -n "$client_group" ]; then
1211
    # client group not required as it is not used for anything but debug info
1212
    echo "GLIDECLIENT_Group $client_group" >> glidein_config
1213
fi
1214
echo "GLIDEIN_CredentialIdentifier $glidein_cred_id" >> glidein_config
1215
echo "CONDORG_CLUSTER $condorg_cluster" >> glidein_config
1216
echo "CONDORG_SUBCLUSTER $condorg_subcluster" >> glidein_config
1217
echo "CONDORG_SCHEDD $condorg_schedd" >> glidein_config
1218
echo "DEBUG_MODE $set_debug" >> glidein_config
1219
echo "GLIDEIN_STARTUP_PID $$" >> glidein_config 
1220
echo "GLIDEIN_WORK_DIR $main_dir" >> glidein_config
1221
echo "GLIDEIN_ENTRY_WORK_DIR $entry_dir" >> glidein_config
1222
echo "TMP_DIR $glide_tmp_dir" >> glidein_config
1223
echo "GLIDEIN_LOCAL_TMP_DIR $glide_local_tmp_dir" >> glidein_config
1224
echo "PROXY_URL $proxy_url" >> glidein_config
1225
echo "DESCRIPTION_FILE $descript_file" >> glidein_config
1226
echo "DESCRIPTION_ENTRY_FILE $descript_entry_file" >> glidein_config
1227
echo "GLIDEIN_Signature $sign_id" >> glidein_config
1228
echo "GLIDEIN_Entry_Signature $sign_entry_id" >> glidein_config
1229
if [ -n "$client_repository_url" ]; then
1230
    echo "GLIDECLIENT_WORK_DIR $client_dir" >> glidein_config
1231
    echo "GLIDECLIENT_DESCRIPTION_FILE $client_descript_file" >> glidein_config
1232
    echo "GLIDECLIENT_Signature $client_sign_id" >> glidein_config
1233
    if [ -n "$client_repository_group_url" ]; then
1234
        echo "GLIDECLIENT_GROUP_WORK_DIR $client_group_dir" >> glidein_config
1235
        echo "GLIDECLIENT_DESCRIPTION_GROUP_FILE $client_descript_group_file" >> glidein_config
1236
        echo "GLIDECLIENT_Group_Signature $client_sign_group_id" >> glidein_config
1237
    fi
1238
fi
1239
echo "ADD_CONFIG_LINE_SOURCE $PWD/add_config_line.source" >> glidein_config
1240
echo "GET_ID_SELECTORS_SOURCE $PWD/get_id_selectors.source" >> glidein_config
1241
echo "WRAPPER_LIST $wrapper_list" >> glidein_config
1242
echo "SLOTS_LAYOUT $slots_layout" >> glidein_config
1243
# Add a line saying we are still initializing
1244
echo "GLIDEIN_INITIALIZED 0" >> glidein_config
1245
# but be optimist, and leave advertise_only for the actual error handling script
1246
echo "GLIDEIN_ADVERTISE_ONLY 0" >> glidein_config
1247
echo "# --- User Parameters ---" >> glidein_config
1248
if [ $? -ne 0 ]; then
1249
    # we should probably be testing all others as well, but this is better than nothing
1250
    early_glidein_failure "Failed in updating '$glidein_config'"
1251
fi
1252
params2file $params
1253

    
1254

    
1255
############################################
1256
# get the proper descript file based on id
1257
# Arg: type (main/entry/client/client_group)
1258
function get_repository_url {
1259
    if [ "$1" = "main" ]; then
1260
        echo $repository_url
1261
    elif [ "$1" = "entry" ]; then
1262
        echo $repository_entry_url
1263
    elif [ "$1" = "client" ]; then
1264
        echo $client_repository_url
1265
    elif [ "$1" = "client_group" ]; then
1266
        echo $client_repository_group_url
1267
    else
1268
        echo "[get_repository_url] Invalid id: $1" 1>&2
1269
        return 1
1270
    fi
1271
}
1272

    
1273
#####################
1274
# Check signature
1275
function check_file_signature {
1276
    cfs_id="$1"
1277
    cfs_fname="$2"
1278

    
1279
    cfs_work_dir=`get_work_dir $cfs_id`
1280

    
1281
    cfs_desc_fname="${cfs_work_dir}/$cfs_fname"
1282
    cfs_signature="${cfs_work_dir}/signature.sha1"
1283

    
1284
    if [ $check_signature -gt 0 ]; then # check_signature is global for simplicity
1285
        tmp_signname="${cfs_signature}_$$_`date +%s`_$RANDOM"
1286
        grep " $cfs_fname$" "$cfs_signature" > $tmp_signname
1287
        if [ $? -ne 0 ]; then
1288
            rm -f $tmp_signname
1289
            echo "No signature for $cfs_desc_fname." 1>&2
1290
        else
1291
            (cd "$cfs_work_dir" && sha1sum -c "$tmp_signname") 1>&2
1292
            cfs_rc=$?
1293
            if [ $cfs_rc -ne 0 ]; then
1294
                $main_dir/error_augment.sh -init
1295
                $main_dir/error_gen.sh -error "check_file_signature" "Corruption" "File $cfs_desc_fname is corrupted." "file" "$cfs_desc_fname" "source_type" "$cfs_id"
1296
                $main_dir/error_augment.sh  -process $cfs_rc "check_file_signature" "$PWD" "sha1sum -c $tmp_signname" "`date +%s`" "`date +%s`"
1297
                $main_dir/error_augment.sh -concat
1298
                warn "File $cfs_desc_fname is corrupted." 1>&2
1299
                rm -f $tmp_signname
1300
                return 1
1301
            fi
1302
            rm -f $tmp_signname
1303
            echo "Signature OK for ${cfs_id}:${cfs_fname}." 1>&2
1304
        fi
1305
    fi
1306
    return 0
1307
}
1308

    
1309
#####################
1310
# Untar support func
1311

    
1312
function get_untar_subdir {
1313
    gus_id="$1"
1314
    gus_fname="$2"
1315

    
1316
    gus_prefix=`get_prefix $gus_id`
1317
    gus_config_cfg="${gus_prefix}UNTAR_CFG_FILE"
1318

    
1319
    gus_config_file="`grep "^$gus_config_cfg " glidein_config | cut -d ' ' -f 2-`"
1320
    if [ -z "$gus_config_file" ]; then
1321
        warn "Error, cannot find '$gus_config_cfg' in glidein_config." 1>&2
1322
        glidein_exit 1
1323
    fi
1324

    
1325
    gus_dir="`grep -i "^$gus_fname " "$gus_config_file" | cut -s -f 2-`"
1326
    if [ -z "$gus_dir" ]; then
1327
        warn "Error, untar dir for '$gus_fname' cannot be empty." 1>&2
1328
        glidein_exit 1
1329
    fi
1330

    
1331
    echo "$gus_dir"
1332
    return 0
1333
}
1334

    
1335
#####################
1336
# Periodic execution support function and global variable
1337
add_startd_cron_counter=0
1338
function add_periodic_script {
1339
    # schedules a script for periodic execution using startd_cron
1340
    # parameters: wrapper full path, period, cwd, executable path (from cwd),
1341
    # config file path (from cwd), ID
1342
    # global variable: add_startd_cron_counter
1343
    #TODO: should it allow for variable number of parameters?
1344
    local include_fname=condor_config_startd_cron_include
1345
    local s_wrapper="$1"
1346
    local s_period_sec="${2}s"
1347
    local s_cwd="$3"
1348
    local s_fname="$4"
1349
    local s_config="$5"
1350
    local s_ffb_id="$6"
1351
    local s_cc_prefix="$7"
1352
    if [ $add_startd_cron_counter -eq 0 ]; then
1353
        # Make sure that no undesired file is there when called for first cron
1354
        rm $include_fname
1355
    fi
1356
    let add_startd_cron_counter=add_startd_cron_counter+1
1357
    local name_prefix=GLIDEIN_PS_
1358
    local s_name="${name_prefix}$add_startd_cron_counter"
1359

    
1360
    # Append the following to the startd configuration
1361
    # Instead of Periodic and Kill wait for completion:
1362
    # STARTD_CRON_DATE_MODE = WaitForExit
1363
    cat >> $include_fname << EOF
1364
STARTD_CRON_JOBLIST = \$(STARTD_CRON_JOBLIST) $s_name
1365
STARTD_CRON_${s_name}_MODE = Periodic
1366
STARTD_CRON_${s_name}_KILL = True
1367
STARTD_CRON_${s_name}_PERIOD = $s_period_sec
1368
STARTD_CRON_${s_name}_EXECUTABLE = $s_wrapper
1369
STARTD_CRON_${s_name}_ARGS = $s_config $s_ffb_id $s_name $s_fname $s_cc_prefix
1370
STARTD_CRON_${s_name}_CWD = $s_cwd
1371
STARTD_CRON_${s_name}_SLOTS = 1
1372
STARTD_CRON_${s_name}_JOB_LOAD = 0.01
1373
EOF
1374
    # NOPREFIX is a keyword for not setting the prefix for all condor attributes
1375
    [ "xNOPREFIX" != "x${s_cc_prefix}" ] && echo "STARTD_CRON_${s_name}_PREFIX = ${s_cc_prefix}" >> $include_fname
1376
    add_config_line "GLIDEIN_condor_config_startd_cron_include" "$include_fname"
1377
    add_config_line "# --- Lines starting with $s_cc_prefix are from priodic scripts ---"
1378
}
1379

    
1380
#####################
1381
# Fetch a single file
1382
#
1383
# Check cWDictFile/FileDictFile for the number and type of parameters (has to be consistent)
1384
function fetch_file_regular {
1385
    fetch_file "$1" "$2" "$2" "regular" 0 "GLIDEIN_PS_" "TRUE" "FALSE"
1386
}
1387

    
1388
function fetch_file {
1389
    if [ $# -gt 8 ]; then
1390
        # For compatibility w/ future versions (add new parameters at the end)
1391
        echo "More then 8 arguments, considering the first 8 ($#/$ifs_str): $*" 1>&2
1392
    elif [ $# -ne 8 ]; then
1393
        if [ $# -eq 7 ]; then
1394
            #TODO: remove in version 3.3
1395
            # For compatibility with past versions (old file list formats)
1396
            # 3.2.13 and older: prefix (par 6) added in #12705, 3.2.14?
1397
            # 3.2.10 and older: period (par 5) added:  fetch_file_try "$1" "$2" "$3" "$4" 0 "GLIDEIN_PS_" "$5" "$6"
1398
            fetch_file_try "$1" "$2" "$3" "$4" "$5" "GLIDEIN_PS_" "$6" "$7"
1399
            if [ $? -ne 0 ]; then
1400
                glidein_exit 1
1401
            fi
1402
            return 0
1403
        fi
1404
        if [ $# -eq 6 ]; then
1405
            # added to maintain compatibility with older (3.2.10) file list format
1406
            #TODO: remove in version 3.3
1407
            fetch_file_try "$1" "$2" "$3" "$4" 0 "GLIDEIN_PS_" "$5" "$6"
1408
            if [ $? -ne 0 ]; then
1409
                glidein_exit 1
1410
            fi
1411
            return 0
1412
        fi
1413
        local ifs_str
1414
        printf -v ifs_str '%q' "$IFS"
1415
        warn "Not enough arguments in fetch_file, 8 expected ($#/$ifs_str): $*" 1>&2
1416
        glidein_exit 1
1417
    fi
1418

    
1419
    fetch_file_try "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8"
1420
    if [ $? -ne 0 ]; then
1421
        glidein_exit 1
1422
    fi
1423
    return 0
1424
}
1425

    
1426
function fetch_file_try {
1427
    fft_id="$1"
1428
    fft_target_fname="$2"
1429
    fft_real_fname="$3"
1430
    fft_file_type="$4"
1431
    fft_period="$5"
1432
    fft_cc_prefix="$6"
1433
    fft_config_check="$7"
1434
    fft_config_out="$8"
1435

    
1436
    if [ "$fft_config_check" = "TRUE" ]; then
1437
        # TRUE is a special case
1438
        fft_get_ss=1
1439
    else
1440
        fft_get_ss=`grep -i "^$fft_config_check " glidein_config | cut -d ' ' -f 2-`
1441
    fi
1442

    
1443
    # TODO: what if fft_get_ss is not 1? nothing? fft_rc is not set but is returned
1444
    if [ "$fft_get_ss" = "1" ]; then
1445
       fetch_file_base "$fft_id" "$fft_target_fname" "$fft_real_fname" "$fft_file_type" "$fft_config_out" "$fft_period" "$fft_cc_prefix"
1446
       fft_rc=$?
1447
    fi
1448

    
1449
    return $fft_rc
1450
}
1451

    
1452
function perform_wget {
1453
    wget_args=("$@")
1454
    arg_len=${#wget_args[@]}
1455
    ffb_url="${wget_args[0]}"
1456
    ffb_repository=$(dirname "$ffb_url")
1457
    ffb_real_fname=$(basename "$ffb_url")
1458
    proxy_url="None"
1459
    for ((i=0; i<arg_len; i++));
1460
    do
1461
        if [ "${wget_args[$i]}" = "--output-document" ]; then
1462
            ffb_tmp_outname=${wget_args[$i+1]}
1463
        fi
1464
        if [ "${wget_args[$i]}" = "--proxy" ]; then
1465
            proxy_url=${wget_args[$i+1]}
1466
        fi
1467
    done
1468
    START=$(date +%s)
1469
    if [ "$proxy_url" != "None" ]; then
1470
        wget_args=(${wget_args[@]:0:$arg_len-2})
1471
        wget_cmd=$(echo "env http_proxy=${proxy_url} wget ${wget_args[@]}"| sed 's/"/\\\"/g')
1472
        wget_resp=$(env http_proxy="$proxy_url" wget "${wget_args[@]}" 2>&1)
1473
        wget_retval=$?
1474
    else
1475
        wget_cmd=$(echo "wget ${wget_args[@]}"| sed 's/"/\\\"/g')
1476
        wget_resp=$(wget "${wget_args[@]}" 2>&1)
1477
        wget_retval=$?
1478
    fi    
1479

    
1480
    if [ $wget_retval -ne 0 ]; then
1481
        wget_version=$(wget --version 2>&1 | head -1)
1482
        warn "$wget_cmd failed. version:$wget_version  exit code $wget_retval stderr: $wget_resp " 
1483
        # cannot use error_*.sh helper functions
1484
        # may not have been loaded yet, and wget fails often
1485
        echo "<OSGTestResult id=\"perform_wget\" version=\"4.3.1\">
1486
  <operatingenvironment>
1487
    <env name=\"cwd\">$PWD</env>
1488
    <env name=\"uname\">$(uname -a)</env>
1489
    <env name=\"release\">$(cat /etc/system-release)</env>
1490
    <env name=\"wget_version\">$wget_version</env>
1491
  </operatingenvironment>
1492
  <test>
1493
    <cmd>$wget_cmd</cmd>
1494
    <tStart>$(date --date=@${START} +%Y-%m-%dT%H:%M:%S%:z)</tStart>
1495
    <tEnd>$(date +%Y-%m-%dT%H:%M:%S%:z)</tEnd>
1496
  </test>
1497
  <result>
1498
    <status>ERROR</status>
1499
    <metric name=\"failure\" ts=\"$(date --date=@${START} +%Y-%m-%dT%H:%M:%S%:z)\" uri=\"local\">Network</metric>
1500
    <metric name=\"URL\" ts=\"$(date --date=@${START} +%Y-%m-%dT%H:%M:%S%:z)\" uri=\"local\">${ffb_url}</metric>
1501
    <metric name=\"http_proxy\" ts=\"$(date --date=@${START} +%Y-%m-%dT%H:%M:%S%:z)\" uri=\"local\">$proxy_url</metric>
1502
    <metric name=\"source_type\" ts=\"$(date --date=@${START} +%Y-%m-%dT%H:%M:%S%:z)\" uri=\"local\">${ffb_id}</metric>
1503
  </result>
1504
  <detail>
1505
  Failed to load file '$ffb_real_fname' from '$ffb_repository' using proxy '$proxy_url'.  $wget_resp
1506
  </detail>
1507
</OSGTestResult>" > otrb_output.xml
1508
        warn "Failed to load file '$ffb_real_fname' from '$ffb_repository'." 
1509

    
1510
        if [ -f otr_outlist.list ]; then
1511
            chmod u+w otr_outlist.list
1512
        else
1513
            touch otr_outlist.list
1514
        fi
1515
        cat otrb_output.xml >> otr_outlist.list
1516
        echo "<?xml version=\"1.0\"?>" > otrx_output.xml
1517
        cat otrb_output.xml >> otrx_output.xml
1518
        rm -f otrb_output.xml
1519
        chmod a-w otr_outlist.list
1520
    fi 
1521
    return $wget_retval
1522
}
1523

    
1524
function perform_curl {
1525
    curl_args=("$@")
1526
    arg_len=${#curl_args[@]}
1527
    ffb_url="${curl_args[0]}"
1528
    ffb_repository=$(dirname "$ffb_url")
1529
    ffb_real_fname=$(basename "$ffb_url")
1530
    for ((i=0; i<arg_len; i++));
1531
    do
1532
        if [ "${curl_args[$i]}" = "--output" ]; then
1533
            ffb_tmp_outname=${curl_args[$i+1]}
1534
        fi
1535
        if [ "${curl_args[$i]}" = "--proxy" ]; then
1536
            proxy_url=${curl_args[$i+1]}
1537
        fi
1538
    done
1539

    
1540
    START=$(date +%s)
1541
    curl_cmd=$(echo "curl ${curl_args[@]}" | sed 's/"/\\\"/g')
1542
    curl_resp=$(curl "${curl_args[@]}" 2>&1)
1543
    curl_retval=$?
1544
    if [ $curl_retval -eq 0 ] && [ ! -e "${ffb_tmp_outname}" ] ; then
1545
        touch "${ffb_tmp_outname}"
1546
    fi
1547

    
1548

    
1549

    
1550
    if [ $curl_retval -ne 0 ]; then
1551
        curl_version=$(curl --version 2>&1 | head -1)
1552
        warn "$curl_cmd failed. version:$curl_version  exit code $curl_retval stderr: $curl_resp " 
1553
        # cannot use error_*.sh helper functions
1554
        # may not have been loaded yet, and wget fails often
1555
        echo "<OSGTestResult id=\"perform_curl\" version=\"4.3.1\">
1556
  <operatingenvironment>
1557
    <env name=\"cwd\">$PWD</env>
1558
    <env name=\"uname\">$(uname -a)</env>
1559
    <env name=\"release\">$(cat /etc/system-release)</env>
1560
    <env name=\"curl_version\">$curl_version</env>
1561
  </operatingenvironment>
1562
  <test>
1563
    <cmd>${curl_cmd}</cmd>
1564
    <tStart>$(date --date=@${START} +%Y-%m-%dT%H:%M:%S%:z)</tStart>
1565
    <tEnd>$(date +%Y-%m-%dT%H:%M:%S%:z)</tEnd>
1566
  </test>
1567
  <result>
1568
    <status>ERROR</status>
1569
    <metric name=\"failure\" ts=\"$(date --date=@${START} +%Y-%m-%dT%H:%M:%S%:z)\" uri=\"local\">Network</metric>
1570
    <metric name=\"URL\" ts=\"$(date --date=@${START} +%Y-%m-%dT%H:%M:%S%:z)\" uri=\"local\">${ffb_url}</metric>
1571
    <metric name=\"http_proxy\" ts=\"$(date --date=@${START} +%Y-%m-%dT%H:%M:%S%:z)\" uri=\"local\">$proxy_url</metric>
1572
    <metric name=\"source_type\" ts=\"$(date --date=@${START} +%Y-%m-%dT%H:%M:%S%:z)\" uri=\"local\">${ffb_id}</metric>
1573
  </result>
1574
  <detail>
1575
  Failed to load file '$ffb_real_fname' from '$ffb_repository' using proxy '$proxy_url'.  ${curl_resp}
1576
  </detail>
1577
</OSGTestResult>" > otrb_output.xml
1578
        warn "Failed to load file '$ffb_real_fname' from '$ffb_repository'." 
1579

    
1580
        if [ -f otr_outlist.list ]; then
1581
            chmod u+w otr_outlist.list
1582
        else
1583
            touch otr_outlist.list
1584
        fi
1585
        cat otrb_output.xml >> otr_outlist.list
1586
        echo "<?xml version=\"1.0\"?>" > otrx_output.xml
1587
        cat otrb_output.xml >> otrx_output.xml
1588
        rm -f otrb_output.xml
1589
        chmod a-w otr_outlist.list
1590
    fi 
1591
    return $curl_retval
1592
}
1593

    
1594
function fetch_file_base {
1595
    ffb_id="$1"
1596
    ffb_target_fname="$2"
1597
    ffb_real_fname="$3"
1598
    ffb_file_type="$4"
1599
    ffb_config_out="$5"
1600
    ffb_period=$6
1601
    # condor cron prefix, used only for periodic executables
1602
    ffb_cc_prefix="$7"
1603

    
1604
    ffb_work_dir=$(get_work_dir "$ffb_id")
1605

    
1606
    ffb_repository=$(get_repository_url "$ffb_id")
1607

    
1608
    ffb_tmp_outname="$ffb_work_dir/$ffb_real_fname"
1609
    ffb_outname="$ffb_work_dir/$ffb_target_fname"
1610
    #these don't appear to be used anywhere
1611
    ffb_desc_fname="$ffb_work_dir/$fname"
1612
    ffb_signature="$ffb_work_dir/signature.sha1"
1613

    
1614

    
1615

    
1616
    # Create a dummy default in case something goes wrong
1617
    # cannot use error_*.sh helper functions
1618
    # may not have been loaded yet
1619
    have_dummy_otrx=1
1620
    echo "<?xml version=\"1.0\"?>
1621
<OSGTestResult id=\"fetch_file_base\" version=\"4.3.1\">
1622
  <operatingenvironment>
1623
    <env name=\"cwd\">$PWD</env>
1624
  </operatingenvironment>
1625
  <test>
1626
    <cmd>Unknown</cmd>
1627
    <tStart>$(date +%Y-%m-%dT%H:%M:%S%:z)</tStart>
1628
    <tEnd>$(date +%Y-%m-%dT%H:%M:%S%:z)</tEnd>
1629
  </test>
1630
  <result>
1631
    <status>ERROR</status>
1632
    <metric name=\"failure\" ts=\"$(date +%Y-%m-%dT%H:%M:%S%:z)\" uri=\"local\">Unknown</metric>
1633
    <metric name=\"source_type\" ts=\"$(date +%Y-%m-%dT%H:%M:%S%:z)\" uri=\"local\">$ffb_id</metric>
1634
  </result>
1635
  <detail>
1636
     An unknown error occured.
1637
  </detail>
1638
</OSGTestResult>" > otrx_output.xml
1639
    user_agent="glidein/$glidein_entry/$condorg_schedd/$condorg_cluster.$condorg_subcluster/$client_name"
1640
    ffb_url="$ffb_repository/$ffb_real_fname"
1641
    curl_version=$(curl --version | head -1 )
1642
    wget_version=$(wget --version | head -1 )
1643
    #old wget command: 
1644
    #wget --user-agent="wget/glidein/$glidein_entry/$condorg_schedd/$condorg_cluster.$condorg_subcluster/$client_name" "$ffb_nocache_str" -q  -O "$ffb_tmp_outname" "$ffb_repository/$ffb_real_fname"
1645
    #equivalent to: 
1646
    #wget ${ffb_url} --user-agent=${user_agent} -q  -O "${ffb_tmp_outname}" "${ffb_nocache_str}"
1647
    #with env http_proxy=$proxy_url set if proxy_url != "None"
1648
    #
1649
    #construct curl equivalent so we can try either
1650

    
1651
    wget_args=("${ffb_url}" "--user-agent" "wget/${user_agent}"  "--quiet"  "--output-document" "${ffb_tmp_outname}" )
1652
    curl_args=("${ffb_url}" "--user-agent" "curl/${user_agent}" "--silent"  "--show-error" "--output" "${ffb_tmp_outname}")
1653

    
1654
    if [ "$ffb_file_type" = "nocache" ]; then
1655
        if [ "$curl_version" != "" ]; then
1656
            curl_args+=("--header")
1657
            curl_args+=("'Cache-Control: no-cache'")
1658
        fi
1659
        if [ "$wget_version" != "" ]; then
1660
            if wget --help | grep -q "\-\-no-cache "; then
1661
                wget_args+=("--no-cache")
1662
            elif wget --help |grep -q "\-\-cache="; then
1663
                wget_args+=("--cache=off")
1664
            else
1665
                warn "wget $wget_version cannot disable caching" 
1666
            fi
1667
         fi    
1668
    fi
1669

    
1670
    if [ "$proxy_url" != "None" ];then
1671
        if [ "$curl_version" != "" ]; then
1672
            curl_args+=("--proxy")
1673
            curl_args+=("$proxy_url")
1674
        fi
1675
        if [ "$wget_version" != "" ]; then
1676
            #these two arguments have to be last as coded, put any future
1677
            #wget args earlier in wget_args array
1678
            wget_args+=("--proxy")
1679
            wget_args+=("$proxy_url")
1680
        fi
1681
    fi
1682

    
1683
    fetch_completed=1
1684
    if [ $fetch_completed -ne 0 ] && [ "$wget_version" != "" ]; then
1685
        perform_wget "${wget_args[@]}"
1686
        fetch_completed=$?
1687
    fi
1688
    if [ $fetch_completed -ne 0 ] && [ "$curl_version" != "" ]; then
1689
        perform_curl "${curl_args[@]}"
1690
        fetch_completed=$?
1691
    fi
1692

    
1693
    if [ $fetch_completed -ne 0 ]; then
1694
        return $fetch_completed
1695
    fi
1696
    # check signature
1697
    check_file_signature "$ffb_id" "$ffb_real_fname"
1698
    if [ $? -ne 0 ]; then
1699
        # error already displayed inside the function
1700
        return 1
1701
    fi
1702

    
1703
    # rename it to the correct final name, if needed
1704
    if [ "$ffb_tmp_outname" != "$ffb_outname" ]; then
1705
        mv "$ffb_tmp_outname" "$ffb_outname"
1706
        if [ $? -ne 0 ]; then
1707
            warn "Failed to rename $ffb_tmp_outname into $ffb_outname" 
1708
            return 1
1709
        fi
1710
    fi
1711

    
1712
    # if executable, execute
1713
    if [ "$ffb_file_type" = "exec" ]; then
1714
        chmod u+x "$ffb_outname"
1715
        if [ $? -ne 0 ]; then
1716
            warn "Error making '$ffb_outname' executable" 1>&2
1717
            return 1
1718
        fi
1719
        if [ "$ffb_id" = "main" -a "$ffb_target_fname" = "$last_script" ]; then # last_script global for simplicity
1720
            echo "Skipping last script $last_script" 1>&2
1721
        else
1722
            echo "Executing $ffb_outname"
1723
            # have to do it here, as this will be run before any other script
1724
            chmod u+rx $main_dir/error_augment.sh
1725

    
1726
            # the XML file will be overwritten now, and hopefully not an error situation
1727
            have_dummy_otrx=0
1728
            $main_dir/error_augment.sh -init
1729
            START=$(date +%s)
1730
            "$ffb_outname" glidein_config "$ffb_id"
1731
            ret=$?
1732
            END=$(date +%s)
1733
            $main_dir/error_augment.sh  -process $ret "$ffb_id/$ffb_target_fname" "$PWD" "$ffb_outname glidein_config" "$START" "$END" #generating test result document
1734
            $main_dir/error_augment.sh -concat
1735
            if [ $ret -ne 0 ]; then
1736
                echo "=== Validation error in $ffb_outname ===" 1>&2
1737
                warn "Error running '$ffb_outname'" 1>&2
1738
                cat otrx_output.xml | awk 'BEGIN{fr=0;}/<[/]detail>/{fr=0;}{if (fr==1) print $0}/<detail>/{fr=1;}' 1>&2
1739
                return 1
1740
            else
1741
                # If ran successfully and periodic, schedule to execute with schedd_cron
1742
                echo "=== validation OK in $ffb_outname ($ffb_period) ===" 1>&2
1743
                if [ $ffb_period -gt 0 ]; then
1744
                    add_periodic_script "$main_dir/script_wrapper.sh" $ffb_period "$work_dir" "$ffb_outname" glidein_config "$ffb_id" "$ffb_cc_prefix"
1745
                fi
1746
            fi
1747
        fi
1748
    elif [ "$ffb_file_type" = "wrapper" ]; then
1749
        echo "$ffb_outname" >> "$wrapper_list"
1750
    elif [ "$ffb_file_type" = "untar" ]; then
1751
        ffb_short_untar_dir=`get_untar_subdir "$ffb_id" "$ffb_target_fname"`
1752
        ffb_untar_dir="${ffb_work_dir}/${ffb_short_untar_dir}"
1753
        START=`date +%s`
1754
        (mkdir "$ffb_untar_dir" && cd "$ffb_untar_dir" && tar -xmzf "$ffb_outname") 1>&2
1755
        ret=$?
1756
        if [ $ret -ne 0 ]; then
1757
            $main_dir/error_augment.sh -init
1758
            $main_dir/error_gen.sh -error "tar" "Corruption" "Error untarring '$ffb_outname'" "file" "$ffb_outname" "source_type" "$cfs_id"
1759
            $main_dir/error_augment.sh  -process $cfs_rc "tar" "$PWD" "mkdir $ffb_untar_dir && cd $ffb_untar_dir && tar -xmzf $ffb_outname" "$START" "`date +%s`"
1760
            $main_dir/error_augment.sh -concat
1761
            warn "Error untarring '$ffb_outname'" 1>&2
1762
            return 1
1763
        fi
1764
    fi
1765

    
1766
    if [ "$ffb_config_out" != "FALSE" ]; then
1767
        ffb_prefix=`get_prefix $ffb_id`
1768
        if [ "$ffb_file_type" = "untar" ]; then
1769
            # when untaring the original file is less interesting than the untar dir
1770
            add_config_line "${ffb_prefix}${ffb_config_out}" "$ffb_untar_dir"
1771
            if [ $? -ne 0 ]; then
1772
                glidein_exit 1
1773
            fi
1774
        else
1775
            add_config_line "${ffb_prefix}${ffb_config_out}" "$ffb_outname"
1776
            if [ $? -ne 0 ]; then
1777
                glidein_exit 1
1778
            fi
1779
        fi
1780
    fi
1781

    
1782
    if [ "$have_dummy_otrx" -eq 1 ]; then
1783
        # noone should really look at this file, but just to avoid confusion
1784
        echo "<?xml version=\"1.0\"?>
1785
<OSGTestResult id=\"fetch_file_base\" version=\"4.3.1\">
1786
  <operatingenvironment>
1787
    <env name=\"cwd\">$PWD</env>
1788
  </operatingenvironment>
1789
  <test>
1790
    <cmd>Unknown</cmd>
1791
    <tStart>`date +%Y-%m-%dT%H:%M:%S%:z`</tStart>
1792
    <tEnd>`date +%Y-%m-%dT%H:%M:%S%:z`</tEnd>
1793
  </test>
1794
  <result>
1795
    <status>OK</status>
1796
  </result>
1797
</OSGTestResult>" > otrx_output.xml
1798
    fi
1799

    
1800
   return 0
1801
}
1802

    
1803
echo "Downloading files from Factory and Frontend"
1804

    
1805
#####################################
1806
# Fetch descript and signature files
1807

    
1808
# disable signature check before I get the signature file itself
1809
# check_signature is global
1810
check_signature=0
1811

    
1812
for gs_id in main entry client client_group
1813
do
1814
  if [ -z "$client_repository_url" ]; then
1815
      if [ "$gs_id" = "client" ]; then
1816
          # no client file when no cilent_repository
1817
          continue
1818
      fi
1819
  fi
1820
  if [ -z "$client_repository_group_url" ]; then
1821
      if [ "$gs_id" = "client_group" ]; then
1822
          # no client group file when no cilent_repository_group
1823
          continue
1824
      fi
1825
  fi
1826

    
1827
  gs_id_work_dir=`get_work_dir $gs_id`
1828

    
1829
  # Fetch description file
1830
  gs_id_descript_file=`get_descript_file $gs_id`
1831
  fetch_file_regular "$gs_id" "$gs_id_descript_file"
1832
  signature_file_line="`grep "^signature " "${gs_id_work_dir}/${gs_id_descript_file}"`"
1833
  if [ $? -ne 0 ]; then
1834
      warn "No signature in description file ${gs_id_work_dir}/${gs_id_descript_file}." 1>&2
1835
      glidein_exit 1
1836
  fi
1837
  signature_file="`echo "$signature_file_line" | cut -s -f 2-`"
1838

    
1839
  # Fetch signature file
1840
  gs_id_signature=`get_signature $gs_id`
1841
  fetch_file_regular "$gs_id" "$signature_file"
1842
  echo "$gs_id_signature  ${signature_file}">"${gs_id_work_dir}/signature.sha1.test"
1843
  (cd "${gs_id_work_dir}"&&sha1sum -c signature.sha1.test) 1>&2
1844
  if [ $? -ne 0 ]; then
1845
      warn "Corrupted signature file '${gs_id_work_dir}/${signature_file}'." 1>&2
1846
      glidein_exit 1
1847
  fi
1848
  # for simplicity use a fixed name for signature file
1849
  mv "${gs_id_work_dir}/${signature_file}" "${gs_id_work_dir}/signature.sha1"
1850
done
1851

    
1852
# re-enable for everything else
1853
check_signature=1
1854

    
1855
# Now verify the description was not tampered with
1856
# doing it so late should be fine, since nobody should have been able
1857
# to fake the signature file, even if it faked its name in
1858
# the description file
1859
for gs_id in main entry client client_group
1860
do
1861
  if [ -z "$client_repository_url" ]; then
1862
      if [ "$gs_id" = "client" ]; then
1863
          # no client file when no cilent_repository
1864
          continue
1865
      fi
1866
  fi
1867
  if [ -z "$client_repository_group_url" ]; then
1868
      if [ "$gs_id" = "client_group" ]; then
1869
          # no client group file when no cilent_repository_group
1870
          continue
1871
      fi
1872
  fi
1873

    
1874
  gs_id_descript_file="`get_descript_file $gs_id`"
1875
  check_file_signature "$gs_id" "$gs_id_descript_file"
1876
  if [ $? -ne 0 ]; then
1877
      gs_id_work_dir="`get_work_dir $gs_id`"
1878
      warn "Corrupted description file ${gs_id_work_dir}/${gs_id_descript_file}." 1>&2
1879
      glidein_exit 1
1880
  fi
1881
done
1882

    
1883
###################################################
1884
# get last_script, as it is used by the fetch_file
1885
gs_id_work_dir="`get_work_dir main`"
1886
gs_id_descript_file="`get_descript_file main`"
1887
last_script="`grep "^last_script " "${gs_id_work_dir}/$gs_id_descript_file" | cut -s -f 2-`"
1888
if [ -z "$last_script" ]; then
1889
    warn "last_script not in description file ${gs_id_work_dir}/$gs_id_descript_file." 1>&2
1890
    glidein_exit 1
1891
fi
1892

    
1893

    
1894
##############################
1895
# Fetch all the other files
1896
for gs_file_id in "main file_list" "client preentry_file_list" "client_group preentry_file_list" "client aftergroup_preentry_file_list" "entry file_list" "client file_list" "client_group file_list" "client aftergroup_file_list" "main after_file_list"
1897
do
1898
  gs_id=`echo $gs_file_id |awk '{print $1}'`
1899

    
1900
  if [ -z "$client_repository_url" ]; then
1901
      if [ "$gs_id" = "client" ]; then
1902
          # no client file when no client_repository
1903
          continue
1904
      fi
1905
  fi
1906
  if [ -z "$client_repository_group_url" ]; then
1907
      if [ "$gs_id" = "client_group" ]; then
1908
          # no client group file when no client_repository_group
1909
          continue
1910
      fi
1911
  fi
1912

    
1913
  gs_file_list_id=`echo $gs_file_id |awk '{print $2}'`
1914
  
1915
  gs_id_work_dir=`get_work_dir $gs_id`
1916
  gs_id_descript_file=`get_descript_file $gs_id`
1917
  
1918
  # extract list file name
1919
  gs_file_list_line="`grep "^$gs_file_list_id " "${gs_id_work_dir}/$gs_id_descript_file"`"
1920
  if [ $? -ne 0 ]; then
1921
      if [ -z "$client_repository_group_url" ]; then
1922
          if [ "${gs_file_list_id:0:11}" = "aftergroup_" ]; then
1923
              # afterfile_.. files optional when no client_repository_group
1924
              continue
1925
          fi
1926
      fi
1927
      warn "No '$gs_file_list_id' in description file ${gs_id_work_dir}/${gs_id_descript_file}." 1>&2
1928
      glidein_exit 1
1929
  fi
1930
  # space+tab separated file with multiple elements (was: awk '{print $2}', not safe for spaces in file name)
1931
  gs_file_list="`echo "$gs_file_list_line" | cut -s -f 2 | sed -e 's/[[:space:]]*$//'`"
1932

    
1933
  # fetch list file
1934
  fetch_file_regular "$gs_id" "$gs_file_list"
1935

    
1936
  # Fetch files contained in list
1937
  while read file
1938
    do
1939
    if [ "${file:0:1}" != "#" ]; then
1940
      fetch_file "$gs_id" $file
1941
    fi
1942
  done < "${gs_id_work_dir}/${gs_file_list}"
1943

    
1944
done
1945

    
1946
###############################
1947
# Start the glidein main script
1948
add_config_line "GLIDEIN_INITIALIZED" "1"
1949

    
1950
echo "# --- Last Script values ---" >> glidein_config
1951
last_startup_time=`date +%s`
1952
let validation_time=$last_startup_time-$startup_time
1953
echo "=== Last script starting `date` ($last_startup_time) after validating for $validation_time ==="
1954
echo
1955
ON_DIE=0
1956
trap 'ignore_signal' SIGHUP
1957
trap_with_arg 'on_die' SIGTERM SIGINT SIGQUIT
1958
#trap 'on_die' TERM
1959
#trap 'on_die' INT
1960
gs_id_work_dir=`get_work_dir main`
1961
$main_dir/error_augment.sh -init
1962
"${gs_id_work_dir}/$last_script" glidein_config &
1963
wait $!
1964
ret=$?
1965
if [ $ON_DIE -eq 1 ]; then
1966
        ret=0
1967
fi
1968
last_startup_end_time=`date +%s`
1969
$main_dir/error_augment.sh  -process $ret "$last_script" "$PWD" "${gs_id_work_dir}/$last_script glidein_config" "$last_startup_time" "$last_startup_end_time"
1970
$main_dir/error_augment.sh -concat
1971

    
1972
let last_script_time=$last_startup_end_time-$last_startup_time
1973
echo "=== Last script ended `date` ($last_startup_end_time) with code $ret after $last_script_time ==="
1974
echo
1975
if [ $ret -ne 0 ]; then
1976
    warn "Error running '$last_script'" 1>&2
1977
fi
1978

    
1979
#Things like periodic scripts might put messages here if they want them printed in the logfile
1980
echo "=== Exit messages left by periodic scripts ===" 1>&2
1981
cat exit_message 1>&2
1982
echo 1>&2
1983

    
1984

    
1985
#########################
1986
# clean up after I finish
1987
glidein_exit $ret