Parent Directory
|
Revision Log
Rollup of release engineering changes that shoudl make multi-architecture installs happier.
# # Copyright (c) 2003-2006 University of Chicago and Fellowship # for Interpretations of Genomes. All Rights Reserved. # # This file is part of the SEED Toolkit. # # The SEED Toolkit is free software. You can redistribute # it and/or modify it under the terms of the SEED Toolkit # Public License. # # You should have received a copy of the SEED Toolkit Public License # along with this program; if not write to the University of Chicago # at info@ci.uchicago.edu or the Fellowship for Interpretation of # Genomes at veronika@thefig.info or download a copy from # http://www.theseed.org/LICENSE.TXT. # # # FIG bootstrap script. # # Control is passed here from the toplevel configure (or dists/releases/install depending # on how far we've gotten in the process). # # The configure has set the following environment variables for our use: # # FIG_HOME Root of the FIGdisk tree we're setting up # FIGCONFIG_ENV_TYPE Type of configuration environment - "config_file" for config file with host-type->directory # mappings, or "dir" tranditional single-environment configuration. # FIGCONFIG_ENV Name of the environment we're configuring for # FIGCONFIG_ENV_CONFIG Location of enviroment configuration file. # FIGCONFIG_ENV_DIR Directory in which the binary install tree for $FIGCONFIG_ENV lives # FIGCONFIG_RELEASE Release number we're configuring # FIGCONFIG_RELEASE_DIR Directory in which that release lives # # Important note: perl system libraries may not be available when this # script is running, if the FIGCONFIG_ENV_DIR is different than it was # when the binaries were created. Part of the task of this # script is to recognize this case and configure the process # environment correctly so that the post-install process as # handled by the Makefiles can use perl properly, without concern for paths. # # # Look into the FIGCONFIG_ENV_DIR for the PREFIX that this # environment was compiled on. If that directory is different # than the one we're currently using, rewrite @INC accordingly. # # We put this into a BEGIN block so that we can later use "use" # without worrying about paths. # # We also set the $perlenv_override to true if we've done this, # so we can insert these fixes into the perl tool header. # BEGIN { print "Here in the perl bootstrap. inc is:\n" . join("\n", @INC), "\n"; my ($my_prefix, $prefix, $inc, @newInc); $my_prefix = $ENV{FIGCONFIG_ENV_DIR}; open(P, "<$my_prefix/PREFIX"); $prefix = <P>; chomp $prefix; # print "Prefix is $prefix myprefix=$my_prefix\n"; if ($prefix ne $my_prefix and $ENV{FIGCONFIG_ENV_CONFIG_TYPE} eq 'dir') { @newInc = (); for $inc (@INC) { $inc =~ s,^$prefix,$my_prefix,; push(@newInc, $inc); } $::perlenv_override = 1; @INC = @newInc; } } use FileHandle; use strict; # # Environment definition # # This list contains triples # ($name, $value, $appendFlag). $name is the name of the # variable; $value is the value to set, and $appendFlag # is nonzero if we need to append this value to an existing # environment variable. # our $Env = []; # # FIG configuration information. # This list contains tuples [$name, $value, $quote] # which are to be set in the FIG_Config modules for # both python and perl. $quote is 1 for things that need # to be quoted, 0 otherwise. # our $Config = []; # # Other key/value pairs of stuff we may need to pass # to and from the environment-specific configuration modules. # # Known keys: # # pythonpath # our $OtherConfig = {}; # # Cache values of the various places we may be installing things. # our $fig_disk = $ENV{FIG_HOME}; our $env_config_type = $ENV{FIGCONFIG_ENV_CONFIG_TYPE}; our $env_config_file = $ENV{FIGCONFIG_ENV_CONFIG_FILE}; our $env_name = $ENV{FIGCONFIG_ENV}; our $env_dir = "$ENV{FIGCONFIG_ENV_DIR}"; our $env_bin = "$ENV{FIGCONFIG_ENV_DIR}/bin"; our $env_lib = "$ENV{FIGCONFIG_ENV_DIR}/lib"; # # We are moving to use a symlink in dist/releases/current for these. # This symlink is managed by switch_to_release. # #our $release_bin = "$ENV{FIGCONFIG_RELEASE_DIR}/bin/$ENV{FIGCONFIG_ENV}"; #our $release_lib = "$ENV{FIGCONFIG_RELEASE_DIR}/lib/$ENV{FIGCONFIG_ENV}"; our $release_bin = "$fig_disk/dist/releases/current/$ENV{FIGCONFIG_ENV}/bin"; our $release_lib = "$fig_disk/dist/releases/current/$ENV{FIGCONFIG_ENV}/lib"; our $fig_bin = "$fig_disk/FIG/bin"; # # Location of start/stop servers scripts. # our $start_servers = "$fig_disk/bin/start-servers"; our $stop_servers = "$fig_disk/bin/stop-servers"; our $run_perl = "$fig_disk/bin/run_perl"; our $run_python = "$fig_disk/bin/run_python"; sub configure_std_fig_environment { # # Populate the Config with the usual stuff we need in FIG_Config.pm. # my $fig = "$fig_disk/FIG"; my $data = "$fig/Data"; my $sproutData = "$fig/SproutData"; my $hostname = `hostname`; chomp $hostname; push(@$Config, ["fig_disk", $fig_disk, 1]); push(@$Config, ["blastmat", "$fig_disk/BLASTMAT", 1]); push(@$Config, ["fig", $fig, 1]); push(@$Config, ["bin", $fig_bin, 1]); push(@$Config, ["env_config_type", $env_config_type, 1]); if ($env_config_type eq 'config_file') { push(@$Config, ["env_config_file", $env_config_file, 1]); push(@$Config, [{ perl => '&compute_env_values; ', python => '' }]); } else { push(@$Config, ["ext_bin", $env_bin, 1]); push(@$Config, ["common_runtime", $env_dir, 1]); } push(@$Config, ["arch", $ENV{FIGCONFIG_ENV}, 1]); push(@$Config, ["var", "$fig/var", 1]); push(@$Config, ["data", $data, 1]); push(@$Config, ["global", "$data/Global", 1]); push(@$Config, ["organisms", "$data/Organisms", 1]); push(@$Config, ["RC", "$fig_disk/FIG/ResolutionCenter", 1]); push(@$Config, ["NR", "$fig_disk/FIG/NR", 1]); push(@$Config, ["temp", "$fig_disk/FIG/Tmp", 1]); push(@$Config, ["sproutData", $sproutData, 1]); my $sandbox; if ($ENV{FIGCONFIG_SANDBOX}) { $sandbox = "/$ENV{FIGCONFIG_SANDBOX}"; } push(@$Config, ["temp_url", "http://$hostname$sandbox/FIG-Tmp", 1]); push(@$Config, ["cgi_url", "http://$hostname$sandbox/FIG", 1]); # # Add values for a relative base href of temp and CGI pages. The latter # is used by HHTP.pm to write common page start. It would make the most # sense to derive the above 2 values from these. -- GJO # push(@$Config, ["temp_base", "$sandbox/FIG-Tmp/", 1]); push(@$Config, ["cgi_base", "$sandbox/FIG/", 1]); push(@$Config, [ { perl => <<'END' }]); sub compute_env_values { return if defined($FIG_Config::hosttype); my $hosttype = `bash -c 'echo \$HOSTTYPE'`; if ($hosttype eq '') { die "Error retrieving hosttype; bash failed with rc=$?"; } chomp $hosttype; open(CF, "<$FIG_Config::env_config_file") or die "Cannot open $FIG_Config::env_config_file: $!"; my $found; while (<CF>) { if (/^$hosttype\t(\S+)/) { $found++; $FIG_Config::common_runtime = $1; $FIG_Config::env_bin = "$1/bin"; $FIG_Config::hosttype = $hosttype; $found++; last; } } $found or die "Could not find binary directory for hosttype $hosttype in $FIG_Config::env_config_file"; } END } sub compute_environment { # # ReleaseTools configuration. # push(@$Env, ["RTROOT", $ENV{FIG_HOME}, 0]); push(@$Env, ["RTDIST", "\$RTROOT/dist", 0]); push(@$Env, ["RTSITECONFIGDIR", "\$RTROOT/config", 0]); push(@$Env, ["RTARCH", $ENV{FIGCONFIG_ENV}, 0]); push(@$Env, ["RTCURRENT", "`cat \$RTROOT/CURRENT_RELEASE`", 0]); push(@$Env, ["FIG_HOME", $ENV{FIG_HOME}, 0]); push(@$Env, ["BLASTMAT", "$ENV{FIG_HOME}/BLASTMAT", 0]); # # Determine the path to use. # # This includes the path into the particular release we're configuring for, # and to the environment's bin directory. # my @path = (); push(@path, $fig_bin); if ($env_config_type eq 'dir') { push(@path, $env_bin); } push(@path, "$fig_disk/bin"); push(@$Env, ["PATH", join(":", @path), 1]); # # Compute LD_LIBRARY_PATH. # # Some packages, like mysql, place their shared libs in subdirectories # of the libdir. # # We can only do this if we're configured with an env dir. # if ($env_config_type eq 'dir') { my @ld_path = ($env_lib); my $dh; if (!opendir($dh, $env_lib)) { warn "Could not opendir $env_lib: $!"; } while ($_ = readdir($dh)) { next if /^\./; my $path = "$env_lib/$_"; next unless -d $path; # # See if there are any .so's in here. # my @solist = <$path/*.so*>; if (@solist > 0) { push(@ld_path, $path); } } closedir($dh); # # And if perl is dynamically linked, we need to add the perl core directory # to the path too. # my @coredir = <$env_lib/perl5/*/*/CORE>; if (@coredir) { if ( -f "$coredir[0]/libperl.so" ) { print "Found libperl in $coredir[0]\n"; push(@ld_path, $coredir[0]); } } my $ld_path = join(":", @ld_path); $OtherConfig->{ld_library_path} = $ld_path; push(@$Env, ["LD_LIBRARY_PATH", $ld_path, 1]); } # # If we're configuring with an env dir, we start with our @INC that we # found. Otherwise we just append. # my @perllib; if ($env_config_type eq 'dir') { @perllib = grep({ $_ ne "." } @INC); } push(@perllib, $release_lib, "$release_lib/FigKernelPackages", "$release_lib/WebApplication", "$release_lib/FortyEight", "$release_lib/PPO", "$fig_disk/config"); push(@$Env, ["PERL5LIB", join(":", @perllib), 1]); } sub configure_python { # # Determine the PYTHONPATH we're to use. # # Right now, we don't compute a replacement for the system path, # but we're likely going to require that *if* python is # distributed with the environment. We're currently not doing that. # # So we just need to point to any python packages in the release, # and to packages that were installed in the environment dir. # my $python = find_python(1); print "Found python at $python\n"; my $py_version = `$python -c 'import sys; print "%d.%d" % (sys.version_info[:2])'`; chomp $py_version; print "Python version $py_version\n"; # # Python figures this out for us. #$OtherConfig->{python_site_path} = "$ENV{FIGCONFIG_ENV_DIR}/lib/python$py_version/site-packages"; my @path = (); #push(@path, $OtherConfig->{python_site_path}); push(@path, "$release_lib"); push(@path, "$fig_disk/config"); push(@$Env, ["PYTHONPATH", join(":", @path), 1]); $OtherConfig->{pythonpath} = join(":", @path); } sub find_in_path { my($file, @extra) = @_; my(@path) = split(":", $ENV{PATH}); for my $p (@path, @extra) { my $x = "$p/$file"; if (-x $x) { return $x; } } return undef; } # # Find the name of the python executable we are to use. # sub find_python { my($to_exec) = @_; my $python; if (!$to_exec and $env_config_type eq 'config_file') { return $run_python; } # # Special case for the mac. # # RDO 20040603 - don't do this any more; we want to pick up # the python we ship. # if (0 && $ENV{FIGCONFIG_ENV} eq "mac") { # # We'd like to use the MacPython that is installed # as pythonw. # if ($python = find_in_path("pythonw", "/usr/local/bin")) { $OtherConfig->{python_require_poundbang_env} = 1; return $python; } # # Otherwise, we can live with the regular python. # Fall thru to the generic case. # } # # Non-mac, just look in the env dir or the path. # $python = "$ENV{FIGCONFIG_ENV_DIR}/bin/python"; if (-x $python) { # # The mac doesn't seem to like the long #! lines, so we'll use poundbang env. # if ($ENV{FIGCONFIG_ENV} =~ /^mac/) { $OtherConfig->{python_require_poundbang_env} = 1; } return $python; } return find_in_path("python"); } # # Find the name of the perl executable we are to use. # sub find_perl { my $perl; if ($env_config_type eq 'config_file') { return $run_perl; } $perl = "$ENV{FIGCONFIG_ENV_DIR}/bin/perl"; if (-x $perl) { return $perl; } warn "We did not find a perl executable in the SEED distribution; some modules may not be found\n"; return find_in_path("perl"); } sub write_bash_init { my($fh, $env) = @_; foreach my $item (@$env) { my($name, $value, $append) = @$item; if ($append) { # # Write code to detect if the value is set, and act accordingly. # print $fh <<END; DELIM= if [ -n "\$$name" ] ; then DELIM=: fi $name=$value\${DELIM}\${$name} export $name END } else { print $fh "$name=\"$value\"\n"; print $fh "export $name\n"; } } # # If we're configuring from a config file, add the code to set up the PATH with the # right ext_bin. # if ($env_config_type eq 'config_file') { print $fh "export FIG_ENV_CONFIG_FILE='$env_config_file'\n"; print $fh <<'END'; env_dir=`awk "\\$1 == \"$HOSTTYPE\" { print \\$2 }" $FIG_ENV_CONFIG_FILE` export PATH=$env_dir/bin:${PATH} END } print $fh "alias rtpath='source \$RTDIST/releases/\$RTCURRENT/ReleaseTools/RTPath.sh'\n"; } sub write_csh_init { my($fh, $env) = @_; foreach my $item (@$env) { my($name, $value, $append) = @$item; if ($append) { # # Write code to detect if the value is set, and act accordingly. # print $fh <<END; if (\$?$name) then setenv $name $value:\${$name} else setenv $name $value endif END } else { print $fh "setenv $name \"$value\"\n"; } } # # Alias for RT stuff. # print $fh "alias rtpath 'source \$RTDIST/releases/\$RTCURRENT/ReleaseTools/RTPath.csh'\n"; } sub run_script { my($script) = @_; unless (my $ret = do $script) { if ($@) { warn "Error parsing $script: $@\n"; } elsif (!defined($ret)) { warn "Couldn't do $script: $!\n"; } else { warn "Counldn't run $script\n"; } } } sub configure_environment_specific { my $env_script = $ENV{FIGCONFIG_ENV_CONFIG}; if (! -f $env_script) { warn "No environment-specific configuration file $env_script found, skipping\n"; return; } run_script($env_script); } # # Create any directories that might be missing. # sub setup_directories { my(@needed) = @_; for my $dir (@needed) { if (! -d $dir) { mkdir($dir) or warn "Could not create $dir: $!\n"; } } } sub setup_server_scripts { # # Remove any start/stop servers scripts we might have, and write the stub # start. # unlink($start_servers); unlink($stop_servers); open(F, ">$start_servers") or die "Cannot write $start_servers: $!"; print F "#!/bin/sh\n\n"; close(F); chmod(0775, $start_servers); open(F, ">$stop_servers") or die "Cannot write $stop_servers: $!"; print F "#!/bin/sh\n\n"; close(F); chmod(0775, $stop_servers); } sub write_run_perl { unlink($run_perl); open(F, ">$run_perl") or die "Cannot write $run_perl: $!"; print F "#!/bin/sh\n\n"; print F ". $fig_disk/config/fig-user-env.sh\n\n"; if ($env_config_type eq 'config_file') { print F <<'END'; env_dir=`awk "\\$1 == \"$HOSTTYPE\" { print \\$2 }" $FIG_ENV_CONFIG_FILE` perl="$env_dir/bin/perl" END } else { print F "perl=$env_dir/bin/perl\n"; } print F 'exec $perl "$@"' . "\n"; close(F); chmod(0775, $run_perl); } sub write_run_python { unlink($run_python); open(F, ">$run_python") or die "Cannot write $run_python: $!"; print F "#!/bin/sh\n\n"; print F ". $fig_disk/config/fig-user-env.sh\n\n"; if ($env_config_type eq 'config_file') { print F <<'END'; env_dir=`awk "\\$1 == \"$HOSTTYPE\" { print \\$2 }" $FIG_ENV_CONFIG_FILE` python="$env_dir/bin/python" END } else { print F "python=$env_dir/bin/python\n"; } print F 'exec $python "$@"' . "\n"; close(F); chmod(0775, $run_python); } sub finalize_server_scripts { # # After any environment-specific stuff, call start_services and stop_services. # open(F, ">>$start_servers") or die "Cannot write $start_servers: $!"; print F "\n$fig_bin/start_services\n"; close(F); chmod(0775, $start_servers); open(F, ">>$stop_servers") or die "Cannot write $stop_servers: $!"; print F "\n$fig_bin/stop_services\n"; close(F); chmod(0775, $stop_servers); } sub write_config_pm { my($fh, $config) = @_; print $fh "package FIG_Config;\n\n"; foreach my $item (@$config) { my($name, $value, $quote) = @$item; # # special code for non-var=value items. # if (ref($name) eq 'HASH') { my $l = $name->{perl}; if ($l ne '') { print $fh "$l\n"; } } else { my $q = $quote ? '"' : ''; printf $fh "\$%-15s = $q$value$q;\n", $name; } } print $fh "\n1;\n"; } sub write_config_py { my($fh, $config) = @_; foreach my $item (@$config) { my($name, $value, $quote) = @$item; # # special code for non-var=value items. # if (ref($name) eq 'HASH') { my $l = $name->{python}; if ($l ne '') { print $fh "$l\n"; } } else { # # Ugh. "global" is a keyword in python. # $name = "global_dir" if $name eq "global"; my $q = $quote ? '"' : ''; printf $fh "%-15s = $q$value$q\n", $name; } } } sub write_tool_hdr_perl { my($fh) = @_; my $perl = find_perl(); print $fh "#!$perl\n"; print $fh "\n"; if ($::perlenv_override) { # # Write the tool header BEGIN block to reset the environment. # print $fh "BEGIN {\n"; print $fh " \@INC = qw(\n"; for my $inc (@INC) { next if $inc eq '.'; print $fh "\t$inc\n"; } print $fh ");\n"; print $fh "}\n"; } print $fh "use Data::Dumper;\n"; print $fh "use Carp;\n"; # # We generate a comment here that gets expanded by switch_to_release # This is part of the effort in making the environment bootstrapping # code independent of releases. # #print $fh "use lib \"$release_lib\";\n"; #print $fh "use lib \"$release_lib/FigKernelPackages\";\n"; print $fh "# Following block is expanded by switch_to_release to add use lib directives\n"; print $fh "# to point at the correct locations in the release directory.\n"; print $fh "#BEGIN switch_to_release generated code\n"; print $fh "#END switch_to_release generated code\n"; print $fh "\n"; print $fh "use lib \"$fig_disk/config\";\n"; print $fh "use FIG_Config;\n"; print $fh "\n"; print $fh "#### END tool_hdr ####\n\n" } sub write_tool_hdr_python { my($fh) = @_; my $python = find_python(); if ($OtherConfig->{python_require_poundbang_env}) { print $fh "#!/usr/bin/env $python\n"; } else { print $fh "#!$python\n"; } print $fh "\n"; print $fh "import sys, os\n"; print $fh "sys.path.append('$OtherConfig->{python_site_path}')\n"; # # Append the perl path to the environment, for use later with CallPerl. # my $perlpath = join(":", @INC, $release_lib, "$release_lib/FigKernelPackages", "$fig_disk/config"); print $fh <<END; if os.getenv("PERL5LIB", "") != "": _delim = ":" else: _delim = "" os.environ["PERL5LIB"] = "$perlpath" + _delim + os.getenv("PERL5LIB", "") END print $fh "# Following block is expanded by switch_to_release to add use lib directives\n"; print $fh "# to point at the correct locations in the release directory.\n"; print $fh "#BEGIN switch_to_release generated code\n"; print $fh "#END switch_to_release generated code\n"; print $fh "\n"; print $fh "sys.path.append('$fig_disk/config')\n"; print $fh "import FIG_Config\n"; print $fh "\n"; print $fh "#### END tool_hdr_py ####\n\n" } sub write_rtconfig { my($fh) = @_; my $python = find_python(); my $perl = find_perl(); print $fh "RTPYTHON=$python\n"; print $fh "RTPERL=$perl\n"; print $fh "RTPYTHONPATH=$OtherConfig->{pythonpath}\n"; my %seen; my @perlpath; my @dirs; if ($env_config_type eq 'dir') { push(@dirs, @INC); } push(@dirs, "$fig_disk/config"); for (@dirs) { next if $seen{$_}; push(@perlpath, $_); $seen{$_}++; } my $perlpath = join(":", @perlpath); print $fh "RTPERL5LIB=$perlpath\n"; print $fh "RTPYTHONIMPORTS=FIG_Config\n"; print $fh "RTPERLIMPORTS=FIG_Config\n"; print $fh "RTSETENV=BLASTMAT=$fig_disk/BLASTMAT\n"; print $fh "RTSETENV=FIG_HOME=$fig_disk\n"; print $fh "#RTLD_LDPATH=$OtherConfig->{ld_library_path}\n"; } setup_directories("$fig_disk/bin", "$fig_disk/config"); setup_server_scripts(); write_run_perl(); write_run_python(); find_python(); compute_environment(); configure_std_fig_environment(); configure_python(); configure_environment_specific(); # configure_database(); finalize_server_scripts(); # # Write the shell startup to the figdisk. # open(FH, ">$fig_disk/config/fig-user-env.sh") or die "Cannot write $fig_disk/config/fig-user-env.sh: $!"; write_bash_init(\*FH, $Env); close(FH); open(FH, ">$fig_disk/config/fig-user-env.csh") or die "Cannot write $fig_disk/config/fig-user-env.csh: $!"; write_csh_init(\*FH, $Env); close(FH); # # Write the FIG_Config file. # open(FH, ">$fig_disk/config/FIG_Config.pm") or die "Cannot write $fig_disk/config/FIG_Config.pm: $!"; write_config_pm(\*FH, $Config); close(FH); open(FH, ">$fig_disk/config/FIG_Config.py") or die "Cannot write $fig_disk/config/FIG_Config.py: $!"; write_config_py(\*FH, $Config); close(FH); # # Write the tool headers # open(FH, ">$fig_disk/config/base_tool_hdr") or die "Cannot write $fig_disk/config/tool_hdr: $!"; write_tool_hdr_perl(\*FH); close(FH); open(FH, ">$fig_disk/config/base_tool_hdr_py") or die "Cannot write $fig_disk/config/tool_hdr_py: $!"; write_tool_hdr_python(\*FH); close(FH); open(FH, ">$fig_disk/config/RTConfig") or die "Cannot write $fig_disk/config/RTConfig: $!"; write_rtconfig(\*FH); close(FH); unshift(@INC, "$ENV{FIGCONFIG_RELEASE_DIR}"); require FigCommon::SwitchRelease; # # We need to tweak the current path and PERL5LIB environment to get bootstrapping to # work correctly. # $ENV{PATH} = "$ENV{FIGCONFIG_ENVDIR}/bin:$ENV{PATH}"; $ENV{PERL5LIB} = (map { $_->[1] } grep { $_->[0] eq "PERL5LIB"} @$Env)[0]; &FigCommon::SwitchRelease::switch_to_release($fig_disk, $ENV{FIGCONFIG_ENV}, $ENV{FIGCONFIG_RELEASE});
MCS Webmaster | ViewVC Help |
Powered by ViewVC 1.0.3 |