Mercurial > hg > LGDataverses
view scripts/installer/install @ 14:be7787c36e58 default tip
new: nofity LGSercies for deleted files
author | Zoe Hong <zhong@mpiwg-berlin.mpg.de> |
---|---|
date | Mon, 02 Nov 2015 16:41:23 +0100 |
parents | a50cf11e5178 |
children |
line wrap: on
line source
#!/usr/bin/perl use strict; use warnings; use Getopt::Long; use Socket; use File::Copy; my $verbose; my $pg_only; my $hostname; my $gfdir; my $mailserver; my $yes; my $force; my $nogfpasswd; my ($rez) = GetOptions( #"length=i" => \$length, # numeric #"file=s" => \$data, # string "verbose" => \$verbose, "pg_only" => \$pg_only, "hostname=s" => \$hostname, "gfdir=s" => \$gfdir, "mailserver=s" => \$mailserver, "y|yes" => \$yes, "f|force" => \$force, "nogfpasswd" => \$nogfpasswd, ); my $postgresonly = 0; my @CONFIG_VARIABLES = ( 'HOST_DNS_ADDRESS', 'GLASSFISH_DIRECTORY', 'MAIL_SERVER', 'POSTGRES_SERVER', 'POSTGRES_PORT', 'POSTGRES_DATABASE', 'POSTGRES_USER', 'POSTGRES_PASSWORD', 'RSERVE_HOST', 'RSERVE_PORT', 'RSERVE_USER', 'RSERVE_PASSWORD' ); if ($pg_only) { # exit; @CONFIG_VARIABLES = ( 'POSTGRES_SERVER', 'POSTGRES_PORT', 'POSTGRES_DATABASE', 'POSTGRES_USER', 'POSTGRES_PASSWORD' ); $postgresonly = 1; } # TODO: # supply pre-set, default values in a text file; # this way we can provide different sets of default # values, for the installers intended for different # groups of users - local developers vs. "real" # dataverse users. my %CONFIG_DEFAULTS = ( 'HOST_DNS_ADDRESS', 'localhost', 'GLASSFISH_DIRECTORY', '/usr/local/glassfish4', 'MAIL_SERVER', 'mail.hmdc.harvard.edu', 'POSTGRES_SERVER', 'localhost', 'POSTGRES_PORT', 5432, 'POSTGRES_DATABASE', 'dvndb', 'POSTGRES_USER', 'dvnapp', 'POSTGRES_PASSWORD', 'secret', 'RSERVE_HOST', 'localhost', 'RSERVE_PORT', 6311, 'RSERVE_USER', 'rserve', 'RSERVE_PASSWORD', 'rserve' ); my %CONFIG_PROMPTS = ( 'HOST_DNS_ADDRESS', 'Internet Address of your host', 'GLASSFISH_DIRECTORY', 'Glassfish Directory', 'MAIL_SERVER', 'SMTP (mail) server to relay notification messages', 'POSTGRES_SERVER', 'Postgres Server', 'POSTGRES_PORT', 'Postgres Server Port', 'POSTGRES_DATABASE', 'Name of the Postgres Database', 'POSTGRES_USER', 'Name of the Postgres User', 'POSTGRES_PASSWORD', 'Postgres user password', 'RSERVE_HOST', 'Rserve Server', 'RSERVE_PORT', 'Rserve Server Port', 'RSERVE_USER', 'Rserve User Name', 'RSERVE_PASSWORD', 'Rserve User Password' ); # Supported Posstgres JDBC drivers: # (have to be configured explicitely, so that Perl "taint" (security) mode # doesn't get paranoid) my %POSTGRES_DRIVERS = ( # "8_4", "postgresql-8.3-603.jdbc4.jar", "8_4", "postgresql-8.4-703.jdbc4.jar", "9_0", "postgresql-9.0-802.jdbc4.jar", "9_1", "postgresql-9.1-902.jdbc4.jar", "9_2", "postgresql-9.1-902.jdbc4.jar", "9_3", "postgresql-9.1-902.jdbc4.jar" ); # A few preliminary checks: # user -- must be root: my $user_real = `who am i`; chop $user_real; $user_real =~ s/ .*$//; if ( $< != 0 ) { print STDERR "\nERROR: You must be logged in as root to run the installer.\n\n"; exit 1; } # OS: my $uname_out = `uname -a`; # hostname: my $hostname_from_cmdline = `hostname`; chop $hostname_from_cmdline; if ($hostname) { $CONFIG_DEFAULTS{'HOST_DNS_ADDRESS'} = $hostname; } else { $CONFIG_DEFAULTS{'HOST_DNS_ADDRESS'} = $hostname_from_cmdline; } if ($mailserver) { $CONFIG_DEFAULTS{'MAIL_SERVER'} = $mailserver; } if ($gfdir) { $CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'} = $gfdir; } print "\nWelcome to the Dataverse installer.\n"; unless ($postgresonly) { print "You will be guided through the process of setting up a NEW\n"; print "instance of the dataverse application\n"; } else { print "You will be guided through the process of configuring the\n"; print "LOCAL instance of PostgreSQL database for use by the DVN\n"; print "application.\n"; } my @uname_tokens = split( " ", $uname_out ); my $WORKING_OS; if ( $uname_tokens[0] eq "Darwin" ) { print "\nThis appears to be a MacOS X system; good.\n"; # TODO: check the OS version $WORKING_OS = "MacOSX"; } elsif ( $uname_tokens[0] eq "Linux" ) { if ( -f "/etc/redhat-release" ) { print "\nThis appears to be a RedHat system; good.\n"; $WORKING_OS = "RedHat"; # TODO: check the distro version } else { print "\nThis appears to be a non-RedHat Linux system;\n"; print "this installation *may* succeed; but we're not making any promises!\n"; $WORKING_OS = "Linux"; } } else { print "\nWARNING: This appears to be neither a Linux or MacOS X system!\n"; print "This installer script will most likely fail. Please refer to the\n"; print "DVN Installers Guide for more information.\n\n"; $WORKING_OS = "Unknown"; print "Do you wish to continue?\n [y/n] "; my $yesnocont; if ($yes) { $yesnocont = "y"; } else { print "here"; exit; $yesnocont = <>; chop $yesnocont; } while ( $yesnocont ne "y" && $yesnocont ne "n" ) { print "Please enter 'y' or 'n'!\n"; print "(or ctrl-C to exit the installer)\n"; $yesnocont = <>; chop $yesnocont; } if ( $yesnocont eq "n" ) { exit 0; } } ENTERCONFIG: print "\n"; print "Please enter the following configuration values:\n"; print "(hit [RETURN] to accept the default value)\n"; print "\n"; for my $ENTRY (@CONFIG_VARIABLES) { print $CONFIG_PROMPTS{$ENTRY} . ": "; print "[" . $CONFIG_DEFAULTS{$ENTRY} . "] "; my $user_entry; unless ($yes) { $user_entry = <>; chop $user_entry; } if ( $user_entry ne "" ) { $CONFIG_DEFAULTS{$ENTRY} = $user_entry; } print "\n"; } # CONFIRM VALUES ENTERED: print "\nOK, please confirm what you've entered:\n\n"; for my $ENTRY (@CONFIG_VARIABLES) { print $CONFIG_PROMPTS{$ENTRY} . ": " . $CONFIG_DEFAULTS{$ENTRY} . "\n"; } my $yesno; if ($yes) { $yesno = "y"; } else { print "\nIs this correct? [y/n] "; $yesno = <>; chop $yesno; } while ( $yesno ne "y" && $yesno ne "n" ) { print "Please enter 'y' or 'n'!\n"; print "(or ctrl-C to exit the installer)\n"; $yesno = <>; chop $yesno; } if ( $yesno eq "n" ) { goto ENTERCONFIG; } # VALIDATION/VERIFICATION OF THE CONFIGURATION VALUES: # 1. VERIFY MAIL SERVER THEY CONFIGURED: unless ($postgresonly) { my ( $mail_server_iaddr, $mail_server__paddr, $mail_server_proto, $mail_server_status ); $mail_server_status = 1; unless ( $mail_server_iaddr = inet_aton( $CONFIG_DEFAULTS{'MAIL_SERVER'} ) ) { print STDERR "Could not look up $CONFIG_DEFAULTS{'MAIL_SERVER'},\n"; print STDERR "the host you specified as your mail server\n"; $mail_server_status = 0; } if ($mail_server_status) { my $mail_server_paddr = sockaddr_in( 25, $mail_server_iaddr ); $mail_server_proto = getprotobyname('tcp'); unless ( socket( SOCK, PF_INET, SOCK_STREAM, $mail_server_proto ) && connect( SOCK, $mail_server_paddr ) ) { print STDERR "Could not establish connection to $CONFIG_DEFAULTS{'MAIL_SERVER'},\n"; print STDERR "the address you provided for your Mail server.\n"; print STDERR "Please select a valid mail server, and try again.\n\n"; $mail_server_status = 0; } } close(SOCK); unless ($mail_server_status) { goto ENTERCONFIG; } } # 2. CHECK IF THE WAR FILE IS AVAILABLE: my $WARFILE_LOCATION = "../../target/dataverse-4.0.war"; unless ( -f $WARFILE_LOCATION ) { $WARFILE_LOCATION = "dataverse-4.0.war"; } unless ( -f $WARFILE_LOCATION ) { print "\nWARNING: Can't find the project .war file!\n"; print "\tAre you running the installer in the right directory?\n"; print "\tHave you built the war file?\n"; print "\t(if not, build the project and run the installer again)\n"; exit 0; } # check the working (installer) dir: my $cwd; chomp( $cwd = `pwd` ); # 2b. CHECK IF THE SQL TEMPLATE IS IN PLACE AND CREATE THE SQL FILE my $SQL_REFERENCE_DATA = "reference_data_filtered.sql"; my $SQL_REFERENCE_TEMPLATE = "../database/reference_data.sql"; unless ( -f $SQL_REFERENCE_TEMPLATE ) { $SQL_REFERENCE_TEMPLATE = "reference_data.sql"; } unless ( -f $SQL_REFERENCE_TEMPLATE ) { print "\nWARNING: Can't find .sql data template!\n"; print "(are you running the installer in the right directory?)\n"; exit 0; } open DATATEMPLATEIN, $SQL_REFERENCE_TEMPLATE || die $@; open SQLDATAOUT, '>' . $SQL_REFERENCE_DATA || die $@; while (<DATATEMPLATEIN>) { s/dvnapp/$CONFIG_DEFAULTS{'POSTGRES_USER'}/g; print SQLDATAOUT $_; } close DATATEMPLATEIN; close SQLDATAOUT; # 3. CHECK POSTGRES AND JQ AVAILABILITY: my $pg_local_connection = 0; my $psql_exec; my $jq_exec = ""; my $pg_major_version = 0; my $pg_minor_version = 0; my $POSTGRES_SYS_UID; if ( $CONFIG_DEFAULTS{'POSTGRES_SERVER'} eq 'localhost' ) { $pg_local_connection = 1; # 3a. CHECK FOR USER postgres: print "\nChecking system user \"postgres\"... "; my $POSTGRES_SYS_NAME = "postgres"; $POSTGRES_SYS_UID = ( getpwnam("postgres") )[2]; unless ($POSTGRES_SYS_UID) { print STDERR "\nERROR: I haven't been able to find user \"postgres\" on the system! Is PostgreSQL installed?\n"; print STDERR "(TODO: prompt the user instead to supply an alternative username, if\n"; print STDERR "available)\n"; exit 1; } print "OK.\n"; # 3b. LOCATE THE EXECUTABLE: my $sys_path = $ENV{'PATH'}; my @sys_path_dirs = split( ":", $sys_path ); $psql_exec = ""; for my $sys_path_dir (@sys_path_dirs) { if ( -x $sys_path_dir . "/psql" ) { $psql_exec = $sys_path_dir; last; } } for my $sys_path_dir (@sys_path_dirs) { if ( -x $sys_path_dir . "/jq" ) { $jq_exec = $sys_path_dir; last; } } if ( $jq_exec eq "" ) { 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"; exit 1; } my $psql_major_version = 0; my $psql_minor_version = 0; # 3c. IF PSQL WAS FOUND IN THE PATH, CHECK ITS VERSION: unless ( $psql_exec eq "" ) { open( PSQLOUT, $psql_exec . "/psql --version|" ); my $psql_version_line = <PSQLOUT>; chop $psql_version_line; close PSQLOUT; my ( $postgresName, $postgresNameLong, $postgresVersion ) = split( " ", $psql_version_line ); unless ( $postgresName eq "psql" && $postgresVersion =~ /^[0-9][0-9\.]*$/ ) { print STDERR "\nWARNING: Unexpected output from psql command!\n"; } else { my (@psql_version_tokens) = split( '\.', $postgresVersion ); print "\n\nFound Postgres psql command, version $postgresVersion.\n\n"; $psql_major_version = $psql_version_tokens[0]; $psql_minor_version = $psql_version_tokens[1]; $pg_major_version = $psql_major_version; $pg_minor_version = $psql_minor_version; } } # a frequent problem with MacOSX is that the copy of psql found in the PATH # belongs to the older version of PostgresQL supplied with the OS, which happens # to be incompatible with the newer builds from the Postgres project; which are # recommended to be used with dataverse. So if this is a MacOSX box, we'll # check what other versions of PG are available, and select the highest version # we can find: if ( $WORKING_OS eq "MacOSX" ) { my $macos_pg_major_version = 0; my $macos_pg_minor_version = 0; for $macos_pg_minor_version ( "3", "2", "1", "0" ) { if ( -x "/Library/PostgreSQL/9." . $macos_pg_minor_version . "/bin/psql" ) { $macos_pg_major_version = 9; if ( ( $macos_pg_major_version > $psql_major_version ) || ( $macos_pg_minor_version >= $psql_minor_version ) ) { $psql_exec = "/Library/PostgreSQL/9." . $macos_pg_minor_version . "/bin"; $pg_major_version = $macos_pg_major_version; $pg_minor_version = $macos_pg_minor_version; } last; } } # And if we haven't found an 9.* version of postgresql installed, we'll also check # for version 8.* available: if ( $macos_pg_major_version < 9 ) { for $macos_pg_minor_version ( "4", "3" ) # TODO: # Do we even want to support postgres 8.3? { if ( -x "/Library/PostgreSQL/8." . $macos_pg_minor_version . "/bin/psql" ) { $macos_pg_major_version = 8; if ( $macos_pg_major_version > $psql_major_version || $macos_pg_minor_version > $psql_minor_version ) { $psql_exec = "/Library/PostgreSQL/8." . $macos_pg_minor_version . "/bin"; $pg_major_version = $macos_pg_major_version; $pg_minor_version = $macos_pg_minor_version; } last; } } } } if ( $psql_exec eq "" ) { print STDERR "\nERROR: I haven't been able to find the psql command in your PATH!\n"; print STDERR "Please make sure PostgresQL is properly installed; if necessary, add\n"; print STDERR "the location of psql to the PATH, then try again.\n\n"; exit 1; } if ( $pg_major_version == 0 ) { } # 4. CONFIGURE POSTGRES: print "\nConfiguring Postgres Database:\n"; print "(Using psql version " . $pg_major_version . "." . $pg_minor_version . ")\n"; $< = $POSTGRES_SYS_UID; $> = $POSTGRES_SYS_UID; # 4a. CHECK IF POSTGRES IS RUNNING: print "Checking if a local instance of Postgres is running and accessible...\n"; # (change to /tmp before executing the command below - # we are trying to do it as user postgres, and it may not have # access to the current, installer directory; the command would still # work, but there would be an error message from the shell init on screen # - potentially confusing) chdir("/tmp"); if ( !system( $psql_exec . "/psql -c 'SELECT * FROM pg_roles' > /dev/null 2>&1" ) ) { print "Yes, it is.\n"; } else { print "Nope, I haven't been able to connect to the local instance of PostgresQL.\n"; print "daemon. Is postgresql running? \n"; print "On a RedHat-like system, you can check the status of the daemon with\n\n"; print " service postgresql status\n\n"; print "and, if it's not running, start the daemon with\n\n"; print " service postgresql start\n\n"; print "On MacOSX, use Applications -> PostgresQL -> Start Server.\n"; print "(or, if there's no \"Start Server\" item in your PostgresQL folder, \n"; print "simply restart your MacOSX system!)\n"; print "Also, please make sure that the daemon is listening to network connections,\n"; print "at least on the localhost interface. (See \"Installing Postgres\" section\n"; print "of the installation manual).\n"; print "Finally, please make sure that the postgres user can make localhost \n"; print "connections without supplying a password. (That's controlled by the \n"; print "\"localhost ... ident\" line in pg_hba.conf; again, please consult the \n"; print "installation manual).\n"; exit 1; } # 4c. CHECK IF THIS DB ALREADY EXISTS: my $psql_command_dbcheck = $psql_exec . "/psql -c \"\" -d " . $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} . ">/dev/null 2>&1"; if ($force) { print "WARNING! Database " . $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} . " already exists but --force given... continuing.\n"; } elsif ( ( my $exitcode = system($psql_command_dbcheck) ) == 0 ) { $> = 0; $< = 0; chdir($cwd); print "WARNING! Database " . $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} . " already exists!\n"; print "\nPlease note that you can only use this installer to create a blank, \n"; print "new and shiny DVN database. I.e., you cannot install on top of an \n"; print "existing database. Please enter a different name for the DVN database.\n"; print "\nPress any key to continue, or ctrl-C to exit the installer...\n\n"; system "stty cbreak </dev/tty >/dev/tty 2>&1"; my $key = getc(STDIN); system "stty -cbreak </dev/tty >/dev/tty 2>&1"; print "\n"; goto ENTERCONFIG; } # 4d. CHECK IF THIS USER ALREADY EXISTS: my $psql_command_rolecheck = $psql_exec . "/psql -c \"\" -d postgres " . $CONFIG_DEFAULTS{'POSTGRES_USER'} . " >/dev/null 2>&1"; if ( ( my $exitcode = system($psql_command_rolecheck) ) == 0 ) { print "User (role) " . $CONFIG_DEFAULTS{'POSTGRES_USER'} . " already exists;\n"; print "Proceeding."; } else { # 4e. CREATE DVN DB USER: print "\nCreating Postgres user (role) for the DVN:\n"; open TMPCMD, ">/tmp/pgcmd.$$.tmp"; # with md5-encrypted password: my $pg_password_md5 = &create_pg_hash( $CONFIG_DEFAULTS{'POSTGRES_USER'}, $CONFIG_DEFAULTS{'POSTGRES_PASSWORD'} ); my $sql_command = "CREATE ROLE \"" . $CONFIG_DEFAULTS{'POSTGRES_USER'} . "\" PASSWORD 'md5" . $pg_password_md5 . "' NOSUPERUSER CREATEDB CREATEROLE INHERIT LOGIN"; print TMPCMD $sql_command; close TMPCMD; my $psql_commandline = $psql_exec . "/psql -f /tmp/pgcmd.$$.tmp >/dev/null 2>&1"; my $out = qx($psql_commandline 2>&1); my $exitcode = $?; unless ( $exitcode == 0 ) { print STDERR "Could not create the DVN Postgres user role!\n"; print STDERR "(SQL: " . $sql_command . ")\n"; print STDERR "(psql exit code: " . $exitcode . ")\n"; print STDERR "(STDERR and STDOUT was: " . $out . ")\n"; exit 1; } unlink "/tmp/pgcmd.$$.tmp"; print "done.\n"; } # 4f. CREATE DVN DB: print "\nCreating Postgres database:\n"; my $psql_command = $psql_exec . "/createdb " . $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} . " --owner=" . $CONFIG_DEFAULTS{'POSTGRES_USER'}; my $out = qx($psql_command 2>&1); my $exitcode = $?; unless ( $exitcode == 0 ) { print STDERR "Could not create Postgres database for the DVN app!\n"; print STDERR "(command: " . $psql_command . ")\n"; print STDERR "(psql exit code: " . $exitcode . ")\n"; print STDERR "(STDOUT and STDERR: " . $out . ")\n"; if ($force) { print STDERR "\n--force called, continuing\n"; } else { print STDERR "\naborting the installation (sorry!)\n\n"; exit 1; } } # Changing back to root UID: $> = 0; $< = 0; chdir($cwd); } else { if (0) { # THE LINES BELOW WERE PART OF THE 3.* "DEV." INSTALLER: # DO WE STILL WANT TO MAINTAIN THIS FUNCTIONALITY IN 4.0? print "\nIt is strongly recommended that you use a local PostgresQL server,\n"; print "running on localhost, in your development environment!\n\n"; print "Do you wish to continue?\n [y/n] "; my $yesnocont = <>; chop $yesnocont; while ( $yesnocont ne "y" && $yesnocont ne "n" ) { print "Please enter 'y' or 'n'!\n"; print "(or ctrl-C to exit the installer)\n"; $yesnocont = <>; chop $yesnocont; } if ( $yesnocont eq "n" ) { print "(aborting the installation)\n" . exit 0; } } if ($pg_only) { print "The script must be run in the --pg_only mode ONLY locally,\n"; print "i.e., on the server where PostgresQL is running.\n"; exit 1; } print "In order to use a PostgresQL database running on a remote server,\n"; print "Please run this installer on that host with the \"--pg_only\" option:\n\n"; print "./install --pg_only\n\n"; print "Press any key to continue the installation process once that has been\n"; print "done. Or press ctrl-C to exit the installer.\n\n"; chdir("/tmp"); system "stty cbreak </dev/tty >/dev/tty 2>&1"; my $key = getc(STDIN); system "stty -cbreak </dev/tty >/dev/tty 2>&1"; print "\n"; chdir($cwd); # Check if the role and database have been created on the remote server: # -- TODO; # Find out what Postgres version is running remotely: $pg_major_version = 9; $pg_minor_version = 1; print "What version of PostgresQL is installed on the remote server?\n [" . $pg_major_version . "." . $pg_minor_version . "] "; my $postgresVersion = <>; chop $postgresVersion; while ( $postgresVersion ne "" && !( $postgresVersion =~ /^[0-9]+\.[0-9]+$/ ) ) { print "Please enter valid Postgres version!\n"; print "(or ctrl-C to exit the installer)\n"; $postgresVersion = <>; chop $postgresVersion; } unless ( $postgresVersion eq "" ) { my (@postgres_version_tokens) = split( '\.', $postgresVersion ); unless ( ( $postgres_version_tokens[0] == 8 && $postgres_version_tokens[1] >= 4 ) || ( $postgres_version_tokens[0] >= 9 ) ) { print STDERR "\nERROR: PostgresQL version 8.4, or newer, is required!\n"; print STDERR "Please make sure the right version of PostgresQL is properly installed\n"; print STDERR "on the remote server, then try again.\n"; exit 1; } $pg_major_version = $postgres_version_tokens[0]; $pg_minor_version = $postgres_version_tokens[1]; } } if ($postgresonly) { print "\nOK, done.\n"; print "You can now resume the installation on the main DVN host.\n\n"; exit 0; } # 5. CONFIGURE GLASSFISH print "\nProceeding with the Glassfish setup.\n"; print "\nChecking your Glassfish installation..."; my $glassfish_dir = $CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'}; # 5a. CHECK IF GLASSFISH DIR LOOKS OK: unless ( -d $glassfish_dir . "/glassfish/domains/domain1" ) { # TODO: need better check than this while ( !( -d $glassfish_dir . "/glassfish/domains/domain1" ) ) { print "\nInvalid Glassfish directory " . $glassfish_dir . "!\n"; print "Enter the root directory of your Glassfish installation:\n"; print "(Or ctrl-C to exit the installer): "; $glassfish_dir = <>; chop $glassfish_dir; } } print "OK!\n"; # 5b. DETERMINE HOW MUCH MEMORY TO GIVE TO GLASSFISH AS HEAP: my $gf_heap_default = "2048m"; my $sys_mem_total = 0; if ( -e "/proc/meminfo" && open MEMINFO, "/proc/meminfo" ) { # Linux while ( my $mline = <MEMINFO> ) { if ( $mline =~ /MemTotal:[ \t]*([0-9]*) kB/ ) { $sys_mem_total = $1; } } close MEMINFO; } elsif ( -x "/usr/sbin/sysctl" ) { # MacOS X, probably... $sys_mem_total = `/usr/sbin/sysctl -n hw.memsize`; chop $sys_mem_total; if ( $sys_mem_total > 0 ) { $sys_mem_total = int( $sys_mem_total / 1024 ); # size in kb } } if ( $sys_mem_total > 0 ) { # setting the default heap size limit to 3/8 of the available # amount of memory: $gf_heap_default = ( int( $sys_mem_total / ( 8 / 3 * 1024 ) ) ); print "\nSetting the heap limit for Glassfish to " . $gf_heap_default . "MB. \n"; print "You may need to adjust this setting to better suit \n"; print "your system.\n\n"; #$gf_heap_default .= "m"; } else { print "\nCould not determine the amount of memory on your system.\n"; print "Setting the heap limit for Glassfish to 2GB. You may need \n"; print "to adjust the value to better suit your system.\n\n"; } push @CONFIG_VARIABLES, "DEF_MEM_SIZE"; $CONFIG_DEFAULTS{"DEF_MEM_SIZE"} = $gf_heap_default; # TODO: # if the system has more than 4GB of memory (I believe), glassfish must # be run with the 64 bit flag set explicitly (at least that was the case # with the MacOS glassfish build...). Verify, and if still the case, # add a check. print "\nInstalling the Glassfish PostgresQL driver... "; my $install_driver_jar = ""; $install_driver_jar = $POSTGRES_DRIVERS{ $pg_major_version . "_" . $pg_minor_version }; unless ( $install_driver_jar && -e "pgdriver/" . $install_driver_jar ) { die "Installer could not find POSTGRES JDBC driver for your version of PostgresQL!\n(" . $pg_major_version . "." . $pg_minor_version . ")"; } system( "/bin/cp", "pgdriver/" . $install_driver_jar, $glassfish_dir . "/glassfish/lib" ); # more diagnostics needed? print "done!\n"; print "\n*********************\n"; print "PLEASE NOTE, SOME OF THE ASADMIN COMMANDS ARE GOING TO FAIL,\n"; print "FOR EXAMPLE, IF A CONFIGURATION SETTING THAT WE ARE TRYING\n"; print "TO CREATE ALREADY EXISTS; OR IF A JVM OPTION THAT WE ARE\n"; print "DELETING DOESN'T. THESE \"FAILURES\" ARE NORMAL!\n"; print "*********************\n\n"; print "When/if asadmin asks you to \"Enter admin user name\",\n"; print "it should be safe to hit return and accept the default\n"; print "(which is \"admin\").\n"; print "\nPress any key to continue...\n\n"; system "stty cbreak </dev/tty >/dev/tty 2>&1"; unless ($yes) { my $key = getc(STDIN); } system "stty -cbreak </dev/tty >/dev/tty 2>&1"; print "\n"; # start domain, if not running: my $javacheck = `java -version`; my $exitcode = $?; unless ( $exitcode == 0 ) { print STDERR "$javacheck\n" if $javacheck; print STDERR "Do you have java installed?\n"; exit 1; } my $DOMAIN = "domain1"; my $DOMAIN_DOWN = `$CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'}/bin/asadmin list-domains | grep "$DOMAIN " | grep "not running"`; print STDERR $DOMAIN_DOWN . "\n"; if ($DOMAIN_DOWN) { print "Trying to start domain up...\n"; system( $CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'} . "/bin/asadmin start-domain domain1" ); } else { print "domain appears to be up...\n"; } # create asadmin login, so that the user doesn't have to enter # the username and password for every asadmin command, if # access to :4848 is password-protected: system( $glassfish_dir. "/bin/asadmin login" ); # NEW: configure glassfish using ASADMIN commands: my $success = &setup_glassfish(); # CHECK EXIT STATUS, BARF IF SETUP SCRIPT FAILED: unless ($success) { print "\nERROR! Failed to configure Glassfish domain!\n"; print "(see the error messages above - if any)\n"; print "Aborting...\n"; exit 1; } # Additional config files: my $JHOVE_CONFIG = "../../conf/jhove/jhove.conf"; unless ( -f $JHOVE_CONFIG ) { $JHOVE_CONFIG = "jhove.conf"; } unless ( -f $JHOVE_CONFIG ) { print "\nERROR! Configuration files not found in config dir!\n"; print "(are you running the installer in the right directory?\n"; print "Aborting...\n"; exit 1; } print "\nCopying additional configuration files... "; system( "/bin/cp -Rf " . $JHOVE_CONFIG . " " . $glassfish_dir . "/glassfish/domains/domain1/config" ); #diagnostics needed! # install the DVN guides (HTML) into the application docroot: # (if the built docs exist?) # TODO: add documentation build/installation to the installer. #system ( "/bin/cp -Rf doc/guides/* ".$glassfish_dir."/glassfish/domains/domain1/docroot/guides"); print "done!\n"; # check if glassfish is running: # TODO. # 6. DEPLOY APPLICATION: # 6b. TRY TO (AUTO-)DEPLOY: unless ( ( my $exit_code = system( "cp -f " . $WARFILE_LOCATION . " " . $glassfish_dir . "/glassfish/domains/domain1/autodeploy" ) ) == 0 ) { print STDERR "Could copy the application into the auto-deploy directory!\n"; print STDERR "(exit code: " . $exit_code . ")\n"; exit 1; } print "Waiting for the dataverse application to start...\n"; sleep 60; # 7. POPULATE DATABASE: if ($pg_local_connection) { # 7a. POPULATE LOCALLY: print "\nPopulating the database (local PostgresQL instance):\n\n"; # Copy the SQL file to /tmp, where user postgres will definitely # have read access to it: copy( $SQL_REFERENCE_DATA, "/tmp" ) or die "Could not copy $SQL_REFERENCE_DATA to /tmp: $!"; unlink( $SQL_REFERENCE_DATA ); chdir("/tmp"); $< = $POSTGRES_SYS_UID; $> = $POSTGRES_SYS_UID; my $psql_command = $psql_exec . "/psql -d $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} -f $SQL_REFERENCE_DATA"; unless ( ( my $exitcode = system("$psql_command") ) == 0 ) { print STDERR "Could not populate Postgres database for the DVN app!\n"; print STDERR "(command: " . $psql_command . ")\n"; print STDERR "(psql exit code: " . $exitcode . ")\n"; print STDERR "\nYou must populate the database before you can use your new\n"; print STDERR "DVN instance. Please consult the installation manual and/or\n"; print STDERR "seek support from the DVN team.\n\n"; exit 1; } } else { # 7b. INSTRUCT THE USER TO POPULATE THE DB ON THE REMOTE SERVER: # NOT SUPPORTED YET -- TODO print "Please copy the file $SQL_REFERENCE_DATA (found in this directory)\n"; print "onto the remote server and populate the database manually,\n"; print "as user postgres, with the following command:\n\n"; print " psql -d $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} -f $SQL_REFERENCE_DATA\n"; print "then start glassfish again on this server with \n\n"; print " " . $glassfish_dir . "/bin/asadmin start-domain domain1\n\n"; # exit 0; } # back to root: $> = 0; $< = 0; chdir($cwd); print "\nOK, done!\n"; # FIXME: don't just sleep... figure out if the app is up yet. print "\n--Sleeping for 3 minutes--\n"; sleep 180; # Populate the metadata block field values, create users # and dataverses: unless ( -d "data" && -f "setup-datasetfields.sh" && -f "setup-users.sh" && -f "setup-dvs.sh" && -f "setup-all.sh" ) { chdir("../api"); } unless ( -d "data" && -f "setup-datasetfields.sh" && -f "setup-users.sh" && -f "setup-dvs.sh" && -f "setup-builtin-roles.sh" && -f "setup-all.sh" ) { print "\nERROR: Can't find the metadata and user/dataverse setup scripts!\n"; print "\tAre you running the installer in the right directory?\n"; exit 1; } for my $script ( "setup-all.sh" ) { print "Executing script " . $script . "...\n"; my $my_hostname = $CONFIG_DEFAULTS{'HOST_DNS_ADDRESS'}; my $run_script; #if ( $my_hostname ne "localhost" ) { # system( "sed 's/localhost:8080/$my_hostname/g' < " . $script . " > tmpscript.sh; chmod +x tmpscript.sh" ); # $run_script = "tmpscript.sh"; #} #else { $run_script = $script; #} unless ( my $exit_code = system( "./" . $run_script ) == 0 ) { print "\nERROR executing script " . $script . "!\n"; exit 1; } print "ok!\n"; } chdir($cwd); print "\n\nYou should now have a running DVN instance at\n"; print " http://" . $CONFIG_DEFAULTS{'HOST_DNS_ADDRESS'} . "[:YOURPORT]\n"; # (going to skip the Rserve check, for now) exit 0; # 9. FINALLY, CHECK IF RSERVE IS RUNNING: print "\n\nFinally, checking if Rserve is running and accessible...\n"; unless ( $CONFIG_DEFAULTS{'RSERVE_PORT'} =~ /^[0-9][0-9]*$/ ) { print $CONFIG_DEFAULTS{'RSERVE_HOST'} . " does not look like a valid port number,\n"; print "defaulting to 6311.\n\n"; $CONFIG_DEFAULTS{'RSERVE_PORT'} = 6311; } my ( $rserve_iaddr, $rserve_paddr, $rserve_proto ); unless ( $rserve_iaddr = inet_aton( $CONFIG_DEFAULTS{'RSERVE_HOST'} ) ) { print STDERR "Could not look up $CONFIG_DEFAULTS{'RSERVE_HOST'},\n"; print STDERR "the host you specified as your R server.\n"; print STDERR "\nDVN can function without a working R server, but\n"; print STDERR "much of the functionality concerning running statistics\n"; print STDERR "and analysis on quantitative data will not be available.\n"; print STDERR "Please consult the Installers guide for more info.\n"; exit 0; } $rserve_paddr = sockaddr_in( $CONFIG_DEFAULTS{'RSERVE_PORT'}, $rserve_iaddr ); $rserve_proto = getprotobyname('tcp'); unless ( socket( SOCK, PF_INET, SOCK_STREAM, $rserve_proto ) && connect( SOCK, $rserve_paddr ) ) { print STDERR "Could not establish connection to $CONFIG_DEFAULTS{'RSERVE_HOST'}\n"; print STDERR "on port $CONFIG_DEFAULTS{'RSERVE_PORT'}, the address you provided\n"; print STDERR "for your R server.\n"; print STDERR "DVN can function without a working R server, but\n"; print STDERR "much of the functionality concerning running statistics\n"; print STDERR "and analysis on quantitative data will not be available.\n"; print STDERR "Please consult the \"Installing R\" section in the Installers guide\n"; print STDERR "for more info.\n"; exit 0; } close(SOCK); print "\nOK!\n"; sub setup_glassfish { my $success = 1; my $failure = 0; # We are going to run a standalone shell script with a bunch of asadmin # commands to set up all the glassfish components for the application. # All the parameters must be passed to that script as environmental # variables: $ENV{'GLASSFISH_ROOT'} = $CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'}; $ENV{'GLASSFISH_DOMAIN'} = "domain1"; $ENV{'ASADMIN_OPTS'} = ""; $ENV{'MEM_HEAP_SIZE'} = $CONFIG_DEFAULTS{'DEF_MEM_SIZE'}; $ENV{'DB_PORT'} = $CONFIG_DEFAULTS{'POSTGRES_PORT'}; $ENV{'DB_HOST'} = $CONFIG_DEFAULTS{'POSTGRES_SERVER'}; $ENV{'DB_NAME'} = $CONFIG_DEFAULTS{'POSTGRES_DATABASE'}; $ENV{'DB_USER'} = $CONFIG_DEFAULTS{'POSTGRES_USER'}; $ENV{'DB_PASS'} = $CONFIG_DEFAULTS{'POSTGRES_PASSWORD'}; $ENV{'RSERVE_HOST'} = $CONFIG_DEFAULTS{'RSERVE_HOST'}; $ENV{'RSERVE_PORT'} = $CONFIG_DEFAULTS{'RSERVE_PORT'}; $ENV{'RSERVE_USER'} = $CONFIG_DEFAULTS{'RSERVE_USER'}; $ENV{'RSERVE_PASS'} = $CONFIG_DEFAULTS{'RSERVE_PASSWORD'}; $ENV{'HOST_ADDRESS'} = $CONFIG_DEFAULTS{'HOST_DNS_ADDRESS'}; $ENV{'SMTP_SERVER'} = $CONFIG_DEFAULTS{'MAIL_SERVER'}; $ENV{'FILES_DIR'} = $CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'} . "/glassfish/domains/" . $ENV{'GLASSFISH_DOMAIN'} . "/files"; system("./glassfish-setup.sh"); if ($?) { return $failure; } return $success; } sub create_pg_hash { my $pg_username = shift @_; my $pg_password = shift @_; my $encode_line = $pg_password . $pg_username; # for Redhat: ##print STDERR "executing /bin/echo -n $encode_line | md5sum\n"; my $hash; if ( $WORKING_OS eq "MacOSX" ) { $hash = `/bin/echo -n $encode_line | md5`; } else { $hash = `/bin/echo -n $encode_line | md5sum`; } chop $hash; $hash =~ s/ \-$//; if ( ( length($hash) != 32 ) || ( $hash !~ /^[0-9a-f]*$/ ) ) { print STDERR "Failed to generate a MD5-encrypted password hash for the Postgres database.\n"; exit 1; } return $hash; }