comparison scripts/installer/install @ 10:a50cf11e5178

Rewrite LGDataverse completely upgrading to dataverse4.0
author Zoe Hong <zhong@mpiwg-berlin.mpg.de>
date Tue, 08 Sep 2015 17:00:21 +0200
parents
children
comparison
equal deleted inserted replaced
9:5926d6419569 10:a50cf11e5178
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5 use Getopt::Long;
6 use Socket;
7 use File::Copy;
8
9 my $verbose;
10 my $pg_only;
11 my $hostname;
12 my $gfdir;
13 my $mailserver;
14 my $yes;
15 my $force;
16 my $nogfpasswd;
17 my ($rez) = GetOptions(
18 #"length=i" => \$length, # numeric
19 #"file=s" => \$data, # string
20 "verbose" => \$verbose,
21 "pg_only" => \$pg_only,
22 "hostname=s" => \$hostname,
23 "gfdir=s" => \$gfdir,
24 "mailserver=s" => \$mailserver,
25 "y|yes" => \$yes,
26 "f|force" => \$force,
27 "nogfpasswd" => \$nogfpasswd,
28 );
29
30 my $postgresonly = 0;
31
32 my @CONFIG_VARIABLES = (
33 'HOST_DNS_ADDRESS',
34 'GLASSFISH_DIRECTORY',
35 'MAIL_SERVER',
36
37 'POSTGRES_SERVER',
38 'POSTGRES_PORT',
39 'POSTGRES_DATABASE',
40 'POSTGRES_USER',
41 'POSTGRES_PASSWORD',
42
43 'RSERVE_HOST',
44 'RSERVE_PORT',
45 'RSERVE_USER',
46 'RSERVE_PASSWORD'
47
48 );
49
50 if ($pg_only) {
51 # exit;
52 @CONFIG_VARIABLES =
53 ( 'POSTGRES_SERVER', 'POSTGRES_PORT', 'POSTGRES_DATABASE', 'POSTGRES_USER', 'POSTGRES_PASSWORD' );
54
55 $postgresonly = 1;
56 }
57
58 # TODO:
59 # supply pre-set, default values in a text file;
60 # this way we can provide different sets of default
61 # values, for the installers intended for different
62 # groups of users - local developers vs. "real"
63 # dataverse users.
64
65 my %CONFIG_DEFAULTS = (
66 'HOST_DNS_ADDRESS', 'localhost',
67 'GLASSFISH_DIRECTORY', '/usr/local/glassfish4',
68 'MAIL_SERVER', 'mail.hmdc.harvard.edu',
69
70 'POSTGRES_SERVER', 'localhost',
71 'POSTGRES_PORT', 5432,
72 'POSTGRES_DATABASE', 'dvndb',
73 'POSTGRES_USER', 'dvnapp',
74 'POSTGRES_PASSWORD', 'secret',
75
76 'RSERVE_HOST', 'localhost',
77 'RSERVE_PORT', 6311,
78 'RSERVE_USER', 'rserve',
79 'RSERVE_PASSWORD', 'rserve'
80
81 );
82
83 my %CONFIG_PROMPTS = (
84 'HOST_DNS_ADDRESS', 'Internet Address of your host',
85 'GLASSFISH_DIRECTORY', 'Glassfish Directory',
86 'MAIL_SERVER', 'SMTP (mail) server to relay notification messages',
87
88 'POSTGRES_SERVER', 'Postgres Server',
89 'POSTGRES_PORT', 'Postgres Server Port',
90 'POSTGRES_DATABASE', 'Name of the Postgres Database',
91 'POSTGRES_USER', 'Name of the Postgres User',
92 'POSTGRES_PASSWORD', 'Postgres user password',
93
94 'RSERVE_HOST', 'Rserve Server',
95 'RSERVE_PORT', 'Rserve Server Port',
96 'RSERVE_USER', 'Rserve User Name',
97 'RSERVE_PASSWORD', 'Rserve User Password'
98
99 );
100
101 # Supported Posstgres JDBC drivers:
102 # (have to be configured explicitely, so that Perl "taint" (security) mode
103 # doesn't get paranoid)
104
105 my %POSTGRES_DRIVERS = (
106 # "8_4", "postgresql-8.3-603.jdbc4.jar",
107 "8_4", "postgresql-8.4-703.jdbc4.jar",
108 "9_0", "postgresql-9.0-802.jdbc4.jar",
109 "9_1", "postgresql-9.1-902.jdbc4.jar",
110 "9_2", "postgresql-9.1-902.jdbc4.jar",
111 "9_3", "postgresql-9.1-902.jdbc4.jar"
112 );
113
114 # A few preliminary checks:
115
116 # user -- must be root:
117
118 my $user_real = `who am i`;
119 chop $user_real;
120 $user_real =~ s/ .*$//;
121
122 if ( $< != 0 ) {
123 print STDERR "\nERROR: You must be logged in as root to run the installer.\n\n";
124 exit 1;
125 }
126
127 # OS:
128
129 my $uname_out = `uname -a`;
130
131 # hostname:
132
133 my $hostname_from_cmdline = `hostname`;
134 chop $hostname_from_cmdline;
135
136 if ($hostname) {
137 $CONFIG_DEFAULTS{'HOST_DNS_ADDRESS'} = $hostname;
138 }
139 else {
140 $CONFIG_DEFAULTS{'HOST_DNS_ADDRESS'} = $hostname_from_cmdline;
141 }
142
143 if ($mailserver) {
144 $CONFIG_DEFAULTS{'MAIL_SERVER'} = $mailserver;
145 }
146
147 if ($gfdir) {
148 $CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'} = $gfdir;
149 }
150
151 print "\nWelcome to the Dataverse installer.\n";
152 unless ($postgresonly) {
153 print "You will be guided through the process of setting up a NEW\n";
154 print "instance of the dataverse application\n";
155 }
156 else {
157 print "You will be guided through the process of configuring the\n";
158 print "LOCAL instance of PostgreSQL database for use by the DVN\n";
159 print "application.\n";
160 }
161
162 my @uname_tokens = split( " ", $uname_out );
163
164 my $WORKING_OS;
165 if ( $uname_tokens[0] eq "Darwin" ) {
166 print "\nThis appears to be a MacOS X system; good.\n";
167 # TODO: check the OS version
168
169 $WORKING_OS = "MacOSX";
170 }
171 elsif ( $uname_tokens[0] eq "Linux" ) {
172 if ( -f "/etc/redhat-release" ) {
173 print "\nThis appears to be a RedHat system; good.\n";
174 $WORKING_OS = "RedHat";
175 # TODO: check the distro version
176 }
177 else {
178 print "\nThis appears to be a non-RedHat Linux system;\n";
179 print "this installation *may* succeed; but we're not making any promises!\n";
180 $WORKING_OS = "Linux";
181 }
182 }
183 else {
184 print "\nWARNING: This appears to be neither a Linux or MacOS X system!\n";
185 print "This installer script will most likely fail. Please refer to the\n";
186 print "DVN Installers Guide for more information.\n\n";
187
188 $WORKING_OS = "Unknown";
189
190 print "Do you wish to continue?\n [y/n] ";
191
192 my $yesnocont;
193
194 if ($yes) {
195 $yesnocont = "y";
196 }
197 else {
198 print "here";
199 exit;
200 $yesnocont = <>;
201 chop $yesnocont;
202 }
203
204 while ( $yesnocont ne "y" && $yesnocont ne "n" ) {
205 print "Please enter 'y' or 'n'!\n";
206 print "(or ctrl-C to exit the installer)\n";
207 $yesnocont = <>;
208 chop $yesnocont;
209 }
210
211 if ( $yesnocont eq "n" ) {
212 exit 0;
213 }
214
215 }
216
217 ENTERCONFIG:
218
219 print "\n";
220 print "Please enter the following configuration values:\n";
221 print "(hit [RETURN] to accept the default value)\n";
222 print "\n";
223
224 for my $ENTRY (@CONFIG_VARIABLES) {
225 print $CONFIG_PROMPTS{$ENTRY} . ": ";
226 print "[" . $CONFIG_DEFAULTS{$ENTRY} . "] ";
227
228 my $user_entry;
229 unless ($yes) {
230 $user_entry = <>;
231 chop $user_entry;
232 }
233
234 if ( $user_entry ne "" ) {
235 $CONFIG_DEFAULTS{$ENTRY} = $user_entry;
236 }
237
238 print "\n";
239 }
240
241 # CONFIRM VALUES ENTERED:
242
243 print "\nOK, please confirm what you've entered:\n\n";
244
245 for my $ENTRY (@CONFIG_VARIABLES) {
246 print $CONFIG_PROMPTS{$ENTRY} . ": " . $CONFIG_DEFAULTS{$ENTRY} . "\n";
247 }
248
249 my $yesno;
250 if ($yes) {
251 $yesno = "y";
252 }
253 else {
254 print "\nIs this correct? [y/n] ";
255 $yesno = <>;
256 chop $yesno;
257 }
258
259 while ( $yesno ne "y" && $yesno ne "n" ) {
260 print "Please enter 'y' or 'n'!\n";
261 print "(or ctrl-C to exit the installer)\n";
262 $yesno = <>;
263 chop $yesno;
264 }
265
266 if ( $yesno eq "n" ) {
267 goto ENTERCONFIG;
268 }
269
270 # VALIDATION/VERIFICATION OF THE CONFIGURATION VALUES:
271 # 1. VERIFY MAIL SERVER THEY CONFIGURED:
272
273 unless ($postgresonly) {
274
275 my ( $mail_server_iaddr, $mail_server__paddr, $mail_server_proto, $mail_server_status );
276
277 $mail_server_status = 1;
278
279 unless ( $mail_server_iaddr = inet_aton( $CONFIG_DEFAULTS{'MAIL_SERVER'} ) ) {
280 print STDERR "Could not look up $CONFIG_DEFAULTS{'MAIL_SERVER'},\n";
281 print STDERR "the host you specified as your mail server\n";
282 $mail_server_status = 0;
283 }
284
285 if ($mail_server_status) {
286 my $mail_server_paddr = sockaddr_in( 25, $mail_server_iaddr );
287 $mail_server_proto = getprotobyname('tcp');
288
289 unless ( socket( SOCK, PF_INET, SOCK_STREAM, $mail_server_proto )
290 && connect( SOCK, $mail_server_paddr ) )
291 {
292 print STDERR "Could not establish connection to $CONFIG_DEFAULTS{'MAIL_SERVER'},\n";
293 print STDERR "the address you provided for your Mail server.\n";
294 print STDERR "Please select a valid mail server, and try again.\n\n";
295
296 $mail_server_status = 0;
297 }
298
299 }
300
301 close(SOCK);
302
303 unless ($mail_server_status) {
304 goto ENTERCONFIG;
305 }
306 }
307
308 # 2. CHECK IF THE WAR FILE IS AVAILABLE:
309
310 my $WARFILE_LOCATION = "../../target/dataverse-4.0.war";
311
312 unless ( -f $WARFILE_LOCATION ) {
313 $WARFILE_LOCATION = "dataverse-4.0.war";
314 }
315
316 unless ( -f $WARFILE_LOCATION ) {
317 print "\nWARNING: Can't find the project .war file!\n";
318 print "\tAre you running the installer in the right directory?\n";
319 print "\tHave you built the war file?\n";
320 print "\t(if not, build the project and run the installer again)\n";
321
322 exit 0;
323 }
324
325 # check the working (installer) dir:
326 my $cwd;
327 chomp( $cwd = `pwd` );
328
329 # 2b. CHECK IF THE SQL TEMPLATE IS IN PLACE AND CREATE THE SQL FILE
330
331 my $SQL_REFERENCE_DATA = "reference_data_filtered.sql";
332 my $SQL_REFERENCE_TEMPLATE = "../database/reference_data.sql";
333
334 unless ( -f $SQL_REFERENCE_TEMPLATE ) {
335 $SQL_REFERENCE_TEMPLATE = "reference_data.sql";
336 }
337
338 unless ( -f $SQL_REFERENCE_TEMPLATE ) {
339 print "\nWARNING: Can't find .sql data template!\n";
340 print "(are you running the installer in the right directory?)\n";
341
342 exit 0;
343 }
344
345 open DATATEMPLATEIN, $SQL_REFERENCE_TEMPLATE || die $@;
346 open SQLDATAOUT, '>' . $SQL_REFERENCE_DATA || die $@;
347
348 while (<DATATEMPLATEIN>) {
349 s/dvnapp/$CONFIG_DEFAULTS{'POSTGRES_USER'}/g;
350 print SQLDATAOUT $_;
351 }
352
353 close DATATEMPLATEIN;
354 close SQLDATAOUT;
355
356 # 3. CHECK POSTGRES AND JQ AVAILABILITY:
357
358 my $pg_local_connection = 0;
359 my $psql_exec;
360 my $jq_exec = "";
361 my $pg_major_version = 0;
362 my $pg_minor_version = 0;
363
364 my $POSTGRES_SYS_UID;
365 if ( $CONFIG_DEFAULTS{'POSTGRES_SERVER'} eq 'localhost' ) {
366 $pg_local_connection = 1;
367
368 # 3a. CHECK FOR USER postgres:
369
370 print "\nChecking system user \"postgres\"... ";
371
372 my $POSTGRES_SYS_NAME = "postgres";
373 $POSTGRES_SYS_UID = ( getpwnam("postgres") )[2];
374
375 unless ($POSTGRES_SYS_UID) {
376 print STDERR "\nERROR: I haven't been able to find user \"postgres\" on the system! Is PostgreSQL installed?\n";
377 print STDERR "(TODO: prompt the user instead to supply an alternative username, if\n";
378 print STDERR "available)\n";
379
380 exit 1;
381 }
382
383 print "OK.\n";
384
385 # 3b. LOCATE THE EXECUTABLE:
386
387 my $sys_path = $ENV{'PATH'};
388 my @sys_path_dirs = split( ":", $sys_path );
389
390 $psql_exec = "";
391
392 for my $sys_path_dir (@sys_path_dirs) {
393 if ( -x $sys_path_dir . "/psql" ) {
394 $psql_exec = $sys_path_dir;
395 last;
396 }
397 }
398
399 for my $sys_path_dir (@sys_path_dirs) {
400 if ( -x $sys_path_dir . "/jq" ) {
401 $jq_exec = $sys_path_dir;
402 last;
403 }
404 }
405 if ( $jq_exec eq "" ) {
406 print STDERR "\nERROR: I haven't been able to find the jq command in your PATH! Please install it from http://stedolan.github.io/jq/\n";
407 exit 1;
408
409 }
410
411 my $psql_major_version = 0;
412 my $psql_minor_version = 0;
413
414 # 3c. IF PSQL WAS FOUND IN THE PATH, CHECK ITS VERSION:
415
416 unless ( $psql_exec eq "" ) {
417 open( PSQLOUT, $psql_exec . "/psql --version|" );
418
419 my $psql_version_line = <PSQLOUT>;
420 chop $psql_version_line;
421 close PSQLOUT;
422
423 my ( $postgresName, $postgresNameLong, $postgresVersion ) = split( " ", $psql_version_line );
424
425 unless ( $postgresName eq "psql" && $postgresVersion =~ /^[0-9][0-9\.]*$/ ) {
426 print STDERR "\nWARNING: Unexpected output from psql command!\n";
427 }
428 else {
429 my (@psql_version_tokens) = split( '\.', $postgresVersion );
430
431 print "\n\nFound Postgres psql command, version $postgresVersion.\n\n";
432
433 $psql_major_version = $psql_version_tokens[0];
434 $psql_minor_version = $psql_version_tokens[1];
435
436 $pg_major_version = $psql_major_version;
437 $pg_minor_version = $psql_minor_version;
438
439 }
440 }
441
442 # a frequent problem with MacOSX is that the copy of psql found in the PATH
443 # belongs to the older version of PostgresQL supplied with the OS, which happens
444 # to be incompatible with the newer builds from the Postgres project; which are
445 # recommended to be used with dataverse. So if this is a MacOSX box, we'll
446 # check what other versions of PG are available, and select the highest version
447 # we can find:
448
449 if ( $WORKING_OS eq "MacOSX" ) {
450 my $macos_pg_major_version = 0;
451 my $macos_pg_minor_version = 0;
452
453 for $macos_pg_minor_version ( "3", "2", "1", "0" ) {
454 if ( -x "/Library/PostgreSQL/9." . $macos_pg_minor_version . "/bin/psql" ) {
455 $macos_pg_major_version = 9;
456 if ( ( $macos_pg_major_version > $psql_major_version )
457 || ( $macos_pg_minor_version >= $psql_minor_version ) )
458 {
459 $psql_exec = "/Library/PostgreSQL/9." . $macos_pg_minor_version . "/bin";
460 $pg_major_version = $macos_pg_major_version;
461 $pg_minor_version = $macos_pg_minor_version;
462 }
463 last;
464 }
465 }
466
467 # And if we haven't found an 9.* version of postgresql installed, we'll also check
468 # for version 8.* available:
469
470 if ( $macos_pg_major_version < 9 ) {
471 for $macos_pg_minor_version ( "4", "3" )
472 # TODO:
473 # Do we even want to support postgres 8.3?
474 {
475 if ( -x "/Library/PostgreSQL/8." . $macos_pg_minor_version . "/bin/psql" ) {
476 $macos_pg_major_version = 8;
477 if ( $macos_pg_major_version > $psql_major_version
478 || $macos_pg_minor_version > $psql_minor_version )
479 {
480 $psql_exec = "/Library/PostgreSQL/8." . $macos_pg_minor_version . "/bin";
481 $pg_major_version = $macos_pg_major_version;
482 $pg_minor_version = $macos_pg_minor_version;
483 }
484 last;
485 }
486 }
487 }
488 }
489
490 if ( $psql_exec eq "" ) {
491 print STDERR "\nERROR: I haven't been able to find the psql command in your PATH!\n";
492 print STDERR "Please make sure PostgresQL is properly installed; if necessary, add\n";
493 print STDERR "the location of psql to the PATH, then try again.\n\n";
494
495 exit 1;
496 }
497
498 if ( $pg_major_version == 0 ) {
499 }
500
501 # 4. CONFIGURE POSTGRES:
502
503 print "\nConfiguring Postgres Database:\n";
504 print "(Using psql version " . $pg_major_version . "." . $pg_minor_version . ")\n";
505
506 $< = $POSTGRES_SYS_UID;
507 $> = $POSTGRES_SYS_UID;
508
509 # 4a. CHECK IF POSTGRES IS RUNNING:
510 print "Checking if a local instance of Postgres is running and accessible...\n";
511
512 # (change to /tmp before executing the command below -
513 # we are trying to do it as user postgres, and it may not have
514 # access to the current, installer directory; the command would still
515 # work, but there would be an error message from the shell init on screen
516 # - potentially confusing)
517
518 chdir("/tmp");
519
520 if ( !system( $psql_exec . "/psql -c 'SELECT * FROM pg_roles' > /dev/null 2>&1" ) ) {
521 print "Yes, it is.\n";
522 }
523 else {
524 print "Nope, I haven't been able to connect to the local instance of PostgresQL.\n";
525 print "daemon. Is postgresql running? \n";
526 print "On a RedHat-like system, you can check the status of the daemon with\n\n";
527 print " service postgresql status\n\n";
528 print "and, if it's not running, start the daemon with\n\n";
529 print " service postgresql start\n\n";
530 print "On MacOSX, use Applications -> PostgresQL -> Start Server.\n";
531 print "(or, if there's no \"Start Server\" item in your PostgresQL folder, \n";
532 print "simply restart your MacOSX system!)\n";
533 print "Also, please make sure that the daemon is listening to network connections,\n";
534 print "at least on the localhost interface. (See \"Installing Postgres\" section\n";
535 print "of the installation manual).\n";
536 print "Finally, please make sure that the postgres user can make localhost \n";
537 print "connections without supplying a password. (That's controlled by the \n";
538 print "\"localhost ... ident\" line in pg_hba.conf; again, please consult the \n";
539 print "installation manual).\n";
540
541 exit 1;
542 }
543
544 # 4c. CHECK IF THIS DB ALREADY EXISTS:
545
546 my $psql_command_dbcheck =
547 $psql_exec . "/psql -c \"\" -d " . $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} . ">/dev/null 2>&1";
548 if ($force) {
549 print "WARNING! Database "
550 . $CONFIG_DEFAULTS{'POSTGRES_DATABASE'}
551 . " already exists but --force given... continuing.\n";
552 }
553 elsif ( ( my $exitcode = system($psql_command_dbcheck) ) == 0 ) {
554 $> = 0;
555 $< = 0;
556
557 chdir($cwd);
558
559 print "WARNING! Database " . $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} . " already exists!\n";
560 print "\nPlease note that you can only use this installer to create a blank, \n";
561 print "new and shiny DVN database. I.e., you cannot install on top of an \n";
562 print "existing database. Please enter a different name for the DVN database.\n";
563 print "\nPress any key to continue, or ctrl-C to exit the installer...\n\n";
564
565 system "stty cbreak </dev/tty >/dev/tty 2>&1";
566 my $key = getc(STDIN);
567 system "stty -cbreak </dev/tty >/dev/tty 2>&1";
568 print "\n";
569
570 goto ENTERCONFIG;
571
572 }
573
574 # 4d. CHECK IF THIS USER ALREADY EXISTS:
575
576 my $psql_command_rolecheck =
577 $psql_exec . "/psql -c \"\" -d postgres " . $CONFIG_DEFAULTS{'POSTGRES_USER'} . " >/dev/null 2>&1";
578 if ( ( my $exitcode = system($psql_command_rolecheck) ) == 0 ) {
579 print "User (role) " . $CONFIG_DEFAULTS{'POSTGRES_USER'} . " already exists;\n";
580 print "Proceeding.";
581 }
582 else {
583 # 4e. CREATE DVN DB USER:
584
585 print "\nCreating Postgres user (role) for the DVN:\n";
586
587 open TMPCMD, ">/tmp/pgcmd.$$.tmp";
588
589 # with md5-encrypted password:
590 my $pg_password_md5 =
591 &create_pg_hash( $CONFIG_DEFAULTS{'POSTGRES_USER'}, $CONFIG_DEFAULTS{'POSTGRES_PASSWORD'} );
592 my $sql_command =
593 "CREATE ROLE \""
594 . $CONFIG_DEFAULTS{'POSTGRES_USER'}
595 . "\" PASSWORD 'md5"
596 . $pg_password_md5
597 . "' NOSUPERUSER CREATEDB CREATEROLE INHERIT LOGIN";
598
599 print TMPCMD $sql_command;
600 close TMPCMD;
601
602 my $psql_commandline = $psql_exec . "/psql -f /tmp/pgcmd.$$.tmp >/dev/null 2>&1";
603
604 my $out = qx($psql_commandline 2>&1);
605 my $exitcode = $?;
606 unless ( $exitcode == 0 ) {
607 print STDERR "Could not create the DVN Postgres user role!\n";
608 print STDERR "(SQL: " . $sql_command . ")\n";
609 print STDERR "(psql exit code: " . $exitcode . ")\n";
610 print STDERR "(STDERR and STDOUT was: " . $out . ")\n";
611 exit 1;
612 }
613
614 unlink "/tmp/pgcmd.$$.tmp";
615 print "done.\n";
616 }
617
618 # 4f. CREATE DVN DB:
619
620 print "\nCreating Postgres database:\n";
621
622 my $psql_command =
623 $psql_exec
624 . "/createdb "
625 . $CONFIG_DEFAULTS{'POSTGRES_DATABASE'}
626 . " --owner="
627 . $CONFIG_DEFAULTS{'POSTGRES_USER'};
628
629 my $out = qx($psql_command 2>&1);
630 my $exitcode = $?;
631 unless ( $exitcode == 0 ) {
632 print STDERR "Could not create Postgres database for the DVN app!\n";
633 print STDERR "(command: " . $psql_command . ")\n";
634 print STDERR "(psql exit code: " . $exitcode . ")\n";
635 print STDERR "(STDOUT and STDERR: " . $out . ")\n";
636 if ($force) {
637 print STDERR "\n--force called, continuing\n";
638 }
639 else {
640 print STDERR "\naborting the installation (sorry!)\n\n";
641 exit 1;
642 }
643 }
644
645 # Changing back to root UID:
646
647 $> = 0;
648 $< = 0;
649
650 chdir($cwd);
651
652 }
653 else {
654 if (0) { # THE LINES BELOW WERE PART OF THE 3.* "DEV." INSTALLER:
655 # DO WE STILL WANT TO MAINTAIN THIS FUNCTIONALITY IN 4.0?
656 print "\nIt is strongly recommended that you use a local PostgresQL server,\n";
657 print "running on localhost, in your development environment!\n\n";
658
659 print "Do you wish to continue?\n [y/n] ";
660
661 my $yesnocont = <>;
662 chop $yesnocont;
663
664 while ( $yesnocont ne "y" && $yesnocont ne "n" ) {
665 print "Please enter 'y' or 'n'!\n";
666 print "(or ctrl-C to exit the installer)\n";
667 $yesnocont = <>;
668 chop $yesnocont;
669 }
670
671 if ( $yesnocont eq "n" ) {
672 print "(aborting the installation)\n" . exit 0;
673 }
674 }
675
676 if ($pg_only) {
677 print "The script must be run in the --pg_only mode ONLY locally,\n";
678 print "i.e., on the server where PostgresQL is running.\n";
679
680 exit 1;
681 }
682
683 print "In order to use a PostgresQL database running on a remote server,\n";
684 print "Please run this installer on that host with the \"--pg_only\" option:\n\n";
685 print "./install --pg_only\n\n";
686
687 print "Press any key to continue the installation process once that has been\n";
688 print "done. Or press ctrl-C to exit the installer.\n\n";
689
690 chdir("/tmp");
691 system "stty cbreak </dev/tty >/dev/tty 2>&1";
692 my $key = getc(STDIN);
693 system "stty -cbreak </dev/tty >/dev/tty 2>&1";
694 print "\n";
695 chdir($cwd);
696
697 # Check if the role and database have been created on the remote server:
698 # -- TODO;
699
700 # Find out what Postgres version is running remotely:
701
702 $pg_major_version = 9;
703 $pg_minor_version = 1;
704
705 print "What version of PostgresQL is installed on the remote server?\n ["
706 . $pg_major_version . "."
707 . $pg_minor_version . "] ";
708
709 my $postgresVersion = <>;
710 chop $postgresVersion;
711
712 while ( $postgresVersion ne "" && !( $postgresVersion =~ /^[0-9]+\.[0-9]+$/ ) ) {
713 print "Please enter valid Postgres version!\n";
714 print "(or ctrl-C to exit the installer)\n";
715 $postgresVersion = <>;
716 chop $postgresVersion;
717 }
718
719 unless ( $postgresVersion eq "" ) {
720 my (@postgres_version_tokens) = split( '\.', $postgresVersion );
721
722 unless ( ( $postgres_version_tokens[0] == 8 && $postgres_version_tokens[1] >= 4 )
723 || ( $postgres_version_tokens[0] >= 9 ) )
724 {
725 print STDERR "\nERROR: PostgresQL version 8.4, or newer, is required!\n";
726 print STDERR "Please make sure the right version of PostgresQL is properly installed\n";
727 print STDERR "on the remote server, then try again.\n";
728
729 exit 1;
730 }
731
732 $pg_major_version = $postgres_version_tokens[0];
733 $pg_minor_version = $postgres_version_tokens[1];
734 }
735
736 }
737
738 if ($postgresonly) {
739 print "\nOK, done.\n";
740 print "You can now resume the installation on the main DVN host.\n\n";
741
742 exit 0;
743 }
744
745 # 5. CONFIGURE GLASSFISH
746
747 print "\nProceeding with the Glassfish setup.\n";
748 print "\nChecking your Glassfish installation...";
749
750 my $glassfish_dir = $CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'};
751
752 # 5a. CHECK IF GLASSFISH DIR LOOKS OK:
753
754 unless ( -d $glassfish_dir . "/glassfish/domains/domain1" ) {
755 # TODO: need better check than this
756
757 while ( !( -d $glassfish_dir . "/glassfish/domains/domain1" ) ) {
758 print "\nInvalid Glassfish directory " . $glassfish_dir . "!\n";
759 print "Enter the root directory of your Glassfish installation:\n";
760 print "(Or ctrl-C to exit the installer): ";
761
762 $glassfish_dir = <>;
763 chop $glassfish_dir;
764 }
765 }
766
767 print "OK!\n";
768
769 # 5b. DETERMINE HOW MUCH MEMORY TO GIVE TO GLASSFISH AS HEAP:
770
771 my $gf_heap_default = "2048m";
772 my $sys_mem_total = 0;
773
774 if ( -e "/proc/meminfo" && open MEMINFO, "/proc/meminfo" ) {
775 # Linux
776
777 while ( my $mline = <MEMINFO> ) {
778 if ( $mline =~ /MemTotal:[ \t]*([0-9]*) kB/ ) {
779 $sys_mem_total = $1;
780 }
781 }
782
783 close MEMINFO;
784
785 }
786 elsif ( -x "/usr/sbin/sysctl" ) {
787 # MacOS X, probably...
788
789 $sys_mem_total = `/usr/sbin/sysctl -n hw.memsize`;
790 chop $sys_mem_total;
791 if ( $sys_mem_total > 0 ) {
792 $sys_mem_total = int( $sys_mem_total / 1024 );
793 # size in kb
794 }
795 }
796
797 if ( $sys_mem_total > 0 ) {
798 # setting the default heap size limit to 3/8 of the available
799 # amount of memory:
800 $gf_heap_default = ( int( $sys_mem_total / ( 8 / 3 * 1024 ) ) );
801
802 print "\nSetting the heap limit for Glassfish to " . $gf_heap_default . "MB. \n";
803 print "You may need to adjust this setting to better suit \n";
804 print "your system.\n\n";
805
806 #$gf_heap_default .= "m";
807
808 }
809 else {
810 print "\nCould not determine the amount of memory on your system.\n";
811 print "Setting the heap limit for Glassfish to 2GB. You may need \n";
812 print "to adjust the value to better suit your system.\n\n";
813 }
814
815 push @CONFIG_VARIABLES, "DEF_MEM_SIZE";
816 $CONFIG_DEFAULTS{"DEF_MEM_SIZE"} = $gf_heap_default;
817
818 # TODO:
819 # if the system has more than 4GB of memory (I believe), glassfish must
820 # be run with the 64 bit flag set explicitly (at least that was the case
821 # with the MacOS glassfish build...). Verify, and if still the case,
822 # add a check.
823
824 print "\nInstalling the Glassfish PostgresQL driver... ";
825
826 my $install_driver_jar = "";
827
828 $install_driver_jar = $POSTGRES_DRIVERS{ $pg_major_version . "_" . $pg_minor_version };
829
830 unless ( $install_driver_jar && -e "pgdriver/" . $install_driver_jar ) {
831 die "Installer could not find POSTGRES JDBC driver for your version of PostgresQL!\n("
832 . $pg_major_version . "."
833 . $pg_minor_version . ")";
834
835 }
836
837 system( "/bin/cp", "pgdriver/" . $install_driver_jar, $glassfish_dir . "/glassfish/lib" );
838 # more diagnostics needed?
839
840 print "done!\n";
841
842 print "\n*********************\n";
843 print "PLEASE NOTE, SOME OF THE ASADMIN COMMANDS ARE GOING TO FAIL,\n";
844 print "FOR EXAMPLE, IF A CONFIGURATION SETTING THAT WE ARE TRYING\n";
845 print "TO CREATE ALREADY EXISTS; OR IF A JVM OPTION THAT WE ARE\n";
846 print "DELETING DOESN'T. THESE \"FAILURES\" ARE NORMAL!\n";
847 print "*********************\n\n";
848 print "When/if asadmin asks you to \"Enter admin user name\",\n";
849 print "it should be safe to hit return and accept the default\n";
850 print "(which is \"admin\").\n";
851
852 print "\nPress any key to continue...\n\n";
853
854 system "stty cbreak </dev/tty >/dev/tty 2>&1";
855 unless ($yes) {
856 my $key = getc(STDIN);
857 }
858 system "stty -cbreak </dev/tty >/dev/tty 2>&1";
859 print "\n";
860
861 # start domain, if not running:
862
863 my $javacheck = `java -version`;
864 my $exitcode = $?;
865 unless ( $exitcode == 0 ) {
866 print STDERR "$javacheck\n" if $javacheck;
867 print STDERR "Do you have java installed?\n";
868 exit 1;
869 }
870 my $DOMAIN = "domain1";
871 my $DOMAIN_DOWN =
872 `$CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'}/bin/asadmin list-domains | grep "$DOMAIN " | grep "not running"`;
873 print STDERR $DOMAIN_DOWN . "\n";
874 if ($DOMAIN_DOWN) {
875 print "Trying to start domain up...\n";
876 system( $CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'} . "/bin/asadmin start-domain domain1" );
877 }
878 else {
879 print "domain appears to be up...\n";
880 }
881
882 # create asadmin login, so that the user doesn't have to enter
883 # the username and password for every asadmin command, if
884 # access to :4848 is password-protected:
885
886 system( $glassfish_dir. "/bin/asadmin login" );
887
888 # NEW: configure glassfish using ASADMIN commands:
889
890 my $success = &setup_glassfish();
891
892 # CHECK EXIT STATUS, BARF IF SETUP SCRIPT FAILED:
893
894 unless ($success) {
895 print "\nERROR! Failed to configure Glassfish domain!\n";
896 print "(see the error messages above - if any)\n";
897 print "Aborting...\n";
898
899 exit 1;
900 }
901
902 # Additional config files:
903
904 my $JHOVE_CONFIG = "../../conf/jhove/jhove.conf";
905
906 unless ( -f $JHOVE_CONFIG ) {
907 $JHOVE_CONFIG = "jhove.conf";
908 }
909
910 unless ( -f $JHOVE_CONFIG ) {
911 print "\nERROR! Configuration files not found in config dir!\n";
912 print "(are you running the installer in the right directory?\n";
913 print "Aborting...\n";
914 exit 1;
915 }
916
917 print "\nCopying additional configuration files... ";
918
919 system( "/bin/cp -Rf " . $JHOVE_CONFIG . " " . $glassfish_dir . "/glassfish/domains/domain1/config" );
920 #diagnostics needed!
921
922 # install the DVN guides (HTML) into the application docroot:
923 # (if the built docs exist?)
924 # TODO: add documentation build/installation to the installer.
925 #system ( "/bin/cp -Rf doc/guides/* ".$glassfish_dir."/glassfish/domains/domain1/docroot/guides");
926
927 print "done!\n";
928
929 # check if glassfish is running:
930 # TODO.
931
932 # 6. DEPLOY APPLICATION:
933
934 # 6b. TRY TO (AUTO-)DEPLOY:
935
936 unless (
937 (
938 my $exit_code =
939 system( "cp -f " . $WARFILE_LOCATION . " " . $glassfish_dir . "/glassfish/domains/domain1/autodeploy" )
940 ) == 0
941 )
942 {
943 print STDERR "Could copy the application into the auto-deploy directory!\n";
944 print STDERR "(exit code: " . $exit_code . ")\n";
945 exit 1;
946 }
947
948 print "Waiting for the dataverse application to start...\n";
949 sleep 60;
950
951 # 7. POPULATE DATABASE:
952
953 if ($pg_local_connection) {
954 # 7a. POPULATE LOCALLY:
955 print "\nPopulating the database (local PostgresQL instance):\n\n";
956
957 # Copy the SQL file to /tmp, where user postgres will definitely
958 # have read access to it:
959
960 copy( $SQL_REFERENCE_DATA, "/tmp" ) or die "Could not copy $SQL_REFERENCE_DATA to /tmp: $!";
961 unlink( $SQL_REFERENCE_DATA );
962
963 chdir("/tmp");
964 $< = $POSTGRES_SYS_UID;
965 $> = $POSTGRES_SYS_UID;
966 my $psql_command = $psql_exec . "/psql -d $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} -f $SQL_REFERENCE_DATA";
967
968 unless ( ( my $exitcode = system("$psql_command") ) == 0 ) {
969 print STDERR "Could not populate Postgres database for the DVN app!\n";
970 print STDERR "(command: " . $psql_command . ")\n";
971 print STDERR "(psql exit code: " . $exitcode . ")\n";
972 print STDERR "\nYou must populate the database before you can use your new\n";
973 print STDERR "DVN instance. Please consult the installation manual and/or\n";
974 print STDERR "seek support from the DVN team.\n\n";
975 exit 1;
976
977 }
978
979 }
980 else {
981 # 7b. INSTRUCT THE USER TO POPULATE THE DB ON THE REMOTE SERVER:
982 # NOT SUPPORTED YET -- TODO
983 print "Please copy the file $SQL_REFERENCE_DATA (found in this directory)\n";
984 print "onto the remote server and populate the database manually,\n";
985 print "as user postgres, with the following command:\n\n";
986 print " psql -d $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} -f $SQL_REFERENCE_DATA\n";
987 print "then start glassfish again on this server with \n\n";
988 print " " . $glassfish_dir . "/bin/asadmin start-domain domain1\n\n";
989
990 # exit 0;
991
992 }
993
994 # back to root:
995
996 $> = 0;
997 $< = 0;
998 chdir($cwd);
999 print "\nOK, done!\n";
1000
1001 # FIXME: don't just sleep... figure out if the app is up yet.
1002 print "\n--Sleeping for 3 minutes--\n";
1003 sleep 180;
1004
1005 # Populate the metadata block field values, create users
1006 # and dataverses:
1007
1008 unless ( -d "data" && -f "setup-datasetfields.sh" && -f "setup-users.sh" && -f "setup-dvs.sh" && -f "setup-all.sh" ) {
1009 chdir("../api");
1010 }
1011
1012 unless ( -d "data" && -f "setup-datasetfields.sh" && -f "setup-users.sh" && -f "setup-dvs.sh" && -f "setup-builtin-roles.sh" && -f "setup-all.sh" ) {
1013 print "\nERROR: Can't find the metadata and user/dataverse setup scripts!\n";
1014 print "\tAre you running the installer in the right directory?\n";
1015 exit 1;
1016 }
1017
1018 for my $script ( "setup-all.sh" ) {
1019 print "Executing script " . $script . "...\n";
1020
1021 my $my_hostname = $CONFIG_DEFAULTS{'HOST_DNS_ADDRESS'};
1022
1023 my $run_script;
1024 #if ( $my_hostname ne "localhost" ) {
1025 # system( "sed 's/localhost:8080/$my_hostname/g' < " . $script . " > tmpscript.sh; chmod +x tmpscript.sh" );
1026 # $run_script = "tmpscript.sh";
1027 #}
1028 #else {
1029 $run_script = $script;
1030 #}
1031
1032 unless ( my $exit_code = system( "./" . $run_script ) == 0 ) {
1033 print "\nERROR executing script " . $script . "!\n";
1034 exit 1;
1035 }
1036 print "ok!\n";
1037 }
1038
1039 chdir($cwd);
1040
1041 print "\n\nYou should now have a running DVN instance at\n";
1042 print " http://" . $CONFIG_DEFAULTS{'HOST_DNS_ADDRESS'} . "[:YOURPORT]\n";
1043
1044 # (going to skip the Rserve check, for now)
1045
1046 exit 0;
1047
1048 # 9. FINALLY, CHECK IF RSERVE IS RUNNING:
1049 print "\n\nFinally, checking if Rserve is running and accessible...\n";
1050
1051 unless ( $CONFIG_DEFAULTS{'RSERVE_PORT'} =~ /^[0-9][0-9]*$/ ) {
1052 print $CONFIG_DEFAULTS{'RSERVE_HOST'} . " does not look like a valid port number,\n";
1053 print "defaulting to 6311.\n\n";
1054
1055 $CONFIG_DEFAULTS{'RSERVE_PORT'} = 6311;
1056 }
1057
1058 my ( $rserve_iaddr, $rserve_paddr, $rserve_proto );
1059
1060 unless ( $rserve_iaddr = inet_aton( $CONFIG_DEFAULTS{'RSERVE_HOST'} ) ) {
1061 print STDERR "Could not look up $CONFIG_DEFAULTS{'RSERVE_HOST'},\n";
1062 print STDERR "the host you specified as your R server.\n";
1063 print STDERR "\nDVN can function without a working R server, but\n";
1064 print STDERR "much of the functionality concerning running statistics\n";
1065 print STDERR "and analysis on quantitative data will not be available.\n";
1066 print STDERR "Please consult the Installers guide for more info.\n";
1067
1068 exit 0;
1069 }
1070
1071 $rserve_paddr = sockaddr_in( $CONFIG_DEFAULTS{'RSERVE_PORT'}, $rserve_iaddr );
1072 $rserve_proto = getprotobyname('tcp');
1073
1074 unless ( socket( SOCK, PF_INET, SOCK_STREAM, $rserve_proto )
1075 && connect( SOCK, $rserve_paddr ) )
1076 {
1077 print STDERR "Could not establish connection to $CONFIG_DEFAULTS{'RSERVE_HOST'}\n";
1078 print STDERR "on port $CONFIG_DEFAULTS{'RSERVE_PORT'}, the address you provided\n";
1079 print STDERR "for your R server.\n";
1080 print STDERR "DVN can function without a working R server, but\n";
1081 print STDERR "much of the functionality concerning running statistics\n";
1082 print STDERR "and analysis on quantitative data will not be available.\n";
1083 print STDERR "Please consult the \"Installing R\" section in the Installers guide\n";
1084 print STDERR "for more info.\n";
1085
1086 exit 0;
1087
1088 }
1089
1090 close(SOCK);
1091 print "\nOK!\n";
1092
1093 sub setup_glassfish {
1094 my $success = 1;
1095 my $failure = 0;
1096
1097 # We are going to run a standalone shell script with a bunch of asadmin
1098 # commands to set up all the glassfish components for the application.
1099 # All the parameters must be passed to that script as environmental
1100 # variables:
1101
1102 $ENV{'GLASSFISH_ROOT'} = $CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'};
1103 $ENV{'GLASSFISH_DOMAIN'} = "domain1";
1104 $ENV{'ASADMIN_OPTS'} = "";
1105 $ENV{'MEM_HEAP_SIZE'} = $CONFIG_DEFAULTS{'DEF_MEM_SIZE'};
1106
1107 $ENV{'DB_PORT'} = $CONFIG_DEFAULTS{'POSTGRES_PORT'};
1108 $ENV{'DB_HOST'} = $CONFIG_DEFAULTS{'POSTGRES_SERVER'};
1109 $ENV{'DB_NAME'} = $CONFIG_DEFAULTS{'POSTGRES_DATABASE'};
1110 $ENV{'DB_USER'} = $CONFIG_DEFAULTS{'POSTGRES_USER'};
1111 $ENV{'DB_PASS'} = $CONFIG_DEFAULTS{'POSTGRES_PASSWORD'};
1112
1113 $ENV{'RSERVE_HOST'} = $CONFIG_DEFAULTS{'RSERVE_HOST'};
1114 $ENV{'RSERVE_PORT'} = $CONFIG_DEFAULTS{'RSERVE_PORT'};
1115 $ENV{'RSERVE_USER'} = $CONFIG_DEFAULTS{'RSERVE_USER'};
1116 $ENV{'RSERVE_PASS'} = $CONFIG_DEFAULTS{'RSERVE_PASSWORD'};
1117
1118 $ENV{'HOST_ADDRESS'} = $CONFIG_DEFAULTS{'HOST_DNS_ADDRESS'};
1119 $ENV{'SMTP_SERVER'} = $CONFIG_DEFAULTS{'MAIL_SERVER'};
1120 $ENV{'FILES_DIR'} =
1121 $CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'} . "/glassfish/domains/" . $ENV{'GLASSFISH_DOMAIN'} . "/files";
1122
1123 system("./glassfish-setup.sh");
1124
1125 if ($?) {
1126 return $failure;
1127 }
1128 return $success;
1129 }
1130
1131 sub create_pg_hash {
1132 my $pg_username = shift @_;
1133 my $pg_password = shift @_;
1134
1135 my $encode_line = $pg_password . $pg_username;
1136
1137 # for Redhat:
1138
1139 ##print STDERR "executing /bin/echo -n $encode_line | md5sum\n";
1140
1141 my $hash;
1142 if ( $WORKING_OS eq "MacOSX" ) {
1143 $hash = `/bin/echo -n $encode_line | md5`;
1144 }
1145 else {
1146 $hash = `/bin/echo -n $encode_line | md5sum`;
1147 }
1148
1149 chop $hash;
1150
1151 $hash =~ s/ \-$//;
1152
1153 if ( ( length($hash) != 32 ) || ( $hash !~ /^[0-9a-f]*$/ ) ) {
1154 print STDERR "Failed to generate a MD5-encrypted password hash for the Postgres database.\n";
1155 exit 1;
1156 }
1157
1158 return $hash;
1159 }