00bd6030314d75c6fa7f81fd2434ee16cfd04943
max
  Wed Jul 7 07:16:16 2021 -0700
fixing gbic script output random error messages on startup by changing the entire error handling, refs #27795

diff --git src/product/installer/browserSetup.sh src/product/installer/browserSetup.sh
index c3f28c6..b26f58a 100755
--- src/product/installer/browserSetup.sh
+++ src/product/installer/browserSetup.sh
@@ -1,32 +1,41 @@
 #!/bin/bash
 
 # script to install/setup dependencies for the UCSC genome browser CGIs
 # call it like this as root from a command line: bash browserInstall.sh
 
 # you can easily debug this script with 'bash -x browserInstall.sh', it 
 # will show all commands then
 
 set -u -e -o pipefail # fail on unset vars and all errors, also in pipes
 
-function errorHandler {
+exitHandler() {
+    if [ "$1" == "100" -o "$1" == "0" ] ; then
+       exit 1 # all fine, a specific error message has already been output
+    fi
+
+    # somehow this script exited with an unknown type of error code
+    echo Exit error $1 occurred on line $2
     echo The UCSC Genome Browser installation script exited with an error.
     echo Please contact us at genome-mirror@soe.ucsc.edu and send us an output log 
     echo of the command prefixed with '"bash -x"', e.g.
     echo 'bash -x browserSetup.sh install 2>&1 > install.log'
 }
-trap errorHandler ERR
+
+# only trap the exit, not the errors 
+# see https://medium.com/@dirk.avery/the-bash-trap-trap-ce6083f36700
+trap 'exitHandler $? $LINENO' EXIT
 
 # ---- GLOBAL DEFAULT SETTINGS ----
 
 # Directory where CGI-BIN and htdocs are downloaded to.
 # this is the main runtime directory of the genome browser. It contains
 # CGI binaries, the config file (hg.conf), temporary ("trash") files, downloaded pieces of big files
 # ("udcCache") and various other runtime data needed for the browser
 APACHEDIR=/usr/local/apache
 
 # apache document root, for html documents
 HTDOCDIR=$APACHEDIR/htdocs
 # apache CGI-bin directory
 CGIBINDIR=$APACHEDIR/cgi-bin
 # directory for temporary files
 TRASHDIR=$APACHEDIR/trash
@@ -748,31 +757,31 @@
 
 }
 
 # OSX specific setup of the installation
 function installOsx () 
 {
    # check for xcode
    if [ -f /usr/bin/xcode-select 2> /dev/null > /dev/null ]; then
        echo2 Found XCode
    else
        echo2
        echo2 'This installer has to compile the UCSC tools locally on OSX.'
        echo2 'Please install XCode from https://developer.apple.com/xcode/downloads/'
        echo2 'Start XCode once and accept the Apple license.'
        echo2 'Then run this script again.'
-       exit 101
+       exit 100
    fi
 
    # make sure that the xcode command line tools are installed
    echo2 Checking/Installing Xcode Command line tools
    xcode-select --install 2> /dev/null >/dev/null  || true
 
    # in case that it is running, try to stop Apple's personal web server, we need access to port 80
    # ignore any error messages
    #if [ -f /usr/sbin/apachectl ]; then
        #echo2 Stopping the Apple Personal Web Server
        #/usr/sbin/apachectl stop 2> /dev/null || true
        #launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist 2> /dev/null || true
    #fi
 
    if [ -f ~/.my.cnf ]; then
@@ -1071,31 +1080,31 @@
 function mysqlChangeRootPwd ()
 {
    # first check if an old password still exists in .my.cnf
    if [ -f ~/.my.cnf ]; then
        echo2 ~/.my.cnf already exists, you might want to remove this file
        echo2 and restart the script if an error message appears below.
        echo2
    fi
 
    # generate a random char string
    # OSX's tr is quite picky with unicode, so change LC_ALL temporarily
    MYSQLROOTPWD=`cat /dev/urandom | LC_ALL=C tr -dc A-Za-z0-9 | head -c8` || true
    # paranoia check
    if [[ "$MYSQLROOTPWD" == "" ]]; then
        echo2 Error: could not generate a random Mysql root password
-       exit 111
+       exit 100
    fi
 
    echo2
    echo2 The Mysql server was installed and therefore has an empty root password.
    echo2 Trying to set mysql root password to the randomly generated string '"'$MYSQLROOTPWD'"'
 
    # now set the mysql root password
    if $MYSQLADMIN -u root password $MYSQLROOTPWD; then
        # and write it to my.cnf
        if [ ! -f ~/.my.cnf ]; then
            echo2
            echo2 Writing password to ~/.my.cnf so root does not have to provide a password on the 
            echo2 command line.
            echo '[client]' >> ~/.my.cnf
            echo user=root >> ~/.my.cnf
@@ -1105,61 +1114,61 @@
         else
            echo2 ~/.my.cnf already exists, not changing it.
         fi 
    else
        echo2 Could not connect to mysql to set the root password to $MYSQLROOTPWD.
        echo2 A root password must have been set by a previous installation.
        echo2 Please reset the root password to an empty password by following these
        echo2 instructions: http://dev.mysql.com/doc/refman/5.0/en/resetting-permissions.html
        echo2 Then restart the script.
        echo2 Or, if you remember the old root password, write it to a file ~/.my.cnf, 
        echo2 create three lines
        echo2 '[client]'
        echo2 user=root
        echo2 password=PASSWORD
        echo2 run chmod 600 ~/.my.cnf and restart this script.
-       exit 123
+       exit 100
    fi
 }
 
 function checkCanConnectMysql ()
 {
 if $MYSQL -e "SHOW DATABASES;" 2> /dev/null > /dev/null; then
     true
 else
     echo2 "ERROR:"
     echo2 "Cannot connect to mysql database server, a root password has probably been setup before."
     # create a little basic .my.cnf for the current root user
     # so the mysql root password setup is easier
     if [ ! -f ~/.my.cnf ]; then
        echo '[client]' >> ~/.my.cnf
        echo user=root >> ~/.my.cnf
        echo password=YOURMYSQLPASSWORD >> ~/.my.cnf
        chmod 600 ~/.my.cnf
        echo2
        echo2 A file ${HOME}/.my.cnf was created with default values
        echo2 Edit the file ${HOME}/.my.cnf and replace YOURMYSQLPASSWORD with the mysql root password that you
        echo2 defined during the mysql installation.
     else
        echo2
        echo2 A file ${HOME}/.my.cnf already exists
        echo2 Edit the file ${HOME}/.my.cnf and make sure there is a '[client]' section
        echo2 and under it at least two lines with 'user=root' and 'password=YOURMYSQLPASSWORD'.
     fi
        
     echo2 "Then run this script again."
-    exit 200
+    exit 100
 fi
 }
    
 # check if a program exists in the PATH
 function commandExists () {
     type "$1" &> /dev/null ;
 }
 
 # DETECT AND DEACTIVATE SELINUX: if it exists and is active
 function disableSelinux () 
 {
 # first check if the command exists on this system
 # then check if it comes back with a non-zero error code, which means it is enabled
 if commandExists selinuxenabled; then
     if [ selinuxenabled ]; then
@@ -1255,31 +1264,31 @@
     
     # removed these now for the new hgGateway page, Apr 2016
     # by default hgGateway needs an empty hg19 database, will crash otherwise
     # $MYSQL -e 'CREATE DATABASE IF NOT EXISTS hg19'
     # mm9 needs an empty hg18 database
     $MYSQL -e 'CREATE DATABASE IF NOT EXISTS hg18'
     
     $MYSQL -e "FLUSH PRIVILEGES;"
 }
 
 # main function, installs the browser on Redhat/Debian and potentially even on OSX
 function installBrowser () 
 {
     if [ -f $COMPLETEFLAG ]; then
         echo2 error: the file $COMPLETEFLAG exists. It seems that you have installed the browser already.
-        exit 246
+        exit 100
     fi
 
     echo '--------------------------------'
     echo UCSC Genome Browser installation
     echo '--------------------------------'
     echo Detected OS: $OS/$DIST, $VER
     echo 
     echo This script will go through three steps:
     echo "1 - setup apache and mysql, open port 80, deactivate SELinux"
     echo "2 - copy CGI binaries into $CGIBINDIR, html files into $HTDOCDIR"
     echo "3 - optional: download genome assembly databases into mysql and /gbdb"
     echo
     echo This script will now install and configure Mysql and Apache if they are not yet installed. 
     echo "Your distribution's package manager will be used for this."
     echo If Mysql is not installed yet, it will be installed, secured and a root password defined.
@@ -1312,41 +1321,41 @@
     # before we do anything else with mysql
     # we need to check if we can access it. 
     # so test if we can connect to the mysql server
     checkCanConnectMysql
 
     disableSelinux
 
     checkDownloadUdr
 
     # CGI DOWNLOAD AND HGCENTRAL MYSQL DB SETUP
 
     if [ ! -f $COMPLETEFLAG ]; then
         # test if an apache file is already present
         if [ -f "$APACHEDIR" ]; then
             echo2 error: please remove the file $APACHEDIR, then restart the script with "bash $0".
-            exit 249
+            exit 100
         fi
     fi
 
     # check if /usr/local/apache is empty
     # on OSX, we had to create an empty htdocs, so skip this check there
     if [ -d "$APACHEDIR" -a "$OS" != "OSX" ]; then
         echo2 error: the directory $APACHEDIR already exists.
         echo2 This installer has to overwrite it, so please move it to a different name
         echo2 or remove it. Then start the installer again with "bash $0 install"
-        exit 250
+        exit 100
     fi
 
     mysqlDbSetup
 
     # -------------------
     # CGI installation
     # -------------------
     echo2
     echo2 Creating $CGIBINDIR and $HTDOCDIR and downloading contents from UCSC
     waitKey
     
     # create apache directories: HTML files, CGIs, temporary and custom track files
     mkdir -p $HTDOCDIR $CGIBINDIR $TRASHDIR $TRASHDIR/customTrash
     
     # the CGIs create links to images in /trash which need to be accessible from htdocs
@@ -1425,31 +1434,31 @@
     echo2
     echo2 To finish the installation, you need to download genome data to the local
     echo2 disk. To download a genome assembly and all its files now, call this script again with
     echo2 the parameters 'download "<assemblyName1> <assemblyName2> ..."', e.g. '"'bash $0 mirror mm10 hg19'"'
     echo2 
     showMyAddress
 }
 
 # GENOME DOWNLOAD: mysql and /gbdb
 function downloadGenomes
 {
     DBS=$*
     GENBANKTBLS=""
     if [ "$DBS" == "" ] ; then
         echo2 Argument error: the '"download"' command requires at least one assembly name, like hg19 or mm10.
-        exit 1
+        exit 100
     fi
 
     echo2
     echo2 Downloading databases $DBS plus hgFixed/proteome/go from the UCSC download server
     echo2
     echo2 Determining download file size... please wait...
 
     if [ "$ONLYGENOMES" == "0" ]; then
         if [[ "$DBS" =~ hg|mm|rn3|rn4|sacCer|dm3|danRer3|ce6 ]]; then
             echo2 Downloading $DBS plus hgFixed proteome go hgFixed
             MYSQLDBS="$DBS proteome uniProt go hgFixed"
         else
             echo2 Downloading $DBS plus GenBank and RefSeq tables
             MYSQLDBS="$DBS"
             GENBANKTBLS="author cell description development gbCdnaInfo gbExtFile gbLoaded \
@@ -1591,31 +1600,31 @@
     elif [ -f /usr/lib/systemd/system/mysql.service ]; then
             # at least seen in Fedora 17
             systemctl start mysql
     else
         echo2 Could not find mysql nor mysqld file in /etc/init.d. Please email genome-mirror@soe.ucsc.edu.
     fi
 }
 
 # only download a set of minimal mysql tables, to make a genome browser that is using the mysql failover mechanism
 # faster. This should be fast enough in the US West Coast area and maybe even on the East Coast.
 function downloadMinimal
 {
     DBS=$*
     if [ "$DBS" == "" ] ; then
         echo2 Argument error: the '"minimal"' command requires at least one assembly name, like hg19 or mm10.
-        exit 1
+        exit 100
     fi
 
     echo2
     echo2 Downloading minimal tables for databases $DBS 
 
     # only these db tables are copied over by default
     minRsyncOpt="--include=cytoBand.* --include=chromInfo.* --include=cytoBandIdeo.* --include=kgColor.* --include=knownAttrs.* --include=knownGene.* --include=knownToTag.* --include=kgXref.* --include=ensemblLift.* --include=ucscToEnsembl.* --include=wgEncodeRegTfbsCells.* --include=encRegTfbsClusteredSources.* --include=tableList.* --include=refSeqStatus.* --include=wgEncodeRegTfbsCellsV3.* --include=extFile.* --include=trackDb.* --include=grp.* --include=ucscRetroInfo5.* --include=refLink.* --include=ucscRetroSeq5.* --include=ensemblLift.* --include=knownCanonical.* --include=gbExtFile.* --include=flyBase2004Xref --include=hgFindSpec.* --include=ncbiRefSeq*"
 
     # these tables are not used for searches by default. Searches are very slow. We focus on genes.
     notSearchTables='wgEncodeGencodeBasicV19 wgEncodeGencodeCompV17 wgEncodeGencodeBasicV14 wgEncodeGencodeBasicV17 wgEncode GencodeCompV14 mgcFullMrna wgEncodeGencodeBasicV7 orfeomeMrna wgEncodeGencodePseudoGeneV14 wgEncodeGencodePseudoGeneV17 wgEncodeGencodePseudoGeneV19 wgEncodeGencodeCompV7 knownGeneOld6 geneReviews transMapAlnSplicedEst gbCdnaInfo oreganno vegaPseudoGene transMapAlnMRna ucscGenePfam qPcrPrimers transMapAlnUcscGenes transMapAlnRefSeq genscan bacEndPairs fosEndPairs'
 
     # these tracks are hidden by default
     hideTracks='intronEst cons100way cons46way ucscRetroAli5 mrna'
 
     stopMysql
@@ -1775,31 +1784,31 @@
       # need to include all subdirectories for include to work
       # need to exclude everything else for exclude to work
       if [[ "$val" == "bestEncode" ]]; then
           RSYNCOPTS="-m --include=wgEncodeGencode* --include=wgEncodeBroadHistone* --include=wgEncodeReg* --include=wgEncodeAwg* --include=wgEncode*Mapability* --include=*/ --exclude=wgEncode*"
           ONLYGENOMES=0
       elif [[ "$val" == "noEncode" ]]; then
           RSYNCOPTS="-m --include=wgEncodeGencode* --include=*/ --exclude=wgEncode*"
           ONLYGENOMES=0
       elif [[ "$val" == "main" ]]; then
           # gbCdnaInfo
           # SNP table selection explained in #17335
           RSYNCOPTS="-m --include=grp.* --include=*gold* --include=augustusGene.* --include=chromInfo.* --include=cpgIslandExt.* --include=cpgIslandExtUnmasked.* --include=cytoBandIdeo.* --include=genscan.* --include=microsat.* --include=simpleRepeat.* --include=tableDescriptions.* --include=ucscToINSDC.* --include=windowmaskerSdust.*  --include=gold.* --include=chromInfo.* --include=trackDb* --include=hgFindSpec.* --include=gap.* --include=*.2bit --include=html/description.html --include=refGene* --include=refLink.* --include=wgEncodeGencode* --include=snp146Common* --include=snp130* --include=snp142Common* --include=snp128* --include=gencode* --include=rmsk* --include=*/ --exclude=*"
           ONLYGENOMES=1 # do not download hgFixed,go,proteome etc
       else
           echo "Unrecognized -t value. Please read the help message, by running bash $0 -h"
-          exit 1
+          exit 100
       fi
       ;;
     u)
       RSYNC="/usr/local/bin/udr rsync"
       checkDownloadUdr
       ;;
     o)
       if [ ! -f $APACHEDIR/cgi-bin/hg.conf ]; then
          echo Please install a browser first, then switch the data loading mode.
       fi
 
       goOffline
       echo $APACHEDIR/cgi-bin/hg.conf was modified. 
       echo Offline mode: data is loaded only from the local Mysql database and file system.
       echo Use the parameter -f to switch to on-the-fly mode.
@@ -1818,31 +1827,31 @@
       ;;
     \?)
       echo "Invalid option: -$OPTARG" >&2
       ;;
   esac
 done
 # reset the $1, etc variables after getopts
 shift $(($OPTIND - 1))
 
 # detect the OS version, linux distribution
 unameStr=`uname`
 DIST=none
 
 if [[ "$unameStr" == MINGW32_NT* ]] ; then
     echo Sorry Windows/CYGWIN is not supported
-    exit 1
+    exit 100
 fi
 
 # set a few very basic variables we need to function
 if [[ "$unameStr" == Darwin* ]]; then
     OS=OSX
     DIST=OSX
     VER=`sw_vers -productVersion`
     APACHECONFDIR=$APACHEDIR/ext/conf # only used by the OSX-spec part
     APACHECONF=$APACHECONFDIR/001-browser.conf
     APACHEUSER=_www # predefined by Apple
     MYSQLDIR=$APACHEDIR/mysqlData
     MYSQLUSER=_mysql # predefined by Apple
     MYSQL="$APACHEDIR/ext/bin/mysql --socket=$APACHEDIR/ext/mysql.socket"
     MYSQLADMIN="$APACHEDIR/ext/bin/mysqladmin --socket=$APACHEDIR/ext/mysql.socket"
     SEDINPLACE="sed -Ei .bak" # difference BSD vs Linux
@@ -1865,67 +1874,67 @@
     elif [[ -f /etc/os-release ]]; then
         # line looks like this on Amazon AMI Linux: 'ID_LIKE="rhel fedora"'
         source /etc/os-release
         if [[ $ID_LIKE == rhel* ]]; then
                 DIST=redhat
                 VER=$VERSION
                 APACHECONF=/etc/httpd/conf.d/001-browser.conf
                 APACHEUSER=apache
         fi
     fi
 fi
 
 if [ "$DIST" == "none" ]; then
     echo Sorry, unable to detect your linux distribution. 
     echo Currently only Debian and Redhat-style distributions are supported.
-    exit 3
+    exit 100
 fi
 
 lastArg=${*: -1:1}
 if [[ "$#" -gt "1" && ( "${2:0:1}" == "-" ) || ( "${lastArg:0:1}" == "-" )  ]]; then
   echo "Error: The options have to be specified before the command, not after it."
   echo
   echo "$HELP_STR"
-  exit 1
+  exit 100
 fi
 
 if uname -m | grep -vq _64; then
   echo "Your machine does not seem to be a 64bit system"
   echo "Sorry, the Genome Browser requires a 64bit linux."
-  exit 1
+  exit 100
 fi
 
 if [[ "$EUID" != "0" ]]; then
   echo "This script must be run as root or with sudo like this:"
   echo "sudo -H $0"
-  exit 1
+  exit 100
 fi
 
 if [ "${1:-}" == "install" ]; then
    installBrowser
 
 elif [ "${1:-}" == "minimal" ]; then
    downloadMinimal ${@:2} # all arguments after the second one
 
 elif [ "${1:-}" == "mirror" ]; then
    downloadGenomes ${@:2} # all arguments after the second one
 
 elif [ "${1:-}" == "cgiUpdate" ]; then
    cgiUpdate
 
 elif [ "${1:-}" == "update" ]; then 
    updateBrowser ${@:2} # all arguments after the second one
 
 elif [ "${1:-}" == "clean" ]; then
     cleanTrash
 
 elif [ "${1:-}" == "addTools" ]; then
     addTools
 
 elif [ "${1:-}" == "mysql" ]; then
     mysqlDbSetup
 
 else
    echo Unknown command: $1
    echo "$HELP_STR"
-   exit 1
+   exit 100
 fi