1 | #!/usr/bin/perl |
---|
2 | |
---|
3 | $svnbase = "gw105.iu.xsede.org/svn/base"; |
---|
4 | |
---|
5 | $|=1; |
---|
6 | |
---|
7 | # $debug++; |
---|
8 | |
---|
9 | my $gb = $ENV{ "GENAPP" } || die "$0: environment variable GENAPP must be set\n"; |
---|
10 | |
---|
11 | print "perl version is $]\n" if $debug; |
---|
12 | print "command is: $0 @ARGV\n" if $debug; |
---|
13 | |
---|
14 | if ( $] < 5.018 ) { |
---|
15 | if ( -e "$gb/perl/bin/perl" ) { |
---|
16 | my $pv =`$gb/perl/bin/perl -e 'print \$];'`; |
---|
17 | if ( $pv >= 5.018 ) { |
---|
18 | print "will run new version\n" if $debug; |
---|
19 | unshift @ARGV, $0; |
---|
20 | exec( "$gb/perl/bin/perl", @ARGV ); |
---|
21 | } else { |
---|
22 | die "$gb/perl/bin/perl exists, but not a correct version of perl (needs a minimum of 5.18)\n"; |
---|
23 | } |
---|
24 | } else { |
---|
25 | die "you need to install a version of perl >= 5.18 in $gb/perl\n |
---|
26 | there is a script $gb/sbin/install-perl-stable to do this"; |
---|
27 | } |
---|
28 | } |
---|
29 | |
---|
30 | my $gap = $gb; |
---|
31 | |
---|
32 | require "$gap/etc/perl/genapp_util.pl"; |
---|
33 | |
---|
34 | $notes = |
---|
35 | "usage[1]: $0 {options} svntype applicationname |
---|
36 | usage[2]: $0 list |
---|
37 | |
---|
38 | When using usage[1]: |
---|
39 | svntype can be svn or svn+ssh |
---|
40 | applicationname must be a valid application name (use usage[2] to get a list) |
---|
41 | svn checks out application and sets up paths |
---|
42 | |
---|
43 | Options: |
---|
44 | -admin user add user name to admin list for application |
---|
45 | -force force checkout even if directory exists |
---|
46 | -gen run genapp.pl after install |
---|
47 | -nolinks do not setup html links |
---|
48 | -dir directory use specified directory instead of application name |
---|
49 | |
---|
50 | when using usage[2]; |
---|
51 | this will list the available application names |
---|
52 | |
---|
53 | "; |
---|
54 | |
---|
55 | my $admin; |
---|
56 | my $force; |
---|
57 | my $gen; |
---|
58 | my $nolinks; |
---|
59 | my $targetdir; |
---|
60 | |
---|
61 | while ( $ARGV[ 0 ] =~ /^-/ ) { |
---|
62 | my $option = shift @ARGV; |
---|
63 | if ( $option =~ /^-admin$/ ) { |
---|
64 | die "$0: option $option requries an argument\n" . $notes if !@ARGV; |
---|
65 | $admin = shift @ARGV; |
---|
66 | next; |
---|
67 | } |
---|
68 | if ( $option =~ /^-dir$/ ) { |
---|
69 | die "$0: option $option requries an argument\n" . $notes if !@ARGV; |
---|
70 | $targetdir = shift @ARGV; |
---|
71 | next; |
---|
72 | } |
---|
73 | if ( $option =~ /^-force$/ ) { |
---|
74 | $force = "--force"; |
---|
75 | next; |
---|
76 | } |
---|
77 | if ( $option =~ /^-gen$/ ) { |
---|
78 | $gen++; |
---|
79 | next; |
---|
80 | } |
---|
81 | if ( $option =~ /^-nolinks$/ ) { |
---|
82 | $nolinks++; |
---|
83 | next; |
---|
84 | } |
---|
85 | die "Unknown command line option specified '$option'\n" . $notes; |
---|
86 | } |
---|
87 | |
---|
88 | $svntype = shift || die $notes; |
---|
89 | |
---|
90 | #--- get config.json info |
---|
91 | |
---|
92 | my $cfgjson = {}; |
---|
93 | my $cfgjsonf = "$gb/etc/config.json"; |
---|
94 | my $cfgjsonnotes = '-'x80 . "\n |
---|
95 | $cfgjsonf contains global system information. |
---|
96 | this is used to setup individual applications values. |
---|
97 | to build a default config.json file |
---|
98 | $gb/sbin/setconfig.pl -pj |
---|
99 | and verify the information is correct. |
---|
100 | Particularly, if the machine is not publically exposed, you probably want to change the hostip and hostname, as it will likely report the public ip of your firewall. |
---|
101 | The full options are listed by |
---|
102 | $gb/sbin/setconfig.pl -h |
---|
103 | You can also manually edit $cfgjsonf |
---|
104 | |
---|
105 | Once you are satisified that the setting are correct |
---|
106 | you can rerun $0 |
---|
107 | " . '-'x80 . "\n" |
---|
108 | ; |
---|
109 | |
---|
110 | { |
---|
111 | my $f = $cfgjsonf; |
---|
112 | if ( -e $f ) { |
---|
113 | print "reading $f\n"; |
---|
114 | open my $fh, $f || die "$0: can not open $f\n"; |
---|
115 | my @ol = <$fh>; |
---|
116 | close $fh; |
---|
117 | my @l = grep !/^\s*#/ , @ol; |
---|
118 | my $l = join '', @l; |
---|
119 | eval { |
---|
120 | $cfgjson = decode_json( $l ); |
---|
121 | 1; |
---|
122 | } || do { |
---|
123 | my $e = $@; |
---|
124 | |
---|
125 | # figure out line # |
---|
126 | |
---|
127 | my ( $cp ) = $e =~ /at character offset (\d+) /; |
---|
128 | my $i; |
---|
129 | my $cpos = $cp; |
---|
130 | for ( $i = 0; $i < @ol; ++$i ) { |
---|
131 | next if $ol[ $i ] =~ /^\s*#/; |
---|
132 | $cpos -= length( $ol[ $i ] ); |
---|
133 | last if $cpos < 0; |
---|
134 | } |
---|
135 | |
---|
136 | my $sline = $i - 2; |
---|
137 | my $eline = $i + 2; |
---|
138 | $sline = 0 if $sline < 0; |
---|
139 | $eline = @ol - 1 if $eline >= @ol; |
---|
140 | |
---|
141 | print "JSON Error in file $f near these lines:\n"; |
---|
142 | for ( my $j = $sline; $j <= $eline; ++$j ) { |
---|
143 | my $uj = $j + 1; |
---|
144 | print "$uj: $ol[$j]"; |
---|
145 | print "$uj: " .'^'x(length($ol[$j])) . "\n" if $j == $i; |
---|
146 | } |
---|
147 | die; |
---|
148 | }; |
---|
149 | } else { |
---|
150 | my $res = `$gb/sbin/setconfig.pl -pj`; |
---|
151 | print "$0 : |
---|
152 | " . '-'x80 . " |
---|
153 | please verify these settings are correct |
---|
154 | " . '-'x80 . " |
---|
155 | $res |
---|
156 | $cfgjsonnotes |
---|
157 | "; |
---|
158 | exit; |
---|
159 | } |
---|
160 | } |
---|
161 | |
---|
162 | sub listapps { |
---|
163 | my @l = `svn ls svn://$svnbase`; |
---|
164 | grep chomp, @l; |
---|
165 | grep s/\///, @l; |
---|
166 | @l = grep !/^genapp$/, @l; |
---|
167 | return @l; |
---|
168 | } |
---|
169 | |
---|
170 | if ( $svntype eq 'list' ) { |
---|
171 | print join "\n", listapps(); |
---|
172 | print "\n"; |
---|
173 | exit; |
---|
174 | } |
---|
175 | |
---|
176 | $app = shift || die $notes; |
---|
177 | $targetdir = $app if !$targetdir; |
---|
178 | |
---|
179 | die "$0: svn-type must be svn or svn+ssh and you specified '$svntype'\n" if $svntype !~ /^svn(\+ssh|)$/; |
---|
180 | |
---|
181 | die "$0: $targetdir directory already exists\n" if -e $targetdir && !$force; |
---|
182 | |
---|
183 | @l = listapps(); |
---|
184 | foreach $i ( @l ) { |
---|
185 | $vapp{ $i }++; |
---|
186 | } |
---|
187 | |
---|
188 | die "$0: Error: $app is not known as an application name\n" if !$vapp{ $app }; |
---|
189 | |
---|
190 | $cmd = "svn $force co ${svntype}://$svnbase/$app $targetdir"; |
---|
191 | |
---|
192 | print "$cmd\n"; |
---|
193 | |
---|
194 | print `$cmd`; |
---|
195 | die "$0: checkout failed. |
---|
196 | One possibility is you switched from svn to svn+ssh or vice-versa, if this is true, you will have to remove or rename the directory. |
---|
197 | Other possibilities include a network issue, host issue, local diskspace or permissions issue or ?\n" if $?; |
---|
198 | |
---|
199 | # sets up the app's appconfig.json: |
---|
200 | |
---|
201 | sub setappconfig { |
---|
202 | my $app = $_[0]; |
---|
203 | my $targetdir = $_[1]; |
---|
204 | my $admin = $_[2]; |
---|
205 | |
---|
206 | my $json = {}; |
---|
207 | $$json{ "hostip" } = $$cfgjson{ 'hostip' } || die "$0 hostip not defined in $cfgjsonf. $cfgjsonnotes"; |
---|
208 | $$json{ "hostname" } = $$cfgjson{ 'hostname' } || die "$0 hostname not defined in $cfgjsonf. $cfgjsonnotes"; |
---|
209 | |
---|
210 | $$json{ "messaging" }{ "wsport" } = $$cfgjson{ "messaging" }{ "wsport" } || die "$0 wsport not defined in $cfgjsonf. $cfgjsonnotes"; |
---|
211 | $$json{ "messaging" }{ "wssport" } = $$cfgjson{ "messaging" }{ "wssport" } || die "$0 wssport not defined in $cfgjsonf. $cfgjsonnotes"; |
---|
212 | $$json{ "messaging" }{ "zmqhostip" } = $$cfgjson{ "messaging" }{ "zmqhostip" } || die "$0 zmqhostip not defined in $cfgjsonf. $cfgjsonnotes"; |
---|
213 | $$json{ "messaging" }{ "zmqport" } = $$cfgjson{ "messaging" }{ "zmqport" } || die "$0 zmqport not defined in $cfgjsonf. $cfgjsonnotes"; |
---|
214 | $$json{ "messaging" }{ "udphostip" } = $$cfgjson{ "messaging" }{ "udphostip" } || die "$0 udphostip not defined in $cfgjsonf. $cfgjsonnotes"; |
---|
215 | $$json{ "messaging" }{ "udpport" } = $$cfgjson{ "messaging" }{ "udpport" } || die "$0 udpport not defined in $cfgjsonf. $cfgjsonnotes"; |
---|
216 | $$json{ "messaging" }{ "tcphostip" } = $$cfgjson{ "messaging" }{ "tcphostip" } || die "$0 tcphostip not defined in $cfgjsonf. $cfgjsonnotes"; |
---|
217 | $$json{ "messaging" }{ "tcpport" } = $$cfgjson{ "messaging" }{ "tcpport" } || die "$0 tcpport not defined in $cfgjsonf. $cfgjsonnotes"; |
---|
218 | |
---|
219 | $$json{ "restricted" }{ "admin" } = ( $admin ) if $admin; |
---|
220 | |
---|
221 | $$json{ "resources" }{ "local" } = ""; |
---|
222 | |
---|
223 | $$json{ "resourcedefault" } = "local"; |
---|
224 | $$json{ "submitpolicy" } = "login"; |
---|
225 | |
---|
226 | $$json{ "lockdir" } = "$gb/etc"; |
---|
227 | |
---|
228 | $f = "$targetdir/appconfig.json"; |
---|
229 | open $fh, ">$f" || die "$0: could not open $f for writing\n"; |
---|
230 | print $fh to_json( $json, { utf8 => 1, pretty => 1 } ); |
---|
231 | close $fh; |
---|
232 | print "created $f\n"; |
---|
233 | } |
---|
234 | |
---|
235 | setappconfig( $app, $targetdir, $admin ); |
---|
236 | |
---|
237 | # setup directives.json |
---|
238 | |
---|
239 | my $devmsg = "You can subscribe to the mailing list http://biochem.uthscsa.edu/mailman/listinfo/genapp-devel |
---|
240 | and then send your questions to genapp-devel\@biochem.uthscsa.edu\n"; |
---|
241 | |
---|
242 | sub setdirectives { |
---|
243 | my $app = $_[0]; |
---|
244 | my $targetdir = $_[1]; |
---|
245 | my $webroot = $_[2]; |
---|
246 | |
---|
247 | my $f = "directives.json.template"; |
---|
248 | my $fo = "directives.json"; |
---|
249 | |
---|
250 | die "$0: $targetdir/$f does not exist for this application. |
---|
251 | This is an error of the application developer and they should be informed.\n$devmsg" if !-e "$targetdir/$f"; |
---|
252 | |
---|
253 | die "$0: $targetdir/$fo already exists for this application. |
---|
254 | This file must be manually removed before continuing. |
---|
255 | If this error recurrs after removing, |
---|
256 | This is an error of the application developer and they should be informed.\n$devmsg" if -e "$targetdir/$fo"; |
---|
257 | |
---|
258 | my $djson = get_file_json( "$targetdir/$f" ); |
---|
259 | |
---|
260 | open my $fh, "$targetdir/$f" || die "$0: file open error on $targetdir/$f\n"; |
---|
261 | my @l = <$fh>; |
---|
262 | close $fh; |
---|
263 | |
---|
264 | my $dir = `pwd`; |
---|
265 | chomp $dir; |
---|
266 | |
---|
267 | die "$0: $targetdir/$f error, missing __app_parent_directory__ tags. |
---|
268 | This is an error of the application developer and they should be informed.\n$devmsg" if !( grep /__app_parent_directory__/, @l ); |
---|
269 | |
---|
270 | die "$0: $targetdir/$f error, missing __webroot__ tags. |
---|
271 | This is an error of the application developer and they should be informed.\n$devmsg" if !( grep /__webroot__/, @l ); |
---|
272 | |
---|
273 | # die "$0: $targetdir/$f error, missing __application__ tags. |
---|
274 | # This is an error of the application developer and they should be informed.\n$devmag" if !( grep /__application__/, @l ); |
---|
275 | |
---|
276 | grep s/__app_parent_directory__/$dir/g, @l; |
---|
277 | |
---|
278 | grep s/__webroot__/$webroot/g, @l; |
---|
279 | |
---|
280 | # grep s/__application__/$app/g, @l; |
---|
281 | |
---|
282 | if ( $app ne $targetdir ) { |
---|
283 | grep s/"$app"/"$targetdir"/g, @l; |
---|
284 | grep s/\/$app\//\/$targetdir\//g, @l; |
---|
285 | } |
---|
286 | |
---|
287 | if ( $$djson{ 'usewss' } && !$$cfgjson{ 'https' } ) { |
---|
288 | @l = grep !/"usewss"/, @l; |
---|
289 | } |
---|
290 | |
---|
291 | if ( $$djson{ 'usews' } && $$cfgjson{ 'https' } ) { |
---|
292 | @l = grep !/"usews"/, @l; |
---|
293 | } |
---|
294 | |
---|
295 | # strip white space and comments from end of array |
---|
296 | while ( $l[ -1 ] =~ /^(#.*|\s*)$/ ) { |
---|
297 | pop @l; |
---|
298 | } |
---|
299 | |
---|
300 | die "$0 : $targetdir/$f error: can not locate json closure. |
---|
301 | This is an error of the application developer and they should be informed.\n$devmsg" if $l[ -1 ] !~ /^\s*}\s*$/; |
---|
302 | |
---|
303 | pop @l; |
---|
304 | push @l, ( $$cfgjson{ 'https' } ? " ,\"usewss\" : \"true\"\n" : " ,\"usews\" : \"true\"\n" ); |
---|
305 | push @l, "}\n"; |
---|
306 | |
---|
307 | open $fh, ">$targetdir/$fo" || die "$0: could not open $targetdir/$fo for writing\n"; |
---|
308 | print $fh ( join '', @l ); |
---|
309 | close $fh; |
---|
310 | print "created $targetdir/$fo\n"; |
---|
311 | } |
---|
312 | |
---|
313 | setdirectives( $app, $targetdir, $$cfgjson{'webroot'} ); |
---|
314 | |
---|
315 | sub runcmd { |
---|
316 | my $cmd = $_[0]; |
---|
317 | my $out; |
---|
318 | print "running shell command:\n--------\n$cmd\n--------\n" if $debug; |
---|
319 | open my $fh, "$cmd |"; |
---|
320 | while ( <$fh> ) { |
---|
321 | $out .= $_; |
---|
322 | print; |
---|
323 | } |
---|
324 | close $fh; |
---|
325 | die "$0: command $cmd failed\n" if $?; |
---|
326 | $out; |
---|
327 | } |
---|
328 | |
---|
329 | sub runcmdsb { |
---|
330 | my $cmd = $_[0]; |
---|
331 | $cmd =~ s/"/\\\"/g; |
---|
332 | $cmd = "sudo bash -c \"$cmd\""; |
---|
333 | print "sd cmd is <$cmd>\n" if $debug; |
---|
334 | runcmd( $cmd ); |
---|
335 | } |
---|
336 | |
---|
337 | if ( $gen ) { |
---|
338 | runcmd( "cd $targetdir; env GENAPP=$gb \$GENAPP/bin/genapp.pl" ); |
---|
339 | if ( !$nolinks ) { |
---|
340 | my $dir = `pwd`; |
---|
341 | chomp $dir; |
---|
342 | my $cmds = |
---|
343 | "cd $targetdir |
---|
344 | ln -sf $dir/$targetdir/output/html5 $$cfgjson{'webroot'}/$targetdir |
---|
345 | mkdir -p output/html5/results output/html5/deleted 2> /dev/null |
---|
346 | rm ajax results util 2> /dev/null |
---|
347 | ln -sf output/html5/ajax ajax && ln -sf output/html5/results results && ln -sf output/html5/util util |
---|
348 | chgrp -R genapp . && chmod -R g+rw . && find . -type d | xargs chmod g+xs |
---|
349 | "; |
---|
350 | print "Setting up via these commands: |
---|
351 | $cmds"; |
---|
352 | runcmdsb( $cmds ); |
---|
353 | } |
---|
354 | } |
---|
355 | |
---|