#!/bin/bash
##############################################################################
# Copyright (c) Members of the EGEE Collaboration. 2004. 
# See http://www.eu-egee.org/partners/ for details on the copyright 
# holders.  
#
# Licensed under the Apache License, Version 2.0 (the "License"); 
# you may not use this file except in compliance with the License. 
# You may obtain a copy of the License at 
#
#    http://www.apache.org/licenses/LICENSE-2.0 
#
# Unless required by applicable law or agreed to in writing, software 
# distributed under the License is distributed on an "AS IS" BASIS, 
# WITHOUT WARRANTIES OR CONDITIONS 
# OF ANY KIND, either express or implied. 
# See the License for the specific language governing permissions and 
# limitations under the License.
##############################################################################
#
# NAME :        yaim
#
# DESCRIPTION : This is YAIM main exacutable script. To learn more about YAIM, visit:
#               https://twiki.cern.ch/twiki/bin/view/EGEE/YAIM
#
# MAINTAINERS : yaim-contact@cern.ch
#               cristina.aiftimiei@pd.infn.it
#
# NOTES : 
#
# YAIM MODULE:  glite-yaim-core
#                 
##############################################################################


###################################
# Function to print usage help    #
###################################

function PrintUsage() {
cat << EOT
Usage: $0 <action>  <parameters>
Actions: 
       -c | --configure   : Configure already installed services.
                            Compulsory parameters: -s, -n

       -r | --runfunction : Execute a configuration function.
                            Compulsory parameters: -s, -f
                            Optional parameters  : -n
 
       -v | --verify      : Goes through on all the functions and checks that
                            the necessary variables required for a given 
                            configuration target are all defined in site-info.def.                            
                            Compulsory parameters: -s -n

       -d | --debug       : Define a loglevel, which overwrites the value of
                            YAIM_LOGGING_LEVEL defined in site-info.def. 
                            Values: 1-7

       -e | --explain     : Doesn't perform configuration but explains what the
                            functions are doing by printing out the comments  
                            found inside them.
                            Compulsory parameters: -s -n

       -a | --available   : Prints out the available configuration targets.
                            Compulsory parameter:  -s

       -p | --package     : Creates an rpm package from the configuration directory structure,
                            that can be installed on other nodes. It installs site-info.def and
                            if they exist: vo.d, group.d, nodes and local functions under:                             
                            /opt/glite/yaim/examples/siteinfo/mysiteinfo-\${SITE_INFO_VERSION}
                            Compulsory parameter:  -s

       -h | --help        : Prints out this help.

Specify only one action at a time !

Parameters:
       -s | --siteinfo:   : Location of the site-info.def file
       -n | --nodetype    : Name of the node type(s) to configure
       -f | --function    : Name of the functions(s) to execute

Examples:
       Check what can you configure:
         $0 -a -s /etc/yaim/site-info.def 

       Configuration:
         $0 -c -s /etc/yaim/site-info.def -n emi_dpm_mysql

       Running a function:
         $0 -r -d 6 -s /etc/yaim/site-info.def -n emi_dpm_mysql -f config_mkgridmap

       Verify your site-info.def:
         $0 -v -s /etc/yaim/site-info.def -n emi_dpm_mysql 

       Create an rpm package from site-info.def:
         $0 -p -s /etc/yaim/site-info.def 

EOT
}

##########################################
# Function to print Missing parameters   #
##########################################

function MissingPar () {
   PrintUsage ; 
   yestr ${YEX_USAGE}
   yaimlog ERROR "${YERRORSTR}" ; 
   exit ${YEX_USAGE} ;                            
}


#########################################
# These are standard system exit codes, #
#  see /usr/include/sysexits.h          #
#########################################

YEX_OK=0           # successful termination
YEX_NOFUNC=1       # One of the functions returned with error without specifying its nature !
YEX_USAGE=64       # command line usage error
YEX_DATAERR=65     # data format error
YEX_NOINPUT=66     # cannot open input
YEX_NOUSER=67      # addressee unknown
YEX_NOHOST=68      # host name unknown
YEX_UNAVAILABLE=69 # service unavailable
YEX_SOFTWARE=70    # internal software error
YEX_OSERR=71       # system error (e.g., can't fork)
YEX_OSFILE=72      # critical OS file missing
YEX_CANTCREAT=73   # can't create (user) output file
YEX_IOERR=74       # input/output error
YEX_TEMPFAIL=75    # temp failure; user is invited to retry
YEX_PROTOCOL=76    # remote error in protocol
YEX_NOPERM=77      # permission denied
YEX_CONFIG=78      # configuration error

# These are YAIM own exit codes

YEX_NOTARGET=90    # The function list definition file for the configuration target hasn't been found
YEX_MISSINGVAR=91  # Missing variables in the configuration files
YEX_NOSUCHFILE=92  # No such file or directory
YEX_CONFFILE=93    # Configuration file error
YEX_NOUSER=94      # User doesn't exist
YEX_USERERR=95     # Error when creating a user
YEX_GROUPERR=96    # Error when creating a group
YEX_CONFTARGET=97  # Wrong configuration target


##############################################
# Here are the error description definitions #
##############################################

YERRSTR_0="YAIM terminated succesfully."
YERRSTR_64="Command line usage error !"
YERRSTR_65="Data format error !"
YERRSTR_66="Cannot open input !"
YERRSTR_67="Address unknown !"
YERRSTR_68="Host name unknown !"
YERRSTR_69="Service unavailable !"
YERRSTR_70="Internal software error !"
YERRSTR_71="System error !"
YERRSTR_72="Critical OS file mising !"
YERRSTR_73="Can't create (user) output file !"
YERRSTR_74="Input/output error !"
YERRSTR_75="Temp failure; user is invited to retry !"
YERRSTR_76="Remote error in protocol !"
YERRSTR_77="Permission denied !"
YERRSTR_78="Configuration error !"

YERRSTR_1="One of the functions returned with error without specifying its nature !"
YERRSTR_90="The function list definition file for the configuration target hasn't been found. !"
YERRSTR_91="There are missing variables in the configuration files !"
YERRSTR_92="No such file or directory !"
YERRSTR_93="Configuration file error" 
YERRSTR_94="User doesn't exist !" 
YERRSTR_95="Error when creating a user !" 
YERRSTR_96="Error when creating a group !" 
YERRSTR_97="Wrong configuration target !" 

function yestr() {
 YERRORSTR=`eval echo \\${YERRSTR_$1}`
}

###################################################################
# Set standard locale to avoid error messages in native languages #
###################################################################

export LANG=C

###################################################################
# Set umask according to implicit expectations of many functions  #
# (bug #73080)                                                    #
###################################################################

umask 022

##############################
# Current working directory  #
##############################

export mythisdir=`dirname $0`
if [ ! "x"`echo ${mythisdir} | head -c 1` = "x/" ]; then 
  mythisdir=`pwd`"/${mythisdir}"
fi

################################################
# Sourcing utility yaimlog and                 #
# setting the proper permission of the logfile #
################################################

. $mythisdir/../functions/utils/yaimlog
export YAIM_LOG="$mythisdir/../log/yaimlog"
touch  ${YAIM_LOG}
chmod  600 ${YAIM_LOG}

# We write everything into the logfile and run a tail in the background.
# This is to enable the detaching of this shell even if there has been 
# improperly daemonized program started during the configuration.

tail -n 0 -f ${YAIM_LOG} & 
tail_pid=$! 
trap 'sleep 1; kill $tail_pid' EXIT 


####################
# Argument parsing #
####################

# Saving command line before start shifting

originalcmd="$*"

# Start argument parsing

TEMP=`getopt -o hcrvepad:n:m:f:s: --long help,configure,runfunction,verify,explain,package,available,debug:,nodetype:,metapackage:,function:,siteinfo: -n YAIM -- "$@"`
if [ $? != 0 ] ; then 
  PrintUsage; exit -1; 
  yestr ${YEX_USAGE}
  yaimlog ERROR "${YERRORSTR}" 
  exit ${YEX_USAGE} 
fi
eval set -- "$TEMP"
while true ; do
	case "$1" in
		-c|--configure) myaction="configure" ; shift ;;
		-r|--runfunction) myaction="runfunction" ; shift ;;
		-v|--verify)  myaction="verify" ; shift ;;
                -n|--nodetype) mynodetype="$mynodetype$2 " ; shift 2;;
                -m|--metapackage) mymetapackage="$mymetapackage$2 " ; shift 2;;
                -f|--function) myfunction="$myfunction$2 " ; shift 2;;
                -s|--siteinfo) mysiteinfo="$2" ; shift 2;;
                -e|--explain) myaction="explain"; shift ;;
                -p|--package) myaction="package"; shift ;;
                -a|--available) myaction="available"; shift ;;
                -d|--debug) mydebuglevel="$2" ; shift 2 ;;
                -h|--help) PrintUsage; exit 0 ;;
		--) shift ; break ;;
		*) echo "Internal error!" ; exit 1 ;;
	esac
done

# Deleting trailing and leading white spaces from nodetype list

mynodetype=`echo $mynodetype | sed 's/^[ \t]*//' | sed 's/[ \t]*$//'`

# Source config_file and install_node
source $mythisdir/../libexec/configure_node
#source $mythisdir/../libexec/install_node
source $mythisdir/../libexec/run_function


# Build up the command

case $myaction in

# These line can be removed when we stop supporting gLite 3.0 
    install)     if [ ! -z "$mysiteinfo" ] && [ ! -z "$mymetapackage" ]; then 
                    mycmd="install_node $mysiteinfo $mymetapackage";                    
                 else 
                    MissingPar; 
                 fi ;;

    configure)   if [ ! -z "$mysiteinfo" ] && [ ! -z "$mynodetype" ]; then 
                    export NODE_TYPE_LIST="${mynodetype}"
                    mycmd="configure_node $mynodetype";
                 else 
                    MissingPar ; 
                 fi ;;

    explain)   if [ ! -z "$mynodetype" ] && [ ! -z "$mysiteinfo" ]; then 
                    mycmd="configure_node explain $mynodetype";
                 else 
                    MissingPar ; 
                 fi ;;

    package)   if [ -z "$mysiteinfo" ]; then 
                    MissingPar ; 
                 fi ;;

    runfunction) if [ ! -z "$mysiteinfo" ] && [ ! -z "$myfunction" ]; then 
                    export NODE_TYPE_LIST="${mynodetype}"
                    mycmd="run_function $myfunction";               
                 else 
                    MissingPar ; 
                 fi ;;

    verify)      if [ ! -z "$mysiteinfo" ] && [ ! -z "$mynodetype" ]; then
                    export NODE_TYPE_LIST="${mynodetype}"
                    mycmd="configure_node check $mynodetype";
                 else 
                    MissingPar ; 
                 fi ;;

    available)    if [ -z "$mysiteinfo" ]; then
                    MissingPar ;
                  fi ;;

    *)            PrintUsage; 
                  yaimlog ERROR "Specify an action !" ; 
                  yestr ${YEX_USAGE}
                  yaimlog ERROR "${YERRORSTR}" ;
                  exit ${YEX_USAGE} ;;
esac

#######################
# YAIM logging level  #
#######################

# Overwriting the YAIM_LOGGING_LEVEL if the -d flag is defined.

i=0;
for myloglevel in NONE ABORT ERROR WARNING INFO DEBUG ; do
 i=$(($i+1))
 if [ ! -z "${mydebuglevel}" ] && [ ! "${mydebuglevel}" -lt "$i" ]; then
        export YAIM_LOGGING_LEVEL=${myloglevel}
 fi
 if [ "x${mydebuglevel}" = "x7" ]; then
       set -x;
 fi
done

# To save this value, since it has to be reset after we source the site-info.def file.

if [ ! -z "${mydebuglevel}" ]; then
       myloglevel=${YAIM_LOGGING_LEVEL}
fi


##########################
# Checking site-info.def #
##########################

# Checking the permissions of the siteinfo directory are not world readable
# Sourcing site-info.def and exiting if it is syntactically invalid

  if [ -f $mysiteinfo ]; then
    yaimlog DEBUG "Checking siteinfo dir is not world readable"
    mysiteinfodir=`dirname $mysiteinfo` 
    permissions=`ls -la $mysiteinfodir | head -n 2 | tail -n 1 | cut -c8-10` 
    if [ "$permissions" != "---" ]; then
      yaimlog WARNING ""
      yaimlog WARNING "*****************************************************************************" 
      yaimlog WARNING "Your siteinfo directory is world readable. This is generally a bad idea      " 
      yaimlog WARNING "as configuration files may contain passwords and other sensitive information." 
      yaimlog WARNING "*****************************************************************************" 
      yaimlog WARNING ""
    fi
    yaimlog DEBUG "Checking site-info.def is syntactically correct"
    checksyn=`mktemp /tmp/checksyn.XXXXXX`
    set +x
    . $mysiteinfo 2> $checksyn 
    if [ "x${mydebuglevel}" = "x7" ]; then
       set -x;
    fi
    if [ -s $checksyn ]; then
      yaimlog ERROR "The site-info specified: $mysiteinfo is syntactically incorrect. Please, check the syntax." 
      yestr ${YEX_CONFFILE}
      yaimlog ERROR "${YERRORSTR}"
      exit ${YEX_CONFFILE}
    fi
    rm -rf $checksyn
  else
    yaimlog ERROR "Your site-info.def $mysiteinfo doesn't exist. Please, make sure you specify the right configuration file." 
    yestr ${YEX_CONFFILE}
    yaimlog ERROR "${YERRORSTR}"
    exit ${YEX_CONFFILE}
  fi

###################
# Hostname checks #
###################

# Checks if 'hostname -f' returns a fully qualified hostname.

mynodename=`hostname -f | tr '[:upper:]' '[:lower:]'`
yaimlog INFO "Configuring HOST: ${mynodename}";

if ( ! hostname -f | grep '\.' > /dev/null ); then
 yaimlog ERROR "The hostname -f command does not return with a fully qualified hostname,";
 yaimlog ERROR "however this is necessary for YAIM to run properly.";
 yaimlog ERROR "Please check your /etc/hosts file ! Exiting.";
 yestr ${YEX_NOHOST}
 yaimlog ERROR "${YERRORSTR}"
 exit ${YEX_NOHOST}
fi

#######################
# .pre, site-info.def #
#######################

mydefaults="${mythisdir}/../defaults"

# Sourcing site-info.pre

if [ -f "${mydefaults}/site-info.pre" ] ; then
  source ${mydefaults}/site-info.pre
  yaimlog DEBUG "Sourcing ${mydefaults}/site-info.pre"
fi

# Sourcing services .pre

for service in `echo $NODE_TYPE_LIST | tr '[:upper:]' '[:lower:]'`; do
  myservicefile=`echo ${service} | sed -e 's/^glite-//'`
  myservicefile=`echo ${service} | sed -e 's/^emi-//'`
  if [ -f "${mydefaults}/${myservicefile}.pre" ] ; then
    source ${mydefaults}/${myservicefile}.pre
    yaimlog DEBUG "Sourcing ${mydefaults}/${myservicefile}.pre"
  else
    if [ -f "${mydefaults}/emi-${myservicefile}.pre" ] ; then
      source ${mydefaults}/emi-${myservicefile}.pre
      yaimlog DEBUG "Sourcing ${mydefaults}/emi-${myservicefile}.pre"
    else
      if [ -f "${mydefaults}/glite-${myservicefile}.pre" ] ; then
         source ${mydefaults}/glite-${myservicefile}.pre
         yaimlog DEBUG "Sourcing ${mydefaults}/glite-${myservicefile}.pre"
      fi
    fi
   fi
done

# Fixes due to compatibility with yaim 3.0.x

export SITE_INFO="${mysiteinfo}"

# source site-info.def

yaimlog INFO "Using site configuration file: ${mysiteinfo}"
yaimlog DEBUG "Sourcing site-info.def file: ${mysiteinfo}"
. ${mysiteinfo}

# Reset the logging level if the -d option was specified, since site-info.def just owerwrote
# the previous setting.

if [ ! -z "${mydebuglevel}" ]; then
   export YAIM_LOGGING_LEVEL="${myloglevel}"
fi

##################
# service, node  #
##################

export config_dir=`dirname ${mysiteinfo}`

# Get service specific configuration (optional)
for service in `echo $NODE_TYPE_LIST | tr '[:upper:]' '[:lower:]'` ; do
    myservicefile=`echo ${service} | sed -e 's/^glite-//'`
    myservicefile=`echo ${service} | sed -e 's/^emi-//'`
    if [ -f "${config_dir}/services/$myservicefile" ] ; then
        source "${config_dir}/services/$myservicefile"
        yaimlog INFO "Sourcing service specific configuration file: ${config_dir}/services/$myservicefile"
    else
        if [ -f "${config_dir}/services/emi-${myservicefile}" ] ; then
           source "${config_dir}/services/emi-${myservicefile}"
           yaimlog INFO "Sourcing service specific configuration file: ${config_dir}/services/emi-$myservicefile"
        else 
           if [ -f "${config_dir}/services/glite-${myservicefile}" ] ; then
              source "${config_dir}/services/glite-${myservicefile}"
              yaimlog INFO "Sourcing service specific configuration file: ${config_dir}/services/glite-$myservicefile"
           fi
        fi
    fi
done

# Get node specific configuration (optional)
if [ -f "${config_dir}/nodes/${mynodename}" ] ; then
   source "${config_dir}/nodes/${mynodename}"
   yaimlog INFO "Sourcing node specific configuration file: ${config_dir}/nodes/${mynodename}"
fi

#########
# .post #
#########

# Sourcing site-info.post

if [ -f "${mydefaults}/site-info.post" ] ; then
  source ${mydefaults}/site-info.post
  yaimlog DEBUG "Sourcing ${mydefaults}/site-info.post"
fi

# Sourcing services .post

for service in `echo $NODE_TYPE_LIST | tr '[:upper:]' '[:lower:]'`; do
  myservicefile=`echo ${service} | sed -e 's/^glite-//'`
  myservicefile=`echo ${service} | sed -e 's/^emi-//'`
  if [ -f "${mydefaults}/${myservicefile}.post" ] ; then
    source ${mydefaults}/${myservicefile}.post
    yaimlog DEBUG "Sourcing ${mydefaults}/${myservicefile}.post"
  else
    if [ -f "${mydefaults}/emi-${myservicefile}.post" ] ; then
       source ${mydefaults}/emi-${myservicefile}.post
       yaimlog DEBUG "Sourcing ${mydefaults}/emi-${myservicefile}.post"
    else
       if [ -f "${mydefaults}/glite-${myservicefile}.post" ] ; then
          source ${mydefaults}/glite-${myservicefile}.post
          yaimlog DEBUG "Sourcing ${mydefaults}/glite-${myservicefile}.post"
       fi
    fi
  fi
done

# Sourcing mapping

if [ -f "${mydefaults}/mapping" ] ; then
  source ${mydefaults}/mapping
  yaimlog DEBUG "Sourcing ${mydefaults}/mapping"
fi

################
# INSTALL_ROOT #
################

# Checking that install root is set and is a directory

if [ -z ${INSTALL_ROOT} ] ; then
        yaimlog ERROR "INSTALL_ROOT variable is not set. Exiting."
        yestr ${YEX_MISSINGVAR}
        yaimlog ERROR "${YERRORSTR}"
        exit ${YEX_MISSINGVAR}
fi

if [ ! -d "${INSTALL_ROOT}" ]; then
        yaimlog ERROR "Please make the distribution available under ${INSTALL_ROOT}"
        yaimlog ERROR "or update your site-info.def file to reflect the correct path"
        yestr ${YEX_NOSUCHFILE}
        yaimlog ERROR "${YERRORSTR}"
        yaimlog ABORT "Exiting."
        exit ${YEX_NOSUCHFILE}
fi

################
# startup info #
################

siteinfodate=`ls -l $mysiteinfo | awk '{print $6" "$7" "$8" "$9}'`
yaimversions=`mktemp /tmp/yaim.XXXXXX`

for i in ${YAIM_ROOT}/glite/yaim/etc/versions/*; do
  cat $i >> ${yaimversions}
done

yaimlog INFO << EOT

###################################################################

.             /'.-. ')
.     yA,-"-,( \,m,:/ )   .oo.     oo    o      ooo  o.     .oo
.    /      .-Y a  a Y-.     8. .8'    8'8.     8    8b   d'8
.   /         \  ~ ~ /         8'    .8oo88.     8    8  8'  8
. (_/         '===='          8    .8'     8.   8    8  Y   8
.   Y,-''-,Yy,-.,/           o8o  o8o    o88o  o8o  o8o    o8o
.    I_))_) I_))_)


 current working directory: `pwd`
 site-info.def date: $siteinfodate
 yaim command: $originalcmd
 log file: ${YAIM_LOG}
 `date` : $0

 Installed YAIM versions:
 `cat ${yaimversions}`

####################################################################
EOT

rm -rf ${yaimversions}


#####################
# GRID_ENV_LOCATION #
#####################

# Default value for the environment file, GRID_ENV_LOCATION is set in site-info.post

if [ -z ${GRID_ENV_LOCATION} ] ; then
        yaimlog ERROR "GRID_ENV_LOCATION variable is not set. Exiting."
        yestr ${YEX_MISSINGVAR}
        yaimlog ERROR "${YERRORSTR}"
        exit ${YEX_MISSINGVAR}
fi

mkdir -p ${GRID_ENV_LOCATION}
yaimlog INFO "The default location of the grid-env.(c)sh files will be: ${GRID_ENV_LOCATION}"

#################
# FUNCTIONS_DIR #
#################

# Check that function dir is well defined
if [ -z "${FUNCTIONS_DIR}" ]; then
 yaimlog WARNING "FUNCTIONS_DIR not set using default: ${mythisdir}/../functions/"
 export FUNCTIONS_DIR="${mythisdir}/../functions/"
fi

if [ -d "${FUNCTIONS_DIR}" ]; then
    if [ ! -d "${FUNCTIONS_DIR}/local" ]; then
        yaimlog ERROR "Can't find the functions in FUNCTIONS_DIR, (no local directory existing) !"
        yestr ${YEX_NOSUCHFILE}
        yaimlog ERROR "${YERRORSTR}"
        yaimlog ABORT "Exiting."
        exit ${YEX_NOSUCHFILE}
    fi
else 
    yaimlog ERROR "Can't find the functions in FUNCTIONS_DIR !"
    yestr ${YEX_NOSUCHFILE}
    yaimlog ERROR "${YERRORSTR}"
    yaimlog ABORT "Exiting."
    exit ${YEX_NOSUCHFILE}
fi

#############
# Utilities #
#############

# Dont source leftovers from possible editing 
# filter on ~ , bckp, #

yaimlog INFO "Sourcing the utilities in ${FUNCTIONS_DIR}/utils" 
if [ -d ${FUNCTIONS_DIR}/utils ]; then
    for i in ${FUNCTIONS_DIR}/utils/*; do
        if [ -r "$i" -a -f "$i" ]; then
          j=${i/\~/}; j=${j/\#/}; j=${j/bckp/}
          if [ "x$j" = "x$i" ]; then
           . $i
          fi
        fi
    done
fi

######################
# Platform detection #
######################

detect_platform

if [ "x${OS_TYPE}" = "xdebian" ]; then

  yaimlog DEBUG "Checking whether gawk is default in Debian"
  update-alternatives --display awk | grep "link currently points to" | grep gawk > /dev/null
  if [ $? -ne 0 ]; then
    dpkg -s gawk | grep Status | grep "not installed" > /dev/null
    if [ $? -ne 0 ]; then
      yaimlog ERROR "YAIM needs gawk installed in your Debian machine. Please install it!"
      yestr ${YEX_NOSUCHFILE}
      yaimlog ERROR "${YERRORSTR}"
      exit ${YEX_NOSUCHFILE}
    else
       yaimlog ERROR "YAIM needs gawk to be the default awk editor. Please set it!"
       yestr ${YEX_CONFIG}
       yaimlog ERROR "${YERRORSTR}"
       exit ${YEX_CONFIG}
    fi
  fi

fi

# Do platform dependent stuff


if [ -n "${GLOBUS_TCP_PORT_RANGE}" ] ; then
  if [ -n "${GLOBUS_TCP_PORT_RANGE//[0-9, ]/}" ] ; then
    yaimlog ERROR "GLOBUS_TCP_PORT_RANGE contains bad characters!"
    exit ${YEX_CONFIG}
  fi

  if [ "x${GLOBUS_TCP_PORT_RANGE/,/}"  = "x${GLOBUS_TCP_PORT_RANGE}" ] ||
     [ "x${GLOBUS_TCP_PORT_RANGE/ /}" != "x${GLOBUS_TCP_PORT_RANGE}" ] ; then
    yaimlog WARNING "GLOBUS_TCP_PORT_RANGE must have a comma and no spaces!"
    myrange=`echo ${GLOBUS_TCP_PORT_RANGE} | sed 's/,/ /g'`
    GLOBUS_TCP_PORT_RANGE=`echo ${myrange} | awk '{print $1","$2}'`
  fi

  export GLOBUS_TCP_PORT_RANGE
fi


########################
# Compulsory variables #
########################

requires INSTALL_ROOT 


####################
# Package creation #
####################

# If we creating an rpm package from the siteinfo (action=package) we can start here:

if [ "x${myaction}" = "xpackage" ]; then
  . ${FUNCTIONS_DIR}/create_siteinforpm
  create_siteinforpm_check
  create_siteinforpm
  if [ $? -ne 0 ]; then
   yaimlog ERROR "There has some error been detected during the rpm package creation. For detailed log see YAIM's log file: ${YAIM_LOG}"
   yestr ${YEX_SOFTWARE}
   yaimlog ERROR "${YERRORSTR}"
   yaimlog ABORT "Exiting."
   exit ${YEX_SOFTWARE}
  fi
 yestr ${YEX_OK}
 yaimlog INFO "${YERRORSTR}"
 exit ${YEX_OK}
fi

###################################
# Available configuration targets #
###################################

# If we just have to print the availabe configuration targets:

if [ "x${myaction}" = "xavailable" ]; then
    . ${mythisdir}/../defaults/node-info.def
    if [ `ls -1 ${mythisdir}/../node-info.d/ | wc -l` -ne 0 ]; then               # check whether node-info.d files actually exist
      for i in ${mythisdir}/../node-info.d/* ; do
       . $i
      done 
    fi
    mytargets=`set | grep _FUNCTIONS | cut -d "=" -f 1 | sed 's/_FUNCTIONS//g' | awk 'ORS=" " {print $1}'`
    yaimlog INFO "The following configuration targets are available:"
    for target in $mytargets; do
      if [ $target != "CE" ]; then
        yaimlog INFO "${target}"
      else
        yaimlog INFO "lcg-CE"
      fi
    done    
    sleep 1; 
    yestr ${YEX_OK}
    yaimlog INFO "${YERRORSTR}"
    exit ${YEX_OK}
fi

############
# glite CE #
############

# Error message if glite CE is configured

if ( echo ${mynodetype} | egrep -q 'glite-CE' ) ; then 

(cat << EOF
  gLite CE is no longer configured by this version of YAIM.

  Please, note that currently the glite-CE should be regarded
  as a proof of principle component that is not in a state to be
  deployed in production in a reasonable manner. In case you are
  still interested in installing a gLite CE, please use yaim core <= 4.0.0-13

EOF
) | yaimlog ERROR
  sleep 1 
  yestr ${YEX_NOTARGET}
  yaimlog INFO "${YERRORSTR}"
  exit ${YEX_NOTARGET}
fi


##################
# CE not allowed #
##################

# Error message if CE is specified

if ( echo ${mynodetype} | egrep -q '\<CE\>' ) && ( ! echo ${mynodetype} | egrep -q 'creamCE' ) && ( ! echo ${mynodetype} | egrep -q 'lcg-CE' ); then

echo $mynodetype

(cat << EOF
  CE is not a valid configuration target. Valid configuration targets for Computing Elements are lcg-CE or creamCE.
EOF
) | yaimlog ERROR
  sleep 1
  yestr ${YEX_NOTARGET}
  yaimlog INFO "${YERRORSTR}"
  exit ${YEX_NOTARGET}
fi


#####################
# Build groups.conf #
#####################

# This is only executed for those node types that need GROUPS_CONF. Otherwsie we don't force to define GROUPS_CONF or group.d/
# That's why we need an 'if'
if ( echo "${NODE_TYPE_LIST}" | egrep -qi '(LFC|FTS|RB|dpm|classic|lcg-CE|VOBOX|WMS|creamCE|TORQUE|glexec|SCAS|SGE|CONDOR|LSF|WN|CLUSTER|storm)' ); then

groups_conf_tmp=`mktemp /tmp/yaim.XXXXXX`

if [ -n "${LOCAL_GROUPS_CONF}" ]; then
  yaimlog DEBUG "LOCAL_GROUPS_CONF is defined. Adding local groups to the groups.conf temp file"
  cat "${LOCAL_GROUPS_CONF}"  >> ${groups_conf_tmp}
fi

if [ -n "${GROUPS_CONF}" ]; then
  yaimlog DEBUG "GROUPS_CONF is defined. Adding global groups to the groups.conf temp file"
  cat ${GROUPS_CONF}  >> ${groups_conf_tmp}
  yaimlog DEBUG "GROUPS_CONF points now to the groups.conf temp file"
  yaimlog DEBUG "GROUPS_CONF=${groups_conf_tmp}"
  export GROUPS_CONF=${groups_conf_tmp}
else
  if [ -d ${mysiteinfodir}/group.d ]; then
    yaimlog DEBUG "group.d/ directory exists. Check whether there's one groups.conf file per supported VO"
    for VO in ${VOS}; do
       if [ -f "${mysiteinfodir}/group.d/groups-${VO}.conf" ]; then
         yaimlog DEBUG "VO $VO has its groups.conf file: groups-${VO}.conf. Adding VO groups to the groups.comf temp file"
         cat ${mysiteinfodir}/group.d/groups-${VO}.conf >> ${groups_conf_tmp}
       else
         yaimlog ERROR "There must be one groups.conf file per supported VO in the group.d directory."
         yaimlog ERROR "${mysiteinfodir}/group.d/groups-${VO}.conf is missing."
         yaimlog ERROR "Please, create the groups-${VO}.conf file under your siteinfo directory and run the configuration again"
         rm -rf ${groups_conf_tmp}
         yestr ${YEX_NOSUCHFILE}
         yaimlog ERROR "${YERRORSTR}"
         exit ${YEX_NOSUCHFILE}
       fi
    done
    yaimlog DEBUG "All the supported VOs have their groups.conf file. GROUPS_CONF points now to the groups.conf temp file"
    yaimlog DEBUG "GROUPS_CONF=${groups_conf_tmp}"
    export GROUPS_CONF=${groups_conf_tmp}
  else
    yaimlog ERROR "There's neither GROUPS_CONF defined nor any groups.conf file per supported VO in group.d directory."
    yaimlog ERROR "Please, check the YAIM guide in www.yaim.info to learn how to define the groups.conf files."
    rm -rf ${groups_conf_tmp}
    yestr ${YEX_CONFIG}
    yaimlog ERROR "${YERRORSTR}"
    exit ${YEX_CONFIG}
  fi
fi

fi

###################
# Execute command #
###################

# Sorting and cleaning up the environment file and 
# substituiting the correct path to the .csh file if 
# we are configuring a node. 

if [ "x${myaction}" = "xconfigure" ] || [ "x${myaction}" = "xrunfunction" ]; then
  
  mytmpfile=`mktemp /tmp/yaimtmp.XXXXXX`
  mygridenvfile=`mktemp /tmp/yaimtmp.XXXXXX`

  # We always copy these files in case there are new changes
  cp ${mythisdir}/../etc/grid-env-funcs.sh ${GRID_ENV_LOCATION}/grid-env-funcs.sh
  cp ${mythisdir}/../etc/clean-grid-env-funcs.sh ${GRID_ENV_LOCATION}/clean-grid-env-funcs.sh

  yaim_python_lines=

  if [ "x${myaction}" = "xconfigure" ]; then
    # In case of a configuraton we recreate the environment file from scratch
    rm -f  ${GRID_ENV_LOCATION}/grid-env.sh
    rm -f  ${GRID_ENV_LOCATION}/grid-clean-env.sh
    # We need to source the funcs now as well so that variables can be defined dynamically
    echo ". ${GRID_ENV_LOCATION}/grid-env-funcs.sh" >> ${GRID_ENV_LOCATION}/grid-env.sh
    echo ". ${GRID_ENV_LOCATION}/grid-env-funcs.sh" >> ${GRID_ENV_LOCATION}/grid-clean-env.sh
  else
    # If we are running a function, we keep the environment 
    if [ -f ${GRID_ENV_LOCATION}/grid-env.sh ]; then # This is needed when -r is used for the first time before -c
      yaim_python_lines=`grep GLITE_PYTHON_VERSION ${GRID_ENV_LOCATION}/grid-env.sh`

      cat ${GRID_ENV_LOCATION}/grid-env.sh | grep -v "grid-env-funcs.sh" \
                                           | grep -v "clean-grid-env-funcs.sh" \
                                           | grep -v "^if\>" \
                                           | grep -v "^fi\>" > ${mytmpfile}
      rm -f  ${GRID_ENV_LOCATION}/grid-env.sh
      echo ". ${GRID_ENV_LOCATION}/grid-env-funcs.sh" >> ${GRID_ENV_LOCATION}/grid-env.sh
      cat ${mytmpfile} >> ${GRID_ENV_LOCATION}/grid-env.sh
      rm -f ${mytmpfile}

      cat ${GRID_ENV_LOCATION}/grid-clean-env.sh | grep -v "grid-env-funcs.sh" \
                                                 | grep -v "clean-grid-env-funcs.sh" \
                                                 | grep -v "^if\>" \
                                                 | grep -v "^fi\>" > ${mytmpfile}
      rm -f  ${GRID_ENV_LOCATION}/grid-clean-env.sh
      echo ". ${GRID_ENV_LOCATION}/grid-env-funcs.sh" >> ${GRID_ENV_LOCATION}/grid-clean-env.sh
      cat ${mytmpfile} >> ${GRID_ENV_LOCATION}/grid-clean-env.sh
      rm -f ${mytmpfile}
    fi
  fi


  # Executing the configuration command
  # Fix for bug #25667 and #27984 
  export yaimb_temp=`mktemp -t yaim.XXXXXXXX`
  export yaimv_temp=`mktemp -t yaimv.XXXXXXXX`

  (${mycmd}) 2>&1 >> ${YAIM_LOG}
  ret_code=$? 
  
  if [ -f ${GRID_ENV_LOCATION}/grid-env.sh ]; then # This is needed when -r is used for the first time before -c
    cat ${GRID_ENV_LOCATION}/grid-env.sh | grep -v "grid-env-funcs.sh" | sort -r | uniq > ${mytmpfile}
  fi
  echo "if [ \"X\${GLITE_ENV_SET+X}\" = \"X\" ]; then" > ${mygridenvfile}
  echo ". ${GRID_ENV_LOCATION}/grid-env-funcs.sh" >> ${mygridenvfile}
  if [ "x${OS_ARCH}" = "x64BIT" ]; then
    echo 'if [ "x${GLITE_UI_ARCH:-$1}" = "x32BIT" ];' \
      'then arch_dir=lib; else arch_dir=lib64; fi' >> ${mygridenvfile}
  fi

  read YAIM_PYTHON_BASE < ${yaimb_temp}
#  echo 'if [ -n "${GLITE_PYTHON_VERSION:-$2}" ];' \
#    'then python=${GLITE_PYTHON_VERSION:-$2}; python=${python/:*};' \
#    'else python='"$YAIM_PYTHON_BASE"'; fi' >> ${mygridenvfile}

#  read YAIM_PYTHON_VERSIONS < ${yaimv_temp}
#  for i in $YAIM_PYTHON_VERSIONS; do
#    j=${i//./\\.}
#    k=${i//./_}
##    echo 'if [[ ":${GLITE_PYTHON_VERSION:-$2}:" =~ :'"$i"': ]];' \
#    echo 'if (echo ":${GLITE_PYTHON_VERSION:-$2}:" | grep -q :'"$j"':);' \
#      'then python'"$k"'=python'"$i"';' \
#      'else python'"$k"'=python$python; fi' >> ${mygridenvfile}
#  done

  if [ -n "$YAIM_PYTHON_BASE" ]; then
    echo 'if [ -n "${GLITE_PYTHON_VERSION:-$2}" ];' \
      'then python=${GLITE_PYTHON_VERSION:-$2}; python=${python/:*};' \
      'else python='"$YAIM_PYTHON_BASE"'; fi' >> ${mygridenvfile}

    read YAIM_PYTHON_VERSIONS < ${yaimv_temp}
    for i in $YAIM_PYTHON_VERSIONS; do
      j=${i//./\\.}
      k=${i//./_}
      echo 'if (echo ":${GLITE_PYTHON_VERSION:-$2}:" | grep -q :'"$j"':);' \
        'then python'"$k"'=python'"$i"';' \
        'else python'"$k"'=python$python; fi' >> ${mygridenvfile}
    done
  elif [ "x${myaction}" = "xrunfunction" ] && [ -n "$yaim_python_lines" ]; then
    echo "$yaim_python_lines" >> ${mygridenvfile}
  fi

  if [ -f ${GRID_ENV_LOCATION}/grid-env.sh ]; then # This is needed when -r is used for the first time before -c
    cat ${mytmpfile} >> ${mygridenvfile}
  fi
  echo ". ${GRID_ENV_LOCATION}/clean-grid-env-funcs.sh" >> ${mygridenvfile}
  echo "fi" >> ${mygridenvfile}
  cp ${mygridenvfile} ${GRID_ENV_LOCATION}/grid-env.sh
  rm -f ${mygridenvfile}
  rm -f ${mytmpfile}
  rm -f ${yaimb_temp}
  rm -f ${yaimv_temp}

  ## fix bug #99296
  #sed -i -e '1i if [ "X`id -u`" != X0 ]; then' -e '$a fi' ${GRID_ENV_LOCATION}/grid-env.sh
  ##end fix

  cat $mythisdir/../etc/grid-env.csh  |  eval sed -e 's%GRID_ENV_LOCATION%${GRID_ENV_LOCATION}/grid-env.sh%' \
                                         > ${GRID_ENV_LOCATION}/grid-env.csh

  if [ -f ${GRID_ENV_LOCATION}/grid-clean-env.sh ]; then # This is needed when -r is used for the first time before -c
    cat ${GRID_ENV_LOCATION}/grid-clean-env.sh | grep -v "grid-env-funcs.sh" | sort -r | uniq > ${mytmpfile}
  fi
  echo ". ${GRID_ENV_LOCATION}/grid-env-funcs.sh" >> ${mygridenvfile}
  if [ -f ${GRID_ENV_LOCATION}/grid-clean-env.sh ]; then # This is needed when -r is used for the first time before -c
    cat ${mytmpfile} >> ${mygridenvfile}
  fi
  echo ". ${GRID_ENV_LOCATION}/clean-grid-env-funcs.sh" >> ${mygridenvfile}
  cp ${mygridenvfile} ${GRID_ENV_LOCATION}/grid-clean-env.sh
  rm -f ${mygridenvfile}
  rm -f ${mytmpfile}
  
  cat $mythisdir/../etc/grid-clean-env.csh  |  eval sed -e 's%GRID_ENV_LOCATION%${GRID_ENV_LOCATION}/grid-clean-env.sh%' \
                                         > ${GRID_ENV_LOCATION}/grid-clean-env.csh



  # Set the environment file permissions
  chmod 644 ${GRID_ENV_LOCATION}/grid-env.sh
  chmod 644 ${GRID_ENV_LOCATION}/grid-env.csh
  chmod 644 ${GRID_ENV_LOCATION}/grid-clean-env.sh
  chmod 644 ${GRID_ENV_LOCATION}/grid-clean-env.csh

else
  # We don't support installation for 3.1 services
  if [ "x${myaction}" = "xinstall" ] && [ "x${GLITE_VERSION}" = "x31" ]; then
    (cat << EOF
      YAIM does not support installation any more for 3.1 services. For installation
      instruction please consult the install section of the Generic Installation Guide for glite 3.1:
      https://twiki.cern.ch/twiki/bin/view/LCG/GenericInstallGuide310#The_install
EOF
    ) | yaimlog ERROR
    sleep 1
    yestr ${YEX_USAGE}
    yaimlog ERROR "${YERRORSTR}" ;
    exit ${YEX_USAGE} ;
  else
    # Execute the command
    (${mycmd}) 2>&1 >> $YAIM_LOG
    ret_code=$?
  fi # installation
fi # environment file

##################
# Cleaning tasks #
##################

# Remove the temp groups.conf file after the execution of the command
rm -rf ${groups_conf_tmp}

# Fix for bug #25667 and #27984
sleep 1
yestr $ret_code
if [ ${ret_code} -eq 0 ]; then
 yaimlog INFO "${YERRORSTR}"
else
 yaimlog ERROR "${YERRORSTR}"
fi
exit $ret_code
