#!/bin/bash # $Id: yaim-install-ui.sh,v 1.11 2007/09/26 12:59:46 dennisvd Exp $ # Easy yaim UI node Installation # (Skip to section main to see where the script starts its work) ###################################################################### # Section: variables ###################################################################### pocversion=2.1 scriptversion=7 yaim_version=3.1.1 apt_version=0.5.15cnc6-4.SL.i386 # Options and parameters which can be overriden on the command line MIRROR=http://poc.vl-e.nl/distribution/$pocversion CMD_SITE_INFO_DEF= CMD_NODETYPE=UI DRYRUN=0 dryprefix= ERROR_STATE=OK # did we detect a problem along the way? INSTALLDIR= POC_CONF=/etc/opt/vl-e/poc.conf SITE_INFO_DEF=/etc/opt/vl-e/site-info.def YAIM=/opt/glite/yaim NODETYPE=UI USE_APT=0 # this is set to 1 for RHEL3 # base os assumptions - do not change UYKWYD READLINK=/usr/bin/readlink RPM=/bin/rpm CP=/bin/cp RM=/bin/rm GPG=/usr/bin/gpg WGET=/usr/bin/wget YUM=/usr/bin/yum APT_GET=/usr/bin/apt-get pkg_mgr=$YUM # RPM's that we know conflict with lcg/vl-e software #CONFLICTING_RPMS="lam-6.5.9 rh-postgresql-devel" # Sanitize the PATH before we do anything else PATH=/bin:/sbin:/usr/bin:/usr/sbin:$PATH export PATH ###################################################################### # Section: Functions ###################################################################### # send to the screen and the log function say() { echo "$@" echo "$@" >&2 } function say_n() { echo -n "$@" echo "$@" >&2 } # echo just to the log function log() { echo $dryprefix "$@" >&2 } function die() { say "FAILED" exec 2>&3 echo "Error: $1" >&2 echo "Tail of the log file follows ($LOGFILE):" >&2 echo "----------------------------------------------------------------------" >&2 echo " ..." >&2 tail $LOGFILE >&2 echo "----------------------------------------------------------------------" >&2 echo "Exiting." trap - EXIT builtin exit 1 } function fail() { echo "$@" exit 1 } # This function will evaluate its arguments if DRYRUN=0; # Otherwise it will just echo them. function really() { if (( $DRYRUN )); then log "$@" else "$@" fi } function usage() { cat < 0 && ! $DRYRUN )); then echo "Only root can run the YAIM Installer." bailout 1 fi # check for existing site-info.def if [ -n "$CMD_SITE_INFO_DEF" ]; then if [ ! -r $CMD_SITE_INFO_DEF ]; then echo "Can't read file $CMD_SITE_INFO_DEF." echo "Sorry, but I can't go on." bailout 1 fi fi } # Function goodbye is called automatically on exit during the normal # operation of the installer... function goodbye() { echo "Goodbye." echo "Log file is $LOGFILE." log "YAIM Installer finished on `date`" } # ...but bailout escapes immediately by using the ejection seat. function bailout() { if [ -n "$INSTALLDIR" -a -d "$INSTALLDIR" ]; then $RM -rf $INSTALLDIR fi trap - EXIT exit $1 } function log_output() { # Send all further errors to the logfile # save old stderr in FD 3, stdout in FD 4 # send all output to the logfile as well #exec 3>&2 2> $LOGFILE 1> >(tee --append $LOGFILE) echo "Logging details to $LOGFILE" exec 3>&2 2> $LOGFILE trap goodbye EXIT } # sometimes we need to toggle stderr, because of select menu input. function error_to_log() { exec 2>> $LOGFILE } function error_to_screen() { exec 2>&3 } function check_update() { echo -n \ "Checking for newer version of yaim-install-ui ....................... " SCRIPTAVAIL=`$WGET $MIRROR/extra/yaim-install-ui -O- -o /dev/null | awk -F= '/^scriptversion=/ { print $2 }' ` || { echo "FAILED" log "Couldn't get $MIRROR/extra/yaim-install-ui" return } if [ -n "SCRIPTAVAIL" ] && [ "$SCRIPTAVAIL" -gt "$scriptversion" ]; then echo "Found build $SCRIPTAVAIL" echo "A newer version of the YAIM installer is available" echo "Do you want to download it?" PS3="Please select a number from 1-4 : " select ans in "yes" "no" "help" "quit"; do case $ans in (yes) mv $1 $1.old wget -O $1 $MIRROR/extra/yaim-install-ui -o /dev/null || \ die "Could not get $MIRROR/extra/yaim-install-ui" chmod u+x $1 echo "OK, Starting the new YAIM installer" exec sh "$@" break ;; (no) echo "OK, proceeding with the old installer." exit 0 break ;; (quit) echo "OK, quitting." bailout 1 ;; (*) cat < $INSTALLDIR/missing-packages <&2 else # adding a little more robustness; if wget is not yet installed # try rpm anyway. if [ -x $WGET ]; then $WGET $1 -O $INSTALLDIR/$(basename $1) >&2 $RPM -i $INSTALLDIR/$(basename $1) >&2 else log "wget is not (yet) installed, trying $RPM." $RPM -i $1 >&2 fi fi } # Check the flavour and version of the distribution function check_distro() { say_n \ "Checking OS distribution ............................................ " if [ ! -f /etc/redhat-release ]; then # this is not a RHEL compatible distribution DISTRO=unk else OSVERSION=$(sed -e 's/.* \([0-9]\).*/\1/' /etc/redhat-release) if [ -z $OSVERSION -o $OSVERSION -lt 3 -o $OSVERSION -gt 4 ]; then OSVERSIONMISMATCH=1 fi if grep -q "Red Hat Enterprise Linux" /etc/redhat-release; then DISTRO=rhel detect="Detected Red Hat Enterprise Linux, release $OSVERSION" elif grep -q "CentOS" /etc/redhat-release; then DISTRO=centos detect="Detected CentOS release $OSVERSION" elif grep -q "Scientific Linux" /etc/redhat-release; then DISTRO=sl detect="Detected Scientific Linux release $OSVERSION" else DISTRO=unk fi fi if [ $DISTRO = "unk" ] || (( $OSVERSIONMISMATCH )); then say "FAILED" say say "I could not determine the kind of Linux distribution of this system." say "This installer only works on Red Hat Enterprise Linux compatible" say "systems, such as CentOS and Scientific Linux; what shall we do?" say "Please choose which flavour closest matches your system, and" say "keep your fingers crossed." error_to_screen select distro in "CentOS 3" "Scientific Linux 3" "Red Hat Enterprise Linux 3" \ "CentOS 4" "Scientific Linux 4" "Red Hat Enterprise Linux 4" "help" quit; do case $distro in ("CentOS 3") DISTRO=centos OSVERSION=4 break ;; ("CentOS 4") DISTRO=centos OSVERSION=4 break ;; ("Scientific Linux 3") DISTRO=sl OSVERSION=3 break ;; ("Scientific Linux 4") DISTRO=sl OSVERSION=4 break ;; ("Red Hat Enterprise Linux 3") DISTRO=rhel OSVERSION=3 break ;; ("Red Hat Enterprise Linux 4") DISTRO=rhel OSVERSION=4 break ;; (quit) echo "OK, quitting." bailout 1 ;; (*) echo "Choose the distribution that you believe matches your system." ;; esac done error_to_log else say "OK" log $detect fi } function determine_action() { if [ ${OSVERSION} -eq 3 ]; then USE_APT=1 pkg_mgr=$APT_GET else pkg_mgr=$YUM fi } function install_apt() { # Install APT say_n \ "Checking apt ........................................................ " if APT=$($RPM -q apt); then say OK log "apt is already installed." else pocbase=$MIRROR/rhel${OSVERSION} apt_rpm=$pocbase/RPMS.externals/apt-${apt_version}.rpm say NO say_n \ "Installing apt ...................................................... " if really rpmi $apt_rpm; then say "OK" else die "Failed to install package $apt_rpm" fi fi } # This function adds an apt source list in a generic way. # arguments: list name, vendor, base url, branch, repositories. # A grep is performed to see if the base url is already present. function add_apt_list() { listname=$1 vendor=$2 baseurl=$3 branch=$4 shift 4 if ! grep -q -F "$baseurl $branch" /etc/apt/sources.list.d/$listname.list ; then if (( $DRYRUN )); then log "Add rpm $vendor $baseurl $branch $* to /etc/apt/sources.list.d/$listname.list" else cat >| /etc/apt/sources.list.d/$listname.list <&2 || \ die "Couldn't import $k into rpm" really $GPG --import $INSTALLDIR/$k >&2 || \ die "Couldn't import $k into gpg" done say OK } function set_vendorlist() { if ! grep -q 'VL-e' /etc/apt/vendors.list; then log "Importing vendors.list for apt ... " if (( $DRYRUN )); then log "cat (HEREDOC) >> /etc/apt/vendors.list" else cat >> /etc/apt/vendors.list <"; } simple-key "VL-e" { Fingerprint "7CB8BF1DDD50687A2212EFF017685BD0E38D518D"; Name "VL-e PoC Release Managers (P4, Scaling & Validation) "; } EOF fi fi } function apt_get_update() { say_n \ "Doing apt-get update ................................................ " really apt-get update >&2 if [ $? -eq 0 ]; then say OK else say "FAILED" say "I detected a problem with apt-get update, but it's" say "Too hard to say what may have caused the problem." say "Sometimes errors like these are harmless, but you" say "should really inspect $LOGFILE to make sure." ERROR_STATE=error fi } function apt_get_fix() { say_n \ "Doing apt-get -f install ............................................ " really apt-get -y -f install >&2 if [ $? -eq 0 ]; then say OK else say "FAILED" say "I detected a problem with apt-get -f install, but it's" say "Too hard to say what may have caused the problem." say "Sometimes errors like these are harmless, but you" say "should really inspect $LOGFILE to make sure." ERROR_STATE=error fi } # add all necessary yum repositories function add_yum_repos() { say_n \ "Adding repositories to yum .......................................... " # grep for repositories if ! grep -qi jpackage /etc/yum.conf /etc/yum.repos.d/*.repo 2>/dev/null then log "writing /etc/yum.repos.d/jpackage.repo" cat > /etc/yum.repos.d/jpackage.repo < /etc/yum.repos.d/glite.repo <<'EOF' [glite-UI] name=gLite 3.1 User Interface baseurl=http://linuxsoft.cern.ch/EGEE/gLite/R3.1/glite-UI/sl4/i386/ gpgcheck=0 enabled=1 EOF fi if [ ! -f /etc/yum.repos.d/ca.repo ]; then log "writing /etc/yum.repos.d/ca.repo" cat > /etc/yum.repos.d/ca.repo < /etc/yum.repos.d/vle.repo < /dev/null) && HAVE_JAVA5_RPM=1 if (( $HAVE_JAVA5_RPM )); then say OK JAVA_OK=1 else say NO JAVA_OK=0 fi } function install_java() { INSTALLJAVA=0 DONEWITHJAVA=0 LATEST_JDK5=11 if (( ! $HAVE_JAVA5_RPM )); then JAVA5_RPM=$MIRROR/rhel${OSVERSION}/externals/RPMS/jdk-1_5_0_${LATEST_JDK5}-linux-i586.rpm say_n \ "Installing Java SDK 1.5.0 RPM ....................................... " really $RPM -i ${JAVA5_RPM} >&2 || \ die "Could not find ${JAVA5_RPM}." say OK fi } # This function will install the site-info.def file in # the given location. # # arguments: src target function cp_site_info_def() { say_n \ "Installing site-info.def ............................................ " if [ ! -d $(dirname $2) ]; then really mkdir -p $(dirname $2) >&2 || \ die "Could not create directory $(dirname $2)." fi # check if user modified her site-info.def if grep -q '^###DO NOT MODIFY BY HAND' $2 2>/dev/null || ! test -f $2; then really $CP $1 $2 >&2 || \ die "Couldn't copy $1 to $2." else say "NO" say -e "I detected manual overrides in $2;\n check $1 for changes" log "differences:" diff -u $2 $1 >&2 return 1 fi say OK } # This funcion will fetch the default site-info def file function download_site_info_def() { say_n \ "Getting site-info.def ............................................... " really $WGET $MIRROR/extra/site-info.def -O $INSTALLDIR/site-info.def >&2 || \ die "Couldn't get $MIRROR/extra/site-info.def" say OK cp_site_info_def $INSTALLDIR/site-info.def $SITE_INFO_DEF } function set_java_home() { # retrieve JDK install directory from RPM package JAVA_HOME=`rpm -q --qf '%{DIRNAMES}\n' jdk | sort | tail -1` || die "jdk rpm is not installed." # remove trailing slash export JAVA_HOME=${JAVA_HOME%/} export PATH=${JAVA_HOME}/bin:${PATH} log "Using Java SDK from ${JAVA_HOME}" # TODO: move this to the postinstall of the vl-e rpm? Define # these as %config files of vl-e? if (( $DRY_RUN )); then log "Create /etc/profile.d/java.{c,}sh" else cat < /etc/profile.d/java.sh export JAVA_HOME=${JAVA_HOME} # tomcat wants this export JAVA_LOCATION=\${JAVA_HOME} export PATH=\${JAVA_HOME}/bin:\${PATH} EOF cat < /etc/profile.d/java.csh setenv JAVA_HOME ${JAVA_HOME} # tomcat wants this setenv JAVA_LOCATION \${JAVA_HOME} setenv PATH \${JAVA_HOME}/bin:\${PATH} EOF fi } # This function calls yaim's install_node. All decision points have already # passed, see determine_action. function yaim_install_node() { say_n \ "Installing EGEE/gLite node (this will take a while) ................. " # translate nodetype to metapackage $pkg_mgr -y install lcg-CA >&2 && \ $pkg_mgr -y install glite-UI >&2 if [ $? -ne 0 ]; then say FAILURE die "Could not install lcg-CA and glite-UI." fi say OK } function yaim_configure_node() { say_n \ "Configuring EGEE/gLite node (hold on) ............................... " really $YAIM/bin/yaim -c -s "$SITE_INFO_DEF" -n UI >&2 || \ die "Could not configure EGEE/gLite middleware" say OK } function cleanup_after_yaim() { say_n \ "Cleaning up after YAIM .............................................. " log " - fixing ldconfig warnings" bad_libs="\ /opt/lcg/lib/liblcg-info-api-ldap.so \ /opt/glite/externals/lib/libswigpy.so \ /opt/glite/externals/lib/libswigpl.so \ /opt/glite/externals/lib/libswigtcl8.so " for i in $bad_libs do if [ ! -r $i.0.0.0 ] then log "$i.0.0.0 not found; skipping" else if [ ! -L $i ] then log "$i is not a symlink; correcting" really $RM $i (cd ${i%/*} ; really $RM $i ; really ln -fs ${i##*/}.0.0.0 $i) fi if [ ! -L $i.0 ] then log "$i.0 is not a symlink; correcting" really $RM $i.0 (cd ${i%/*} ; really $RM $i.0 ; really ln -fs ${i##*/}.0.0.0 $i.0) fi fi done log " - installing correct /etc/java/java/conf file" (( $DRYRUN )) || cat < /etc/java/java.conf # System-wide Java configuration file # # JPackage Project # Location of jar files on the system JAVA_LIBDIR=/usr/share/java # Location of arch-specific jar files on the system JNI_LIBDIR=/usr/lib/java # Root of all JVM installations JVM_ROOT=/usr/lib/jvm # You can define a system-wide JVM root here if you're not using the default one JAVA_HOME=${JAVA_HOME} # Options to pass to the java interpreter JAVACMD_OPTS= EOF say OK } ###################################################################### # Section: main ###################################################################### # the order of calling these functions is very delicate; # some of them need variables or programs that are provided by # others. parse_options "$@" sanity_checks check_update $0 "$@" prepare_installdir log_output log "YAIM installer started on `date`" log "Invocation was: $0 $*" check_distro detect_java determine_action (( $JAVA_OK )) || install_java download_site_info_def set_java_home if [ $USE_APT -eq 1 ] ; then install_apt configure_apt_sources set_vendorlist install_gpg # requires apt gpg_import_keys # requires install files, gpg apt_get_update apt_get_fix install_java apt_update_upgrade else add_yum_repos fi yaim_install_node # TODO: install the voms server host cert. yaim_configure_node cleanup_after_yaim # inspect error state. if [ "$ERROR_STATE" == "OK" ]; then # we're fine say say "Installation completed." exit 0 else say say "We're DONE, but errors occurred along the way." say "Please inspect the log file." exit 1 fi