#!/bin/sh
#___INFO__MARK_BEGIN__
##########################################################################
#
#  The Contents of this file are made available subject to the terms of
#  the Sun Industry Standards Source License Version 1.2
#
#  Sun Microsystems Inc., March, 2001
#
#
#  Sun Industry Standards Source License Version 1.2
#  =================================================
#  The contents of this file are subject to the Sun Industry Standards
#  Source License Version 1.2 (the "License"); You may not use this file
#  except in compliance with the License. You may obtain a copy of the
#  License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
#
#  Software provided under this License is provided on an "AS IS" basis,
#  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
#  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
#  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
#  See the License for the specific provisions governing your rights and
#  obligations concerning the Software.
#
#  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
#
#  Copyright: 2001 by Sun Microsystems, Inc.
#
#  All Rights Reserved.
#
##########################################################################
#___INFO__MARK_END__
#-------------------------------------------------
# SGE default configuration file
#-------------------------------------------------

# Use always fully qualified pathnames, please

# SGE_ROOT Path, this is basic information
#(mandatory for qmaster and execd installation)
SGE_ROOT="${cfg.sge.root}";export SGE_ROOT

# SGE_QMASTER_PORT is used by qmaster for communication
# Please enter the port in this way: 1300
# Please do not this: 1300/tcp
#(mandatory for qmaster installation)
SGE_QMASTER_PORT="${cfg.sge.qmaster.port}";export SGE_QMASTER_PORT

# SGE_EXECD_PORT is used by execd for communication
# Please enter the port in this way: 1300
# Please do not this: 1300/tcp
#(mandatory for qmaster installation)
SGE_EXECD_PORT="${cfg.sge.execd.port}";export SGE_EXECD_PORT

# SGE_ENABLE_SMF
# if set to false SMF will not control SGE services
SGE_ENABLE_SMF="${cfg.sge.enable.smf}";export SGE_ENABLE_SMF

# SGE_CLUSTER_NAME
# Name of this cluster (used by SMF as an service instance name)
SGE_CLUSTER_NAME="${cfg.sge.cluster.name}";export SGE_CLUSTER_NAME

# SGE_JMX_PORT is used by qmasters JMX MBean server
# mandatory if install_qmaster -jmx -auto <cfgfile>
# range: 1-65500 
SGE_JMX_PORT="${cfg.sge.jmx.port}";export SGE_JMX_PORT

# SGE_JMX_SSL is used by qmasters JMX MBean server
# if SGE_JMX_SSL=true, the mbean server connection uses
# SSL authentication
SGE_JMX_SSL="${cfg.sge.jmx.ssl}";export SGE_JMX_SSL

# SGE_JMX_SSL_CLIENT is used by qmasters JMX MBean server
# if SGE_JMX_SSL_CLIENT=true, the mbean server connection uses
# SSL authentication of the client in addition
SGE_JMX_SSL_CLIENT="${cfg.sge.jmx.ssl.client}";export SGE_JMX_SSL_CLIENT

# SGE_JMX_SSL_KEYSTORE is used by qmasters JMX MBean server
# if SGE_JMX_SSL=true the server keystore found here is used
# e.g. /var/lib/sgeCA/port${cfg.sge.qmaster.port}/${cfg.cell.name}/private/keystore
SGE_JMX_SSL_KEYSTORE="${cfg.sge.jmx.ssl.keystore}";export SGE_JMX_SSL_KEYSTORE

# SGE_JMX_SSL_KEYSTORE_PW is used by qmasters JMX MBean server
# password for the SGE_JMX_SSL_KEYSTORE file
SGE_JMX_SSL_KEYSTORE_PW="${cfg.sge.jmx.ssl.keystore.pw}";export SGE_JMX_SSL_KEYSTORE_PW

# SGE_JVM_LIB_PATH is used by qmasters jvm thread 
# path to libjvm.so
# mandatory if install_qmaster -jmx -auto <cfgfile>
SGE_JVM_LIB_PATH="${cfg.sge.jvm.lib.path}";export SGE_JVM_LIB_PATH

# SGE_ADDITIONAL_JVM_ARGS is used by qmasters jvm thread 
# jvm specific arguments as -verbose:jni etc.
# optional, can be empty
SGE_ADDITIONAL_JVM_ARGS="${cfg.sge.additional.jvm.args}";export SGE_ADDITIONAL_JVM_ARGS

# CELL_NAME, will be a dir in SGE_ROOT, contains the common dir
# Please enter only the name of the cell. No path, please
#(mandatory for qmaster and execd installation)
CELL_NAME="${cfg.cell.name}";export CELL_NAME

# ADMIN_USER, if you want to use a different admin user than the owner,
# of SGE_ROOT, you have to enter the user name, here
# Leaving this blank, the owner of the SGE_ROOT dir will be used as admin user
ADMIN_USER="${cfg.admin.user}";export ADMIN_USER

# The dir, where qmaster spools this parts, which are not spooled by DB
#(mandatory for qmaster installation)
QMASTER_SPOOL_DIR="${cfg.qmaster.spool.dir}";export QMASTER_SPOOL_DIR

# The dir, where the execd spools (active jobs)
# This entry is needed, even if your are going to use
# berkeley db spooling. Only cluster configuration and jobs will
# be spooled in the database. The execution daemon still needs a spool
# directory  
#(mandatory for qmaster installation)
EXECD_SPOOL_DIR="${cfg.execd.spool.dir}";export EXECD_SPOOL_DIR

# For monitoring and accounting of jobs, every job will get
# unique GID. So you have to enter a free GID Range, which
# is assigned to each job running on a machine.
# If you want to run 100 Jobs at the same time on one host you
# have to enter a GID-Range like that: 16000-16100
#(mandatory for qmaster installation)
GID_RANGE="${cfg.gid.range}";export GID_RANGE

# If SGE is compiled with -spool-dynamic, you have to enter here, which
# spooling method should be used. (classic or berkeleydb)
#(mandatory for qmaster installation)
SPOOLING_METHOD="${cfg.spooling.method}";export SPOOLING_METHOD

# The dir, where the DB spools
# If berkeley db spooling is used, it must contain the path to
# the spooling db. Please enter the full path. (eg. /tmp/data/spooldb)
# Remember, this directory must be local on the qmaster host.
# No NFS mount, please, unless using NFS4 or the "private" option with NFS3
DB_SPOOLING_DIR="${cfg.db.spooling.dir}";export DB_SPOOLING_DIR

# This parameter set the number of parallel installation processes.
# The prevent a system overload, or exeeding the number of open file
# descriptors the user can limit the number of parallel install processes.
# eg. set PAR_EXECD_INST_COUNT="20", maximum 20 parallel execd are installed.
PAR_EXECD_INST_COUNT="${cfg.par.execd.inst.count}";export PAR_EXECD_INST_COUNT

# A List of Host which should become admin hosts
# If you do not enter any host here, you have to add all of your hosts
# by hand, after the installation. The autoinstallation works without
# any entry
ADMIN_HOST_LIST="${cfg.admin.host.list}";export ADMIN_HOST_LIST

# A List of Host which should become submit hosts
# If you do not enter any host here, you have to add all of your hosts
# by hand, after the installation. The autoinstallation works without
# any entry
SUBMIT_HOST_LIST="${cfg.submit.host.list}";export SUBMIT_HOST_LIST

# A List of Host which should become exec hosts
# If you do not enter any host here, you have to add all of your hosts
# by hand, after the installation. The autoinstallation works without
# any entry
# (mandatory for execution host installation)
EXEC_HOST_LIST="${cfg.exec.host.list}";export EXEC_HOST_LIST

# The dir, where the execd spools (local configuration)
# If you want configure your execution daemons to spool in
# a local directory, you have to enter this directory here.
# If you do not want to configure a local execution host spool directory
# please leave this empty
EXECD_SPOOL_DIR_LOCAL="${cfg.exec.spool.dir.local}";export EXECD_SPOOL_DIR_LOCAL

# If true, the domainnames will be ignored, during the hostname resolving
# if false, the fully qualified domain name will be used for name resolving
HOSTNAME_RESOLVING="${cfg.hostname.resolving}";export HOSTNAME_RESOLVING

# Shell, which should be used for remote installation (rsh/ssh)
# This is only supported, if your hosts and rshd/sshd is configured,
# not to ask for a password, or promting any message.
SHELL_NAME="${cfg.shell.name}";export SHELL_NAME

# This remote copy command is used for csp installation.
# The script needs the remote copy command for distributing
# the csp certificates. Using ssl the command scp has to be entered,
# using  the not so secure rsh the command rcp has to be entered.
# Both need a passwordless ssh/rsh connection to the hosts, which
# should be connected to. (mandatory for csp installation mode)
COPY_COMMAND="${cfg.copy.command}";export COPY_COMMAND

# Enter your default domain, if you are using /etc/hosts or NIS configuration
DEFAULT_DOMAIN="${cfg.default.domain}";export DEFAULT_DOMAIN

# If a job stops, fails, finish, you can send a mail to this adress
ADMIN_MAIL="${cfg.admin.mail}";export ADMIN_MAIL

# If true, the rc scripts (sgemaster, sgeexecd, sgebdb) will be added,
# to start automatically during boottime
ADD_TO_RC="${cfg.add.to.rc}";export ADD_TO_RC

#If this is "true" the file permissions of executables will be set to 755
#and of ordenary file to 644.  
SET_FILE_PERMS="${cfg.set.file.perms}";export SET_FILE_PERMS

# This option is not implemented, yet.
# When a exechost should be uninstalled, the running jobs will be rescheduled
RESCHEDULE_JOBS="wait";export RESCHEDULE_JOBS

# Enter a one of the three distributed scheduler tuning configuration sets
# (1=normal, 2=high, 3=max)
SCHEDD_CONF="${cfg.schedd.conf}";export SCHEDD_CONF

# The name of the shadow host. This host must have read/write permission
# to the qmaster spool directory
# If you want to setup a shadow host, you must enter the servername
# (mandatory for shadowhost installation)
SHADOW_HOST="${cfg.shadow.host}";export SHADOW_HOST

# Remove this execution hosts in automatic mode
# (mandatory for unistallation of execution hosts)
EXEC_HOST_LIST_RM="${cfg.exec.host.list.rm}";export EXEC_HOST_LIST_RM

# This option is used for startup script removing. 
# If true, all rc startup scripts will be removed during
# automatic deinstallation. If false, the scripts won't
# be touched.
# (mandatory for unistallation of execution/qmaster hosts)
REMOVE_RC="${cfg.remove.rc}";export REMOVE_RC

# This is a Windows specific part of the auto isntallation template
# If you going to install windows executions hosts, you have to enable the
# windows support. To do this, please set the WINDOWS_SUPPORT variable
# to "true". ("false" is disabled)
# (mandatory for qmaster installation, by default WINDOWS_SUPPORT is
# disabled)
WINDOWS_SUPPORT="${cfg.windows.support}";export WINDOWS_SUPPORT

# Enabling the WINDOWS_SUPPORT, recommends the following parameter.
# The WIN_ADMIN_NAME will be added to the list of SGE managers.
# Without adding the WIN_ADMIN_NAME the execution host installation
# won't install correctly.
# WIN_ADMIN_NAME is set to "Administrator" which is default on most
# Windows systems. In some cases the WIN_ADMIN_NAME can be prefixed with
# the windows domain name (eg. DOMAIN+Administrator)
# (mandatory for qmaster installation, if windows hosts should be installed)
WIN_ADMIN_NAME="${cfg.win.admin.name}";export WIN_ADMIN_NAME

# This parameter is used to switch between local ADMINUSER and Windows
# Domain Adminuser. Setting the WIN_DOMAIN_ACCESS variable to true, the
# Adminuser will be a Windows Domain User. It is recommended that 
# a Windows Domain Server is configured and the Windows Domain User is
# created. Setting this variable to false, the local Adminuser will be
# used as ADMINUSER. The install script tries to create this user account
# but we recommend, because it will be saver, to create this user,
# before running the installation. 
# (mandatory for qmaster installation, if windows hosts should be installed)
WIN_DOMAIN_ACCESS="${cfg.win.domain.access}";export WIN_DOMAIN_ACCESS

# This section is used for csp installation mode.
# CSP_RECREATE recreates the certs on each installtion, if true.
# In case of false, the certs will be created, if not existing.
# Existing certs won't be overwritten. (mandatory for csp install)
CSP_RECREATE="${cfg.csp.recreate}";export CSP_RECREATE

# The created certs won't be copied, if this option is set to false
# If true, the script tries to copy the generated certs. This
# requires passwordless ssh/rsh access for user root to the
# execution hosts
CSP_COPY_CERTS="${cfg.csp.copy.certs}";export CSP_COPY_CERTS

# csp information, your country code (only 2 characters)
# (mandatory for csp install)
CSP_COUNTRY_CODE="${cfg.csp.country.code}";export CSP_COUNTRY_CODE

# your state (mandatory for csp install)
CSP_STATE="${cfg.csp.state}";export CSP_STATE

# your location, eg. the building (mandatory for csp install)
CSP_LOCATION="${cfg.csp.location}";export CSP_LOCATION

# your arganisation (mandatory for csp install)
CSP_ORGA="${cfg.csp.orga}";export CSP_ORGA

# your organisation unit (mandatory for csp install)
CSP_ORGA_UNIT="${cfg.csp.orga.unit}";export CSP_ORGA_UNIT

# your email (mandatory for csp install)
CSP_MAIL_ADDRESS="${cfg.csp.mail.address}";export CSP_MAIL_ADDRESS

# enforced hostname in case of other than primary network interface was selected
ENFORCED_HOSTNAME="${add.qmaster.host}";export ENFORCED_HOSTNAME

#Additional variables from the installer
#REMOVE_EXISTING_COMPONENT=${add.remove.existing.components}
REMOVE_EXISTING_COMPONENT=false
#QMASTER Flags
USE_JMX=${add.sge.jmx}
PRODUCT_MODE=${add.product.mode}                      #1 none, 2 csp, 3 afs
QMASTER_FLAGS=""
GUI_CSP_MODE_ENABLED=false
if [ "$USE_JMX" = true ]; then
   QMASTER_FLAGS="$QMASTER_FLAGS -jmx"                # -jmx is implicit
else
   SGE_JVM_LIB_PATH="none"                            # this disables JMX
fi
#Set proper product mode flags
if [ "$PRODUCT_MODE" = "csp" ]; then
   QMASTER_FLAGS="$QMASTER_FLAGS -csp"
   GUI_CSP_MODE_ENABLED=true
fi

#Genaretes output consisting of the exit code and log file
# $1 ... COMPONENT (bdb, qmaster, shadow,exec)
# $2 ... output from the previosly executed install/uninstall command
# $3 ... EXIT_CODE (optional if exit code is 0)
GenerateResultOutput()
{
	COMPONENT=$1
	LOG_FILE=`echo "$2" | grep "Install log can be found in:" | awk '{print $NF}' | tail -1`
	EXIT_CODE=$3
	
	if [ -n "$EXIT_CODE" -a "$EXIT_CODE" -ne 0 ]; then
		if [ -z "$2" ]; then
           echo "___EXIT_CODE_${EXIT_CODE}___"
		   exit $EXIT_CODE
		fi
    fi
	
   cat "$LOG_FILE"
   if [ "$EXIT_CODE" -ne 0 ]; then
      echo "___EXIT_CODE_${EXIT_CODE}___"
      exit $EXIT_CODE
   fi
}

#Genaretes output consisting of the exit code and log file
# $1 ... output to be in a log
# $2 ... EXIT_CODE
ExitAndLog()
{
   EXIT_CODE=$2
   echo "$1"
   if [ "$EXIT_CODE" -ne 0 ]; then
         echo "___EXIT_CODE_${EXIT_CODE}___"
   fi
   exit $EXIT_CODE
}

NOEXIT_OK=0
EXIT_PREVIOUS_COMPONENT_DETECTED=10
EXIT_UNINSTALLATION_FAILED=11

IS_BDB=$1
IS_QMASTER=$2
IS_SHADOW=$3
IS_EXECD=$4
IS_ADMIN=$5
IS_SUBMIT=$6


#//TODO: Check if SGE_ROOT is valid and needed files exist first!
cd ${cfg.sge.root}
if [ "$IS_BDB" = true ]; then
   ENFORCED_HOSTNAME=""
   #BDB is considered installed if the SPOOL_DIR_EXISTS
   if [ -d "$DB_SPOOLING_DIR" ]; then
      #Uninstall existing installation if chosen
      if [ "$REMOVE_EXISTING_COMPONENT" = true ]; then
         RES=`${cfg.sge.root}/inst_sge -udb -noremote -autogui`
         #Uninstallation failed if non-zero or bdb spool dir still exists
         if [ $? -ne 0 -o -d "$DB_SPOOLING_DIR" ]; then            
            #Uninstallation failed
            GenerateResultOutput "BDB" "$RES" $EXIT_UNINSTALLATION_FAILED
         fi
      else
	    #Conflicting installation detected
        ExitAndLog "BDB spooling directory $DB_SPOOLING_DIR already exists." $EXIT_PREVIOUS_COMPONENT_DETECTED
      fi
   fi
   RES=`${cfg.sge.root}/inst_sge -db -noremote -autogui`
   ret=$?
   GenerateResultOutput "BDB" "$RES" $ret
   #We exit if there is not other installation, can't do qconf just yet
   if [ "$IS_QMASTER" = false -a "$IS_SHADOW" = false -a "$IS_EXECD" = false ]; then
      exit $ret
   fi
fi

if [ "$IS_QMASTER" = true ]; then
   #Qmaster is considered installed if the bootstrap file exists
   if [ -f "${cfg.sge.root}/$CELL_NAME/common/bootstrap" ]; then
      #Uninstall existing installation if chosen
      if [ "$REMOVE_EXISTING_COMPONENT" = true ]; then
         RES=`${cfg.sge.root}/inst_sge -ux all -um -autogui`
         #Uninstallation failed if non-zero or bootstrap still exists
         if [ $? -ne 0 -o -f "${cfg.sge.root}/$CELL_NAME/common/bootstrap" ]; then
            #Uninstallation failed
            GenerateResultOutput "QMASTER" "$RES" $EXIT_UNINSTALLATION_FAILED
         fi
      else
         #Conflicting installation detected 
         ExitAndLog "${cfg.sge.root}/$CELL_NAME/common/bootstrap file already exits." $EXIT_PREVIOUS_COMPONENT_DETECTED
      fi
   fi
   RES=`${cfg.sge.root}/inst_sge -m $QMASTER_FLAGS -noremote -autogui`
   ret=$?
   #Generate a result based
   GenerateResultOutput "QMASTER" "$RES" $ret
fi

if [ -n "${first_install_task}" ]; then
   echo "Prerequisities"
   #Add all hosts as admin hosts on qmaster host only if this is a first task or right after the installation
   #Only first installation tasks have $cfg.allhosts set (no action otherwise)
   ARCH=`sh -c "${cfg.sge.root}/util/arch" 2>/dev/null`
   QMASTER_HOST=`cat "$SGE_ROOT/$CELL_NAME/common/act_qmaster" 2>/dev/null`
   CURRENT_HOST=`sh -c '. ${cfg.sge.root}/${cfg.cell.name}/common/settings.sh ;  ${cfg.sge.root}/utilbin/'${ARCH}'/gethostname -aname' 2>/dev/null`
   #if [ "$HOSTNAME_RESOLVING" = true ]; then
      QMASTER_HOST=`echo $QMASTER_HOST | cut -f1 -d. | tr "[A-Z]" "[a-z]"`
      CURRENT_HOST=`echo $CURRENT_HOST | cut -f1 -d. | tr "[A-Z]" "[a-z]"`
   #fi
   qmaster_connect_user="${gui_qmaster_connect_user}"
   shell_options="${gui_shell_options}"
   if [ -n "${gui_alladminhosts}" ]; then
      list="${gui_alladminhosts}"
      total=0
      failed=0
      for host in $list ; do
         echo "Adding \"$host\" as admin host ..."
         if [ "$QMASTER_HOST" != "$CURRENT_HOST" ]; then
            output=`$SHELL_NAME -l $qmaster_connect_user $shell_options $QMASTER_HOST "sh -c '. ${cfg.sge.root}/${cfg.cell.name}/common/settings.sh ; qconf -ah '${host}" 2>&1`
         else
            output=`sh -c '. ${cfg.sge.root}/${cfg.cell.name}/common/settings.sh ; qconf -ah '${host} 2>&1`
         fi
         case "$output" in
            *' added '*|*' already exists'*)
               echo "   OK"
               ;;
            *)
               echo "   FAILED: $output"
               failed=`expr $failed + 1`
               ;;
         esac
         total=`expr $total + 1`
      done
      #We fail this task if at least 50% hosts fail
      if [ $failed -gt `expr $total / 2` ]; then
         ExitAndLog "Adding admin hosts failed for many hosts! Further component installations will fail!" 1
      elif [ $failed -gt 0 ]; then
         ExitAndLog "Adding admin hosts failed for ${failed}/${total} hosts! Further component installations will fail on failed hosts!" 0
      else
         echo "Adding admin hosts succeeded."
      fi
   fi
   #TODO: Need only subset of copycerts also for JMX with SSL!
   #For the CSP mode we have to copy the certificates to each of the execd/submit/admin hosts
   if [ -n "${gui_csphosts}" ]; then
      # Setup PORT_DIR
      CA_TOP="/var/lib/sgeCA"
      if [ "$SGE_QMASTER_PORT" = "" ]; then
         PORT_DIR="sge_qmaster"
      else
         PORT_DIR="port$SGE_QMASTER_PORT"
      fi
      TMP_CERTS="/tmp/sgeCA.${CELL_NAME}.$$.tar"
      # Part 1 - copy certs from QMASTER locally (if not on qmaster)
      if [ "$QMASTER_HOST" != "$CURRENT_HOST" ]; then
         echo "Copying certificates from qmaster ($QMASTER_HOST) to localhost ($CURRENT_HOST) ..."
         $SHELL_NAME -l $qmaster_connect_user $shell_options $QMASTER_HOST \
                     "cd $CA_TOP ; tar cpf - ./$PORT_DIR | gzip -" > "$TMP_CERTS".gz
         if [ $? -ne 0 ]; then
            ExitAndLog "Preparing local tar.gz file with certicates from qmaster host failed." 1
         fi
      else
         #We create the tar.gz locally anyway
         (cd $CA_TOP ; tar cpf "$TMP_CERTS" ./$PORT_DIR && gzip "$TMP_CERTS")
         if [ $? -ne 0 ]; then
            ExitAndLog "Preparing local tar.gz file with certicates failed." 1
         fi
      fi
      chmod 400 ${TMP_CERTS}.gz
      # Part 2 - copy the local certs to all hosts (last one is the local host)
      list="${gui_csphosts}"
      total=0
      failed=0
      current=0
      for host in $list ; do
         current=`expr $current + 1`
         total=`expr $total + 1`
         if [ "$host" = "$QMASTER_HOST" ]; then
            echo "Skipping qmaster host (already has certificates)"
            total=`expr $total - 1`
            continue
         fi
         echo "Copying certificates to $host ..."
         #Need a remote connection
         if [ "$host" != "$CURRENT_HOST" ]; then
            currect_connect_user=`echo "${gui_csphosts_connectusers}" | awk '{print $i}' i=$current`
            # Send the certs via ssh as tar.gz
            cat "$TMP_CERTS".gz | $SHELL_NAME -l $currect_connect_user $shell_options $host sh -c "cat > ${TMP_CERTS}.gz && chmod 400 ${TMP_CERTS}.gz && mkdir -p ${CA_TOP} && cd ${CA_TOP} && rm -rf ${CA_TOP}/${PORT_DIR} && gunzip -f ${TMP_CERTS}.gz && tar xpf ${TMP_CERTS} ; rm -f ${TMP_CERTS} && for user in \`ls -1 ${CA_TOP}/${PORT_DIR}/${CELL_NAME}/userkeys\`; do chown -R \$user ${CA_TOP}/${PORT_DIR}/${CELL_NAME}/userkeys/\${user} ; done"
            if [ $? -ne 0 ]; then
               failed=`expr $failed + 1`
               echo "   FAILED"
            else
               echo "   OK"
            fi
         elif [ "$host" != "QMASTER_HOST" ]; then
            # If qmaster is not on the local host (CERT is missing locally). 
            # Must be the last since we move the TMP_CERTS to a final location
            mkdir -p ${CA_TOP} ; rm -rf ${CA_TOP}/${PORT_DIR}
            ( cd ${CA_TOP} ; gunzip -f ${TMP_CERTS}.gz && tar xpf ${TMP_CERTS} )
            if [ $? -ne 0 ]; then
               failed=`expr $failed + 1`
            fi
            #Set correct owners, tar might not preserve uid>60000 on some platforms
            for user in `ls -1 ${CA_TOP}/${PORT_DIR}/${CELL_NAME}/userkeys`; do 
               chown -R $user ${CA_TOP}/${PORT_DIR}/${CELL_NAME}/userkeys/${user}
            done
         fi
      done
      
      #Remove the temporary certificates copied in Part1
      rm -f ${TMP_CERTS}.gz

      if [ $total -eq $failed -a $total -gt 0 ]; then
         ExitAndLog "Copying certificates failed for all hosts! Further component installations will fail due to missing certificates. Try inst_sge -copycerts manually for each host" 1
      elif [ $failed -gt 0 ]; then
         ExitAndLog "Copying certificates failed for ${failed}/${total} hosts! Further component installations will fail due to missing certificates on failed hosts. Try inst_sge -copycerts manually for each host where installation failed." 0
      else
         ExitAndLog "Certificates copied sucessfully to all hosts." 0
      fi
   fi
   ExitAndLog "Prerequisities done." 0
fi

if [ "$IS_SHADOW" = true ]; then
   ENFORCED_HOSTNAME="$EXEC_HOST_LIST"
   #Shadowd is considered installed if it's listed in the shadow_masters file
   SM_FILE="${cfg.sge.root}/$CELL_NAME/common/shadow_masters"   
   if [ -f "$SM_FILE" ]; then
      RES=`cat "$SM_FILE" | grep $EXEC_HOST_LIST 2>/dev/null`
      #Uninstall existing installation if chosen      
      if [ "$REMOVE_EXISTING_COMPONENT" = true -a -n "$RES" ]; then
         RES=`${cfg.sge.root}/inst_sge -usm -noremote -autogui`
         ret=$?			
         RES2=`cat "$SM_FILE" | grep $EXEC_HOST_LIST 2>/dev/null`
         #Uninstallation failed if non-zero or shadow_masters still references it
         if [ $ret -ne 0 -o -n "$RES2" ]; then            
            #Uninstallation failed
            GenerateResultOutput "SHADOW" "$RES" $EXIT_UNINSTALLATION_FAILED
         fi
      elif [ -n "$RES" ]; then
         #Conflicting installation detected 
         ExitAndLog "${cfg.sge.root}/$CELL_NAME/common/shadow_masters already contains host \"$EXEC_HOST_LIST\"." $EXIT_PREVIOUS_COMPONENT_DETECTED
      fi
   fi
   RES=`${cfg.sge.root}/inst_sge -sm -noremote -autogui`
   GenerateResultOutput "SHADOW" "$RES" $?
fi

if [ "$IS_EXECD" = true ]; then
   ENFORCED_HOSTNAME="$EXEC_HOST_LIST"
   host="$EXEC_HOST_LIST"
   if [ -n "$EXECD_SPOOL_DIR_LOCAL" -a -d "$EXECD_SPOOL_DIR_LOCAL" ]; then
      local_exists=true
   fi   
   #Execd is considered installed if EXECD_(LOCAL)SPOOL_DIR/$host exists"   
   if [ "$local_exists" = true -o -d "$EXECD_SPOOL_DIR/$host" ]; then
      #Uninstall existing installation if chosen      
      if [ "$REMOVE_EXISTING_COMPONENT" = true ]; then
         RES=`${cfg.sge.root}/inst_sge -ux -noremote -autogui`
         #Uninstallation failed if non-zero or it's spool dir still exists
         if [ $? -ne 0 \ 
            -o \( "$local_exists" = true -a -d "$EXECD_SPOOL_DIR_LOCAL/$host" \) \
            -o \( "$local_exists" != true -a -d "$EXECD_SPOOL_DIR/$host" \) ]; then            
            #Uninstallation failed
            GenerateResultOutput "EXECD" "$RES" $EXIT_UNINSTALLATION_FAILED
         fi
      else
         #Conflicting installation detected 
         if [ "$local_exists" ]; then
            ExitAndLog "Local execution spooling directory \"$EXECD_SPOOL_DIR_LOCAL\" already exists." $EXIT_PREVIOUS_COMPONENT_DETECTED
         else
            ExitAndLog "Execution spooling directory \"$EXECD_SPOOL_DIR/$host\" already exists." $EXIT_PREVIOUS_COMPONENT_DETECTED
         fi
      fi
   fi
   RES=`${cfg.sge.root}/inst_sge -x -noremote -autogui`
   GenerateResultOutput "EXECD" "$RES" $?
fi

#To setup the final submit/admin hosts settings as specifed
#Extra last tasks runs only this part of the script (otherwise ${cfg.allhosts.current.last} is not set)
if [ -n "${last_install_task}" ]; then
   ARCH=`sh -c "${cfg.sge.root}/util/arch" 2>/dev/null`
   CURRENT_HOST=`sh -c '. ${cfg.sge.root}/${cfg.cell.name}/common/settings.sh ;  ${cfg.sge.root}/utilbin/'${ARCH}'/gethostname -aname' 2>/dev/null`
   #if [ "$HOSTNAME_RESOLVING" = true ]; then
   CURRENT_HOST=`echo $CURRENT_HOST | cut -f1 -d. | tr "[A-Z]" "[a-z]"`
   SKIPPED_HOST=""
   #Remove all hosts as submit/admin hosts (marked possibly as submit in previous installation)
   list="${gui_allhosts}"
   for host in $list; do
      #Remove as submit host
      sh -c '. ${cfg.sge.root}/${cfg.cell.name}/common/settings.sh ; qconf -ds '$host >/dev/null 2>&1
      #Remove admin host except for local host)
      if [ "$host" = "$CURRENT_HOST" ]; then
         SKIPPED_HOST="$host"
         continue
      fi
      sh -c '. ${cfg.sge.root}/${cfg.cell.name}/common/settings.sh ; qconf -dh '$host >/dev/null 2>&1
   done
   echo "Setting submit hosts ..."
   #Add all submit hosts
   list="${gui_allsubmithosts}"
   for host in $list; do
      sh -c '. ${cfg.sge.root}/${cfg.cell.name}/common/settings.sh ; qconf -as '$host 2>&1
   done
   #Same logic for admin hosts
   #Add all admin hosts
   SKIPPED_FOUND=false
   echo "Setting admin hosts ..."
   list="${gui_alladminhosts}"
   for host in $list ; do
      sh -c '. ${cfg.sge.root}/${cfg.cell.name}/common/settings.sh ; qconf -ah '$host 2>&1
      if [ "$host" = "$SKIPPED_HOST" ]; then
         SKIPPED_FOUND=true
      fi
   done
   #Finally remove local host as admin host if not supposed to be an admin host
   if [ "$SKIPPED_FOUND" = "false" ]; then
      sh -c '. ${cfg.sge.root}/${cfg.cell.name}/common/settings.sh ; qconf -dh '$SKIPPED_HOST >/dev/null 2>&1
   fi
   #TODO: could verify that new qconf -ss/sh output contains all new hosts
   #TODO: Additional final verification can go here
   ExitAndLog "Admin and submit hosts set." 0
fi

if [ -z "$EXIT_CODE" ]; then
   exit 0
else
   exit $EXIT_CODE
fi
