File: wrapper_lib.sh

package info (click to toggle)
ncbi-tools6 6.1.20120620-8
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 241,628 kB
  • ctags: 101,236
  • sloc: ansic: 1,431,713; cpp: 6,248; pascal: 3,949; xml: 3,390; sh: 3,090; perl: 1,077; csh: 488; makefile: 449; ruby: 93; lisp: 81
file content (355 lines) | stat: -rw-r--r-- 8,230 bytes parent folder | download | duplicates (13)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
#! /bin/sh
#
# $Id: wrapper_lib.sh,v 6.11 2000/02/10 19:14:19 zimmerma Exp $
#
# this is CGI handler wrapper library. It works as a membrane between httpd and actual
# cgi program and allow to run new technological version of such program in
# parallel to old one and compare results in "real life" condition.
#

atexit() {
    rm -rf $TMPdir
}

basic_settings() {
    basename=`basename $progname | sed 's/[.][^.]*//g'`
    TMPtop=/tmp/$basename
    if [ "x$THEvictim" = x ]; then
        THEvictim="kimelman zimmerma"
    fi
    while [ -d $TMPtop -a ! -w $TMPtop ]; 
    do
        TMPtop="${TMPtop}.A"
    done
    if [ ! -d $TMPtop ]; then
        mkdir -p $TMPtop
        chmod a+rw $TMPtop
    fi
    TMPdir=$TMPtop/$$
    awk_prg=$TMPtop/awkp
    if [ ! -d $TMPdir ]; then
        mkdir -p $TMPdir 
        chmod a+rw $TMPdir
    fi

    trap atexit 0 1 15 9 
}

res_name() {
  res_fname=${TMPdir}/`echo "$1" | tr '/.' '__'`
  dir=`dirname $res_fname`
  [ -d  $dir ] || mkdir -p $dir
}

run_cgi() {
  res_name $1
  case $1 in 
  /* ) 
      prg="$1"
      ;;
  *) 
      prg="$progdir/$1"
      ;;
  esac
  [ x$stats = x ] || timep="/usr/bin/time -p"
  (
     trap '' 0 1 15 9
     cd `dirname $prg`
     $timep ./`basename $prg` $options <$input_file >$res_fname 2>$res_fname.2
  )  &
  waitedID="$waitedID $!"
}

proc_res() {
  res_name $1
  fn=`basename $res_fname`
  # echo "proc_res: $1 --> $fn"
  if [ "x$rcode" != x -a $rcode -eq 0 -a x$stats != x ]; then
    timing
  fi
}

prestart_checks() {
  httpdenv_check_and_fix
  # check sybase settings
  if [ -f ${progdir}/st_configure.sh ] ; then
    if [ x$stats != x ] ; then
        sybase_settings_fname=`dirname $stats`/.syb_set
    fi
    . ${progdir}/st_configure.sh
  fi
}

run_one() {
    texec=$1
    res_name $texec
    if true ; then
        input_file=$res_fname.in
        cat >$input_file
        rf=$res_fname
        $texec $options 2>$res_fname.2 >$rf <$input_file
	rcode=$?
        cat $rf
    else
        rf=/dev/null
        $texec $options 2>$res_fname.2
	rcode=$?        
    fi

    if [ $rcode -ne 0 ] ; then 
      report_failure $texec $rcode $rf $res_fname.2
    fi
}

run_2plus() {
    # stage A : store input stream
    res_name input
    input_file=$res_fname
    cat >$input_file

    #
    # run all cgi programs in parallel
    #

    for texec in $EXECs ; do
        run_cgi $texec
    done

    #
    # wait for termination of all of them
    #
    main_result=
    main_result_rc=0

    for execname in $EXECs ; do # for every runned version of cgi program
        # get it's process id
        set -- $waitedID
        wid=$1 ; shift ; waitedID="$*"
        
        wait $wid            # wait for it to complete
        rcode=$?             # end get it return code and 
        proc_res $execname   # and process the result
        if [ $rcode -ne 0 ] ; then 
            # report mmdbsrv.REAL failure
            report_failure $execname $rcode $res_fname $res_fname.2
            main_result_rc=$rcode
            continue
        fi
        if [ x$main_result = x ] ; then
            main_result=$res_fname
            # output result of first program
            cat $main_result
            main_result_rc=0
            continue
        fi
        # here we have: a: 0 result code & more than 1 output 
        # compare results now
        diff -c $main_result $res_fname >$res_fname.diff
        if [ $? -gt 0 ] ; then
            report_failure $execname $rcode $res_fname.diff $res_fname.2
        fi
    done
    if [ x$main_result = x -a $main_result_rc = 158 ] ; then
        printf "Content-type: text/html\n\n"
        printf "<HTML><BODY bgcolor=\"#FDA51F\" color=\"#000000\">\n"
        printf "<PRE>\n"
        printf "Your request exceeded maximum allowed CPU usage.<BR>\n"
        printf "Please, return back and make smaller request.<BR>\n"
        printf "</PRE>\n"
        printf "</BODY></HTML>\n"
    fi
}

run_all() {

    # stage 0 : 
    check_executables $*

    prestart_checks

    if [ `echo $EXECs | wc -w ` -eq 1 ] ; then 
        run_one $EXECs
    else
        run_2plus
    fi
}

#
# gather timing statistics.
#

do_timing() {
    STATs_to_try="$*"
    [ "x$STATs_to_try" != x ] || STATs_to_try="./stats.$basename log/stats.$basename"
    for stats_file in $STATs_to_try ; do
       if [ -w `dirname $stats_file` ]; then
         stats=$stats_file
         break
       fi
    done
}

create_stats_prog() {
cat >$awk_prg <<EOF
BEGIN   { real=0 ; user=0 ; sys=0 ; cnt=0 ; }
/real/  { real=\$2 }
/user/  { user=\$2 }
/sys/   { sys=\$2  }
        { if ( \$1 == fn ) { cnt=\$5 ; real+=\$2 * cnt ;  user+=\$3 *cnt ; sys +=\$4 * cnt ;  } }
END     { cnt+=1 ; print fn, real/cnt, user/cnt, sys/cnt, cnt }
EOF
}

timing() {
    dd=$$
    while [ -f $stats.lock ] ; do sleep 1 ; done
    echo $dd >$stats.lock
    if [ -f $stats.lock -a "$dd" != "`cat $stats.lock`" ] ; then
        report_lock_problem
    fi
    [ -f $stats ] || echo '! Stats file' >$stats
    grep -v "^$fn " $stats > $res_fname.3
    grep "^$fn " $stats | cat $res_fname.2 -  >$res_fname.4
    if [ ! -r $awk_prg ] ; then
        create_stats_prog
    fi
    nawk -v fn=$fn -f $awk_prg $res_fname.4 >>$res_fname.3
    rm -f $stats
    cat $res_fname.3 >$stats
    chmod a+w $stats
    rm $res_fname.3
    [ ! -f ${stats}.lock ] || rm ${stats}.lock
}

#
#  CHECK & REPORT functions  
#
#

# get aname of person who should got bug reports
get_victim() { # (filename)
    victim=
    [ "x$1" = x ] || victim="`ls -l $1 | awk '  { print $3 ; }'`"
    [ "x$victim" != xpubmed ] || victim=""
    [ "x$victim" != x ] || [ ! -r $1.recepient ] || victim="`cat $1.recepients`"
    [ "x$victim" != x ] || [ ! -r .mail_recepients ] || victim="`cat .mail_recepients`"
    [ "x$victim" != x ] || victim="$THEvictim"
}

httpdenv_check_and_fix() { # check environment & fix required but unset env vars.
    # especially useful in case of debug environment
    if [ "x$REMOTE_ADDR" = x ] ; then
        REMOTE_ADDR=127.0.0.1
        export REMOTE_PORT
    fi
    if [ "x$REMOTE_HOST" = x ] ; then
        REMOTE_HOST=localhost
        export REMOTE_HOST
    fi
    if [ "x$REMOTE_PORT" = x ] ; then
        REMOTE_PORT=0
        export REMOTE_ADDR
    fi
    if [ "x$HTTP_USER_AGENT" = x ] ; then
        HTTP_USER_AGENT="pseudo agent : $progname"
        export HTTP_USER_AGENT
    fi
    if [ "x$REQUEST_URI" = x ] ; then
        REQUEST_URI=$progname
        export REQUEST_URI
    fi
    if [ "x$QUERY_STRING" = x ] ; then
        QUERY_STRING=''
        export QUERY_STRING
    fi
}

check_executables() { # check & find executable from the list
    EXECs=
    EXECs_given="$*"
    [ "x$EXECs_given" != x ] || EXECs_given="./$basename.REAL ./$basename.OLD ./$basename.NEW"
    for fexec in $EXECs_given ; do
       [ ! -x $fexec ] || EXECs="$EXECs $fexec"
    done
    if [ "x$EXECs" = x ]; then
        get_victim
        mail $victim <<EOF
Subject ${progname} : can find binaries to run : $EXECs_given

`ls -al`

EOF
        exit 1
    fi
}

report_lock_problem() {
     get_victim
     opid=`cat $stats.lock`
     mail $victim <<EOF
Subject: mmdbsrv.wrapper locking problem

dd="$dd"
$stats.lock=$opid

`ps -ef | grep $opid`

`ls -al`

`ps -ef`

`set`

EOF
     exit 1
}

report_failure() { # $execname $rcode $res_fname $res_fname.2
    rf_execn=$1
    rf_code=$2 
    if [ x$rf_code = x158 ] ; then
        ttl="Exceeded cpu limit: killed"
    else
        ttl="failed with status $rf_code"
    fi 
    rf_rn=$3
    rf_rn2=$4
    get_victim $rf_execn
    mail $victim <<EOF
Subject: $rf_execn $ttl

HTTP_HOST=${HTTP_HOST}
HTTP_REFERER=${HTTP_REFERER}
QUERY_STRING=${QUERY_STRING}
REMOTE_HOST=${REMOTE_HOST}
REQUEST_METHOD=${REQUEST_METHOD}
REQUEST_URI=${REQUEST_URI}
SYBASE=${SYBASE}
COMMAND_LINE=${options}
`df -k /tmp` - /tmp
`df -k /var/tmp` - /var/tmp
====================================================================
Input file:
`cat $input_file`

====================================================================
stderr:
`cat $rf_rn2`

diff:
`cat $rf_rn`

====================================================================
----------- Environment:----------------

`env`

EOF
}

#
# run basic settings
#

basic_settings