-
Notifications
You must be signed in to change notification settings - Fork 0
/
build_server_tree
executable file
·2810 lines (2346 loc) · 92.1 KB
/
build_server_tree
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
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/bin/env bash
# zzzxxx why the http2 message in error log?
# commend out current line and uncomment out
# #LoadModule mpm_event_module modules/mod_mpm_event.so
# in /etc/httpd/conf.modules.d/00-mpm.conf
# per https://www.youtube.com/watch?v=zT2iCk7-HLs
# Step 3:
# cd /etc/httpd/conf
# vim httpd.conf
#
# Add the below lines to bottom of the page:
# Protocols h2 http/1.1
# Protocols h2 h2c http/1.1
#
#
# Step 4:
# sudo service httpd restart
# sudo service mysqld restart
#
#
# Step 5:
# Ensure your website is still up and running without any issues
#
# Check if HTTP/2 is successfully enabled using the below website:
# https://http2.pro/
# xxx change from filval to File::Slurp ?
# xxx add SNACC account? (to deal with this thing once and for all, since
# EZID's batch interface probably won't ever support bulk minting
# xxxx bug: $sstub/apachebase.t fails on machines where only ports 80 and 443
# are open; also t/service_n2t.t
# yyy ?move wegn and wegnpw from n2t repo into the eggnog repo
# esp. as ApacheTester (and soon t/* tests) rely on them
# don't forget that init.d/apache relies on wegn too.
# XXXX bug: two populators can't have binder of the same name
# fix: change binders path to start binders/<populator>/<bindername>
# instead of binders/<bindername>
# xxx add 1>&2 to error messages throughout (beyond first section)
# xxx don't listen on 80, assume portforwarding always
# XXX add this instruction/advice to make_instance?
# From stackoverflow
#How to stop apache permanently on mac Mavericks?
#Try this:
# sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist
#This will stop a running instance of Apache, and record that it should
#not be restarted. It records your preference in
#/private/var/db/launchd.db/com.apple.launchd/overrides.plist.
# XXX see man sysctl and look at net.inet.ip.forwarding
# XXXX bug: fix timing of initializing rewrite2-server for n2t as a separate
# step from creating N2T binders
evarnames=(
PERL5LIB EGNAPA_TOP
EGNAPA_BUILDOUT_ROOT EGNAPA_BINDERS_ROOT EGNAPA_MINTERS_ROOT
)
declare -x ${evarnames[@]}
# yyy review these vars -- are they still so special?
[[ -f ~/warts/env.sh ]] &&
source ~/warts/env.sh
# Begin by making guesses as to your hostname and Apache instance,
# which will inform some of the help/usage information we may end up
# printing on early exit.
#
# First set values for $uname (OS name) and $host (fully qualified hostname).
uname=$( uname -a ) # get name of operating system (OS)
aws= # XXX hack supporting $sstub/n2t
# on SLES, uname -a returns: Linux
# on EC2, uname -a returns: Linux.*amzn
[[ "$uname" =~ .*amzn.* ]] && # hack indicating if we're
aws=1 # on an Amazon ec2 instance
# yyy?? I guess this means caller can set this on the way in
# on Mac, hostname -f returns: jak-macbook.local
# on EC2, hostname -f returns: ias-n2t-dev.cdlib.org
# on SLES, hostname -f returns: cdl-n2tpre-p01.ucop.edu
# on Solaris, hostname -f returns: error
#
host=$EGNAPA_HOST # EGNAPA_HOST typically set in .bashrc
[[ "$host" ]] || { # try for some platform independence
host=$( hostname -f 2> /dev/null ) || { # fails on Solaris
host=$( hostname )
#host+='.cdlib.org' # XXX kludge
}
}
# Then set value for $aptop (top-level apache2 root of public-facing server).
## Then set value for $aptop (top-level apache2 directory).
#
# Look for the first instance of apache2 that we can find; use it as our
# best guess for EGNAPA_TOP
# yyy is this . and .. search the best approach given $sv on the Mac?
#
aptop=$EGNAPA_TOP
[[ "$aptop" ]] || {
dirs=( ` sed -e 's/:/ /g' -e 's,\([^ ]*\)/bin,\1 \1/etc,g' <<< $PATH ` )
for d in . .. ${dirs[*]}
do
#echo d was $d
d=$( sed 's,$,/apache2,' <<< $d )
#echo d is $d
[[ -d $d ]] && {
aptop=$( cd $d && pwd -P )
[[ "$aptop" ]] &&
break
}
done
}
#
# When we get here, $aptop and $host will have either a caller-defined
# value or our best guess for a value. xxx document
#
# Initialize global variables and source the appropriate .cfg file.
src_top=`pwd -P` # use -P because we don't want symlinks
function usage {
cat << EOT
USAGE
$0 [ --public ] Command ConfigDir
COMMANDS
make - build out-of-date parts of a server config tree for testing
build - force build of entire server config tree for testing purposes
check - check if server config tree is built and exit 0 if so
env - output bash config settings for ingest by others, eg, Perl
which_pswdfile
- output name of password file to be used (real or repo)
cert - create self-signed certificate only; side-effect of build
help - show this documentation
EXAMPLES
$0 build web
$0 build n2t
DESCRIPTION
This script must be called from the eggnog source directory. It is usually
run via File::ApacheTester::prep_server() with the "make" sub-command.
$0 builds the filesystem pieces needed to test and
run a binder/minter/resolver web service under an Apache HTTP Server.
It creates essential server files in a temporary directory without
altering existing non-test data or server log and configuration files.
Most of the script runs after changing the current directory to
\$buildout_root, with the current source directory available as \$src_top.
If the optional --public option is given, the script creates versions of
those server files (in a separate temporary directory) designed to work
with the public-facing server. These files are meant to be copied by the
caller into the public server's Apache subdirectory when upgrading.
The prep_server() call itself is meant to appear near the beginning of Perl
test suites such as t/apachebase.t and t/service_n2t.t. Before calling, the
suite should declare a server configuration directory, \$cfgdir. There, a
configuration file, \$cfgdir/build_server_tree.cfg, may set values for some
of the script control variables if it wishes, notably defining users and
XXXX passwords via a pwdfile variable, augmenting the $checkfiles
array of files whose modification will trigger a rebuild. See comments in
the supplied examplar files for more information.
Another configuration file, \$cfgdir/minder_builder.cfg, defines minters,
binders, and base server documents (if any). See comments for more.
The caller can change this script's behavior by setting some environment
variables before invoking it. Use the optional variables below to set a
specific hostname, Apache server directory, or SSL certificate (but only
specify a chainfile if there is one).
xxx update encouraging reliance on warts/env.sh settings
xxx sysap system apache root
EGNAPA_TOP public-facing server root eg, /etc/apache2
EGNAPA_HOST eg, n2t.net
EGNAPA_SSL_KEYFILE eg, ~sam/ssl/2019-07-19/fran.key
EGNAPA_SSL_CERTFILE eg, ~sam/ssl/2019-07-19/fran.crt
# EGNAPA_SSL_CHAINFILE eg, ~sam/ssl/2019-07-19/gd_bundle-g2-g1.crt
Some other important variables are
EGNAPA_BUILDOUT_ROOT config files we build to complement EGNAPA_TOP
EGNAPA_SRVREF_ROOT final place from which files are referenced on
the running server (built vs running after copy)
The script itself re-exports these control variables to the environment:
export \\
EGNAPA_TOP=\$aptop \\
EGNAPA_HOST=\$host \\
EGNAPA_PORT_HPA=\$port_hpa \\
EGNAPA_PORT_HPAS=\$port_hpas \\
EGNAPA_PORT_HPR=\$port_hpr \\
EGNAPA_PORT_HPRS=\$port_hprs \\
EGNAPA_SRVREF_ROOT=\$srvref_root \\
EGNAPA_BUILDOUT_ROOT=\$buildout_root \\
EGNAPA_BINDERS_ROOT=\$binders_root \\
EGNAPA_MINTERS_ROOT=\$minters_root \\
EGNAPA_SHOULDERS_ROOT=\$shoulders_root
EOT
}
# Basic argument and environment variable sanity checks.
pubflag=
if [[ $1 == --public ]]; then
pubflag=1
shift
elif [[ $1 =~ ^-- ]]; then
echo "Error: unrecognized option: $1" 1>&2
usage 1>&2
exit 1
fi
cmd=$1
[[ "$cmd" ]] || {
usage
exit
}
cfgdir=$2
[[ "$cfgdir" ]] || {
echo Error: missing ConfigDir argument. 1>&2
usage 1>&2
exit 1
}
EGG=""
service="$cfgdir" # yyy "service" is the better var name
export EGG+=" --service $service "
# Needed for first rollout, before there's any may be eggnog_conf file
# (which would override it if it existed).
export EGNAPA_SERVICE="$service"
# Each build has a "signature" so we can run tests twice in a row without
# rebuilding, but we make sure to rebuild if the signature doesn't match.
#
cfgphrase="file \"$cfgdir\"" # "signature" of build
#bst_root=$src_top/$cfgdir # "build_server_tree root"
sstub=t # service config stub directory, eg, $sstub/n2t
bst_root=$src_top/$sstub/$cfgdir # "build_server_tree root"
cfgfile=$bst_root/build_server_tree.cfg
hconf=httpd.conf
# Usage: is_build_out_of_date ConfigRoot
# Echoes empty string and returns 0 if not out of date, else
# echoes names of file newer than the $fqhconf file and returns 1.
#
# This is only part of the test for out-of-datedness. yyy
#
function is_build_out_of_date {
local fqhconf=$1/conf/$hconf
# (note grep -q won't stay quiet in case $fqhconf doesn't exist)
grep "$sstub/$cfgdir" $fqhconf > /dev/null 2>&1 || {
echo "server needs to be (re)built for $cfgdir"
return 1
}
local out_of_date=$( find $bst_root -newer $fqhconf )
#ls -l $0 $fqhconf 1>&2
[[ $0 -nt $fqhconf ]] &&
out_of_date=( $0 ${out_of_date[*]} )
[[ ${out_of_date[0]} ]] || {
echo '' # good return -- not out of date
return 0
}
echo "Server needs to be rebuilt, as these have changed:"
for i in ${out_of_date[*]}
do
echo " $i"
done
return 1
}
[[ ! $cmd || $cmd == help ]] && {
usage
exit 0
}
[[ -f Makefile.PL ]] || {
echo "Error: should be called from eggnog module source directory" 1>&2
usage 1>&2
exit 1
}
[[ "$sv" ]] || {
echo 'An SVU mode must be in effect, eg, "svu cur" or "svu new".' 1>&2
echo 'Type "svu" for details.' 1>&2
exit 1
}
#
# Configuring.
#
# Initialize with default settings, which may be very usefully changed
# as a side-effect of processing $cfgfile. Eg, the $checkfiles array may
# be augmented with names of password files, and $buildout_root may have
# a whole new value. Most of the interesting local variables follow.
# Paths that we use directly here to _create_ files.
#
buildout_root=$src_top/td_egnapa
[[ $pubflag ]] &&
buildout_root=$src_top/td_egnapa_public
# Paths for all files that this script creates descend from $buildout_root.
#
# The script should never alter anything in $EGNAPA_TOP.
# This works fine for testing purposes, but when --public is specified,
# files that we create will later be moved (not by this script) under $aptop,
# and in order for them to work there, the paths that we insert into those
# files are set to reference files under $aptop (in advance of the move).
# Variable names of the form *ref_root are intended to work correctly as
# references in the ordinary and the --public cases.
srvref_root=$buildout_root
[[ $pubflag ]] &&
srvref_root=$aptop
# ddddd sslref_root should no longer be needed, right?
#ssl_root=$buildout_root/ssl
# ddddd sslref_root does appear to host pwdfiles though, so we may need a
# pwdfileref_root var (set to conf/
#sslref_root=$srvref_root/ssl
# yyy should be .../dvN?
pwdfile_root=$buildout_root/conf
pwdfref_root=$srvref_root/conf
binders_root=$buildout_root/binders
bdrsref_root=$srvref_root/binders
minters_root=$buildout_root/minters
mtrsref_root=$srvref_root/minters
shoulders_root=$buildout_root/shoulders
shdrsref_root=$srvref_root/shoulders
prefixes_root=$buildout_root/prefixes # xxx drop? change?
# see also: $cgiref_egg
document_root=$srvref_root/htdocs # paths referenced in files
ruu_document_root=$srvref_root/htdocs/ruu.app
rmap_root=$srvref_root/htdocs/a # more paths referenced
template_root=$src_top/$sstub/$cfgdir # paths to build input files
# ddddd once these locations aren't used any longer for self-signed
# certs, now where do generated password files go? A: conf/
# ddddd set sslcert et al to EGNAPA_SSL_CERTFILE et al
# ?? what about ...ref vars?
sslcert=$EGNAPA_SSL_CERTFILE
sslcertkey=$EGNAPA_SSL_KEYFILE
#sslchain=$EGNAPA_SSL_CHAINFILE
#sslcertref=$sslref_root/server.crt
#sslcertkeyref=$sslref_root/server.key
#sslchainref=
#cp -p $EGNAPA_SSL_CERTFILE $sslcert
#cp -p $EGNAPA_SSL_KEYFILE $sslcertkey
#[[ $EGNAPA_SSL_CHAINFILE ]] && { # if there's a chain file
# cp -p $EGNAPA_SSL_CERTFILE $EGNAPA_SSL_CHAINFILE
#sslcert=$ssl_root/server.crt
#sslcertkey=$ssl_root/server.key
#sslchain=
#sslcertref=$sslref_root/server.crt
#sslcertkeyref=$sslref_root/server.key
#sslchainref=
rotatelogs="/usr/sbin/rotatelogs -l"
#rotatelogs="$aptop/bin/rotatelogs -l"
weekly=604800 # number of seconds in a week
let monthly=(604800 * 4) # actually, just 4 weeks
# The working directory we chdir to from inside scripts. This value will
# change in the --public case.
scripts_wd=$src_top
[[ $pubflag ]] &&
scripts_wd=$aptop
# Flags we pass to Perl when invoked from CGI scripts. This value will
# change in the --public case.
# zzz pull 'td' string from Perl source definition? else not DRY
tda=td # binder name qualifier for --testdata; protects public binders
perl_args="perl -Mblib"
#tda_arg="--testdata $tda"
isolation_arg="--testdata $tda"
[[ $pubflag ]] && {
perl_args=""
isolation_arg="--isolator public"
# tda_arg="--isolator public"
}
# There are 3 categories of port pairs (http and https):
# $port_hpa http public-access (what you advertize)
# $port_hpas https public-access (what you advertize)
# $port_hpr http public-receive (what you receive on,
# eg, after port-forwarding or load balancer)
# $port_hprs https public-receive (what you receive on,
# eg, after port-forwarding or load balancer)
# $port_hts http test server
# $port_htss https test server
#
port_hts=8082
port_htss=8083
port_hpa=$port_hts
port_hpas=$port_htss
port_hpr=$port_hts
port_hprs=$port_htss
[[ $pubflag ]] && {
port_hpa=80 # xxx var unused
port_hpas=443 # xxx var unused
port_hpr=18880
port_hprs=18443
}
# usage: which_pswdfile
#
# Returns (via stdout) filename to be used as pswdfile. This is the
# mechanism that permits real passwords to be stored outside of the
# source code repository. Relies on global $cfgdir being defined.
# Other scripts rely on this output (eg, wegnpw).
#
# It first tries $HOME/warts/.pswdfile.$cfgdir. If and only if that file
# does not exist, it tries "$sstub/$cfgdir/pswdfile" in the eggnog source.
#
function which_pswdfile {
# First try for fully qualified config file.
#
fqconf=$HOME/warts/.pswdfile.$cfgdir
[[ -f $fqconf ]] && {
chmod 600 $fqconf # make sure it's not readable to most
echo $fqconf
return 0 # success
}
# Second try. This time we'll look in the source tree.
fqconf=$bst_root/pswdfile
[[ -f $fqconf ]] && {
echo $fqconf
return 0 # success
}
# failure
return 1
}
# yyy properly add pwdfiles to checkfiles
# yyy is $bst_root/pswdfile even used any more?
checkfiles=(
htdocs/a conf/$hconf $sslcert
eggnog_conf_default
$HOME/warts/env.sh
$HOME/warts/.pswdfile.$cfgdir $bst_root/pswdfile
)
egpath=$PERL_INSTALL_BASE/bin:/bin:/usr/bin:/sbin:/usr/sbin
[[ "$PERLBREW_PATH" ]] && # modify base path if perlbrew is there,
egpath=$PERLBREW_PATH:$egpath # eg, for Mavericks/Mac OSX
[[ -f $cfgfile ]] || {
echo "Error: $cfgfile: build_server_tree configuration" \
"file not found" 1>&2
exit 1
}
#[[ -f $cfgfile ]] || {
# echo -n "Error: " 1>&2
# if [[ "$cfgdir" ]]; then # xxx problematic logic
# echo "no ConfigDir argument" 1>&2
# else
# echo "$cfgfile: build_server_tree configuration file not found" 1>&2
# fi
# usage
# exit 1
#}
source $cfgfile # configure this build_server_tree script
# yyy barely necessary with pswdfile separate
which_pswdfile=$( which_pswdfile ) # find password information
[[ $cmd == which_pswdfile ]] && {
echo $which_pswdfile
exit
}
# ok to output human readable messages now that that command has returned
[[ "$which_pswdfile" ]] || {
echo "Error: no password file found in either warts or source" \
"Config ($fqconf)." 1>&2
exit 1
}
source $which_pswdfile # configure password information
chmod go= $bst_root/pswdfile # kill all perms except the owner's
echo Configured $cfgdir in $buildout_root.
# This script calls egg, and we want the latest -Mblib and cleanest, eg,
# XXX does this do anything?
export EGG="--home $buildout_root" # wrt default config and prefixes
#export NOG="--home $build_root" # yyy later?
# Done with configuring. Now set environment variables based on latest
# that this script sets by default and that the config file overrode.
export \
EGNAPA_TOP=$aptop \
EGNAPA_HOST=$host \
EGNAPA_PORT_HPA=$port_hpa \
EGNAPA_PORT_HPAS=$port_hpas \
EGNAPA_PORT_HPR=$port_hpr \
EGNAPA_PORT_HPRS=$port_hprs \
EGNAPA_SRVREF_ROOT=$srvref_root \
EGNAPA_BUILDOUT_ROOT=$buildout_root \
EGNAPA_BINDERS_ROOT=$binders_root \
EGNAPA_MINTERS_ROOT=$minters_root \
EGNAPA_SHOULDERS_ROOT=$shoulders_root
# EGNAPA_PREFIXES_ROOT=$prefixes_root
# yyy Something equivalent could be achieved, probably, with just shell
# variable instead of environment variables.
# The "env" command (a) lets us see what configuration actually did and
# (b) provides non-bash processes (eg, Perl) with the ability to re-parse
# the settings for themselves in an easy, generic, label=value format.
#
[[ $cmd == env ]] && {
# Print bash config settings for non-bash processes and exit
echo Configuration settings after reading $cfgfile:
env
#set
exit 0
}
# NB: this "egg cfq" is an expensive call (0.7 seconds), which can really
# slow down the wegn and wegnpw scripts when they call this script;
# so we move the call as late as we can
# yyy question: would EGNAPA_HOST_CLASS be missed from the "env" output?
# and if so, how would we speed this up?
# XXX should EGNAPA_HOST_CLASS be set again (as before) in warts/env.sh,
# especially because we have installation probz during first rollout, when
# there's no eggnog_conf already installed?
# >>> trial: semi-kludge to override --home setting from EGG env var (since
# that home dir setting doesn't exist yet) by using an explicit --home
# arg pointing into the source tree so that config file is found;
# instead probably should add new "--config file" arg to egg
# kludgy fake home directory
class=$( perl -Mblib egg --home $bst_root cfq class )
#class=$( perl -Mblib egg cfq class )
ruuapp=$( perl -Mblib egg --home $bst_root cfq vhost_ruuapp )
[[ "$class" != "$EGNAPA_HOST_CLASS" ]] && {
echo "WARNING: configured host class ($class) differs from that" \
"in ~/warts/env.sh ($EGNAPA_HOST_CLASS)"
export EGNAPA_HOST_CLASS="$class"
}
[[ "$aptop" ]] || {
echo Error: could not find apache2 on your system.
exit 1
}
# XXX needed?
let errs=0
for i in ${evarnames[@]}
do
[[ ${!i} ]] || {
let errs++
echo "$i not defined"
}
done
[[ $errs > 0 ]] &&
exit 1
# xxx true in Apache 2.4?
[[ ! $EGNAPA_TOP =~ ^/ || ! -d $EGNAPA_TOP/conf ]] && {
echo "EGNAPA_TOP ($EGNAPA_TOP) must be a full pathname to an" \
"Apache server root directory."
usage
exit 1
}
egg_dbie=
[[ "${EGG_DBIE:-}" ]] && {
egg_dbie="$EGG_DBIE"
[[ "$egg_dbie" =~ e ]] && { # if exdb case
mg status > /dev/null || { # yyy assume mongo
echo "error: database daemon not running;" \
"did you do \"mg start\"?" 1>&2
exit 1; # bail out
}
}
}
#export LC_ALL=C # to deal with unicode errors
out_of_date_msg=$( is_build_out_of_date $buildout_root )
# xxx to do: add prefixes to "n2t backup"
# Get a list of changed files or any error messages. Ignore status code which
# normally returns status 1 (fail) rebuilding isn't needed.
prefixes_need_rebuilding=$( pfx onboard 2>&1 )
# If it wasn't found out of date on the first test, do a second test.
if [[ ! "$out_of_date_msg" ]]
then
checkdir=$buildout_root
#( cd $checkdir; ls ${checkfiles[*]} > /dev/null 2>&1 ) ||
chkr=$( cd $checkdir; ls ${checkfiles[*]} 2>&1 )
# yyy not using $chkr
if [[ $? -ne 0 ]]
then
out_of_date_msg="Server needs to be rebuilt, as some of these "
out_of_date_msg+="checkfiles are missing:"
for i in ${checkfiles[*]}
do
[[ -e "$checkdir/$i" ]] ||
out_of_date_msg+=$'\n'" $i"
done
#elif [[ "$prefixes_need_rebuilding" ]]
#then
# echo "Prefixes file, not server itself, needs rebuilding."
else
echo "Server does not need to be rebuilt." \
"yyy maybe minters don't need it too"
fi
fi
[[ $cmd == check ]] && { # handle the "check" sub-command and return
[[ $out_of_date_msg ]] && {
echo "$out_of_date_msg"
exit 1
}
[[ "$prefixes_need_rebuilding" ]] && {
echo "The prefixes file needs rebuilding."
exit 1
}
echo Server in $checkdir is already built out.
exit 0
}
rwplus=$buildout_root/conf/rewrite2-server.conf
chmod go= $bst_root/minder_builder.cfg # make sure most perms are turned off
source $bst_root/minder_builder.cfg
function makebinder { # args: binder name and owner (populator)
bname=$1
owner=$2
[[ -d $binders_root/$bname ]] && {
echo -n "(Skipping existing binder $binders_root/$bname.) "
return 0
}
# We always use -Mblib here because we may need the latest and
# greatest egg to complete the transition we're working towards.
# yyy is it safe to use -Mblib always?
# zzz test that we can't rmbinder with --isolator public
local args # NB: --testdata needed to shield production DBs!!
# This should ALWAYS use -testdata arg, never --isolator public,
# because that would accidentally remove public-facing binders.
args=( -p "$binders_root" --user "$owner" --testdata $tda )
#perl -Mblib egg "${args[@]}" --force brm $bname; \
(cd $src_top; \
perl -Mblib egg "${args[@]}" --force rmbinder $bname; \
perl -Mblib egg "${args[@]}" mkbinder $bname) || {
echo -n "(Problem creating $owner's binder \"$bname\".) "
return 1
}
return 0
}
# xxx test with minters
# xxx why does .../ark: not found show in error log?
# xxx document how all this works, eg, $2 names a populator's binder,
# and $1 is a binder script path that triggers a populator-specific
# authn realm and password file, and it is (?) symlinked so that it
# will actually be executed as a script
#binder_new="${script_px}egg? --api -d $binders_root/"'$1 $2'
# yyyxxx minter_* untested; should include whole prefix in minter name, eg,
# ark/99999/fk4 (for disambiguating shoulders)
# https://*.*.*/a/ezid/m?<M>.mint N # api to ezid minter M
#cat << EOT >> $hconf
# Create minters, removing existing minters first if need be.
# First arg is populator
# and second arg is a comma-separated list of fqshoulders. A fqshoulder
# (fully qualified shoulder) is of the form scheme:/*naan/shoulder.
# (yyy right now populator has exclusive use of a set of minters, but
# maybe that's not nuanced enough? is there a need for minters shared
# between populators?)
#
function makeminter { # pass in populator and minter names as args
local populator=$1 retstatus=0
local shdrparts scheme naan shdr mname
# Note: $2 looks like ark:/99999/fk4,doi:5072/fk4
for i in ` sed 's/, */ /g' <<< $2 ` # break list items at commas
do
shdrparts=( ` sed -e 's,:/*, ,' -e 's,/, ,' <<< $i ` )
scheme=${shdrparts[0]}
naan=${shdrparts[1]}
shdr=${shdrparts[2]}
mname=$minters_root/$populator/$scheme/$naan/$shdr
shortmname=$scheme/$naan/$shdr
# Important to invoke mkminter with $naan/$shdr as the
# shoulder rather than pushing $naan into the -p path; that
# way the check digit will be computed over "$naan/$shdr"
# rather than just over $shdr.
#
# We always use -Mblib here because we may need the latest and
# greatest nog to complete the transition we're working towards.
#
(cd $src_top; perl -Mblib nog -p \
$minters_root/$populator/$scheme \
mkminter $naan/$shdr) || {
echo -n \
"(Problem creating minter \"$naan/$shdr\" ($mname).) "
retstatus=1
continue
}
done
return $retstatus
}
# Make generic minders sufficient for testing. Note that it doesn't make
# or initialize custom minders as determined by the ConfigDir setting.
# It won't complain and won't overwrite existing (eg, custom) binders,
# in part because it is often called right after removing everything.
# Minters and binders defined in $sstub/*/minder_builder.cfg.
#
function make_minders {
local b n m
echo -n "Creating proto-binders: "
n=0
for b in ${binders[*]}
do
makebinder $b ${populators[$n]} && echo -n "$b "
let n++
done
echo ""
echo -n "Creating proto-minters: "
n=0
for m in ${minters[*]}
do
# xxx this nicely creates the ark subdir, but is it best way to
# officially create it?
makeminter ${populators[$n]} $m && echo -n "$m "
let n++
done
echo ""
}
# If we got the "make" sub-command while the server is up-to-date, all we
# need to do is to possibly rebuild prefixes, and then rebuild minters,
# binders (which each maintain state that is altered by testing) to keep
# the next round of tests clean.
[[ $cmd == make && ! $out_of_date_msg ]] && {
[[ "$prefixes_need_rebuilding" ]] && {
echo Prefix rebuild triggered by: \
"${prefixes_need_rebuilding[@]}"
pfx build || {
echo "Could not rebuild prefixes" 1>&2
exit 1
}
}
# We would normally leave now that we know the server isn't out
# of date, but first we have to re-set a few things.
#
echo Initializing minters, binders, and logs so that tests run clean.
rm -fr $buildout_root/{bind,mint}ers/* $buildout_root/logs/*_log
make_minders > /dev/null # not so interesting on "make"
exit 0
}
# yyy probably shouldn't do this in case of 'cert' command
rebuild_prefixes=
pfx save $buildout_root || # tuck away prefixes stuff for re-use
rebuild_prefixes=1
# If we get here, $cmd is "make", "build", or "cert".
# XXX this logic isn't right if "build" is a forced make
#
if [[ $out_of_date_msg || $cmd == build ]]
then
[[ $out_of_date_msg ]] &&
echo "$out_of_date_msg"
[[ $buildout_root =~ apache2?/*$ ]] && {
echo "Sorry, it looks like I'm to remove \"$buildout_root\"," \
" which makes me nervous because it's named like a real server."
echo "Bailing. You may want to remove it manually."
exit 1
}
echo " now removing $buildout_root for the rebuild"
[[ -f $buildout_root/logs/httpd.pid ]] && {
echo "There appears to be an egnapa server running."
msg="Now shut down."
# xxx this cmd+args is repeated in ApacheTester.pm
# define once and re-use
#$aptop/bin/httpd -f $buildout_root/conf/httpd.conf -d $aptop \
httpd -f $buildout_root/conf/httpd.conf -d $aptop -k stop ||
msg="Warning: error shutting down server."
echo " $msg"
}
# ============== Destroy server !!!! ================
rm -fr $buildout_root
#echo Removing config and prefix defaults affecting your generic use.
#rm -fr $HOME/.eggnog/{eggnog_conf_default,prefixes.yaml}
## yyy kludge, only affects user installing new server
fi
# If we get here, entire server and prefix infrastructure needs rebuilding.
echo Building skeleton server structure extensions.
# yyy what's httpauth for? var/state? should we use var/{run,lock}?
msg=$( mkdir -p 2>&1 $buildout_root \
$buildout_root/{htdocs,conf,cgi-bin,logs} \
$buildout_root/htdocs/ruu.app \
$buildout_root/htdocs/{a,e,r,e/{pop,pub,admin},e/{images,x,css}} )
(cd $buildout_root/htdocs/ruu.app; ln -s ../e e)
[[ -e $bst_root/eggnog_conf ]] && {
echo Copying $bst_root/eggnog_conf
cp -p $bst_root/eggnog_conf $buildout_root/
}
#ln -s $aptop/conf/mime.types $buildout_root/conf/mime.types
cp -p $aptop/conf/mime.types $buildout_root/conf/mime.types
ln -s $aptop/modules $buildout_root/modules # link for modules
ln -s $aptop/conf.modules.d $buildout_root/conf.modules.d # load modules
[[ $msg != '' ]] && {
echo "Some structures already existed (ok):"
echo "$msg" | sed 's/^/ /'
# yyy is this useful?
}
# xxx bug somewhere: remove prebuild area and test fresh?
# or do I really need -d?
# xxx bottom line: need SURE way to update prefixes on running prd system
# as not even n2t rollout will catch latest updates
# xxx much more efficient (instead of rebuilding prefixes all the time),
# would be to save a per-system prefix build that senses when to rebuild,
# eg, changes in pfx or Resolve.pm or ??
# where to cache? in ~/pfx_harvest/tmpxyz?
#pfx onboard || exit
#pfx build || exit
pfx restore $buildout_root || # restore saved prefixes, which might
rebuild_prefixes=1
pfx onboard && # still need rebuilding; exit 1 says yes
rebuild_prefixes=1
[[ "$rebuild_prefixes" ]] && {
pfx build
}
# The next two items help reduce useless noise in error_log.
#
favicon=$buildout_root/htdocs/e/images/favicon.ico
[[ -e $favicon ]] || # create empty favicon.ico file
cp /dev/null $favicon # to prevent routine log errors
robots=$buildout_root/htdocs/robots.txt
[[ -e $robots ]] || # create empty robots.txt file
cp /dev/null $robots # to prevent routine log errors
## yyy drop this form now that google form is available
## Establish a simple, executable form to assist NAAN curation.
#
#naancure=$buildout_root/htdocs/e/admin/q2e.pl
## https://n2t-dev.n2t.net/e/admin/q2e.pl?unusednaan=12345&formout=name%3A+value%0D%0Akey%3A+value
#[[ -e $naancure ]] || {
# cat > $naancure <<- EOT
# #!/bin/sh
#
# PERL5LIB=$PERL5LIB
# PATH=$egpath
# export PERL5LIB PATH
#
# exec perl <<- 'EOS'
#
# #!/usr/bin/env perl
# ##
# ## printenv -- demo CGI program which just prints its environment
# ##
#
# print "Content-type: text/plain; charset=UTF-8\n\n";
# print "xxx Stub q2e.\n";
# my (\$var, \$val);
# foreach \$var (sort(keys(%ENV))) {
# \$val = \$ENV{\$var};
# \$val =~ s|\n|\\n|g;
# \$val =~ s|"|\\"|g;
# print "\${var}=\"\${val}\"\n";
# }
# EOS
#
# EOT
#
# chmod 755 $naancure
#}
# Establish a script to handle inflections and content negotiation.
# CrossRef handles these:
# application/rdf+xml
# text/turtle
# application/atom+xml
#
cp -p $HOME/local/bin/pfx $buildout_root/htdocs/e/x/pfx # local copy
inflect=$buildout_root/htdocs/e/x/inflect
[[ -e $inflect ]] || {
# Remember to quote normal $ \ and ` in << blocks.
cat > $inflect << EOT
#!/bin/sh
# This "inflect" script handles inflections and prefix lookup.
# Script args arrive via a QUERY_STRING as name=value pairs.
# The script constructs a pfx commmand, runs it, and returns its output.
# Add /usr/local/bin to path so that we get our version of bash.
PERL5LIB=$PERL5LIB
PATH=/usr/local/bin:$egpath
LANG=en_US.UTF-8
export PERL5LIB PATH LANG
exec perl << 'EOS'
#!/usr/bin/env perl
use 5.10.1;
use strict;
use warnings;
print "Content-type: text/plain; charset=UTF-8\n",
"THUMP-Status: 0.7 200 OK\n",
"\n";
use Text::ParseWords;
#say "qs: \$ENV{QUERY_STRING}";
# QUERY_STRING contains pseudo command arguments
my @args = shellwords( \$ENV{QUERY_STRING} );
my (%h, \$key, \$val);
for (@args) {
/^-/ and # skip flag args starting with '-'
next;
! /^([^=]+)=(.*)/ and # split at first "=" and skip line
next; # if it doesn't look like key=...
(\$key, \$val) = (\$1, \$2);
\$val =~ s/%([[:xdigit:]]{2})/chr hex \$1/eg; # hex decode
\$h{\$key} = \$val;
}
if (\$h{op} eq 'partial') {
# prefix lookup, eg, n2t.net/pdb:
# n2t.net/pdbe/pdb:
# */pdb: == pdb:
# */pdb:12345 -> list of targets
# user-supplied regex disallowed for now by use of \Q ... \E