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