Commit e9763a58 authored by Kalana Wijethunga's avatar Kalana Wijethunga
Browse files

Add VoBox v1.0 scripts

parents
# JAliEn Startup Scripts
This repository contains the scripts required to control CE and MonaLisa services in VOBoxes. The scripts will reside in `/cvmfs/alice.cern.ch/scripts/vobox`
# Usage
```
Usage: jalien-vobox <Command> [<Service>]
<Command> is one of: start status stop restart mlstatus
<Service> is one of: ce monalisa (defaulting to both if not specified)
```
Running a command without specifying a service will run the command on both CE and MonaLisa services.
## Configuration
Both the services are able to start without any configurations. However, following parameters can be overriden by defining them in `$HOME/alien/version.properties` as key-value pairs.
```
MONALISA_HOME=<MonaLisa package location>
MONALISA=<MonaLisa version>
JALIEN=<JAliEn version>
```
> Note: As the MonaLisa package is not available in CVMFS yet, it is essential to define MONALISA_HOME to specify the MonaLisa package location. If it is not locally available, please use `install` as the value for `<MonaLisa package location>`.
If it is required to run any shell command before starting either of the services, they can be added in `$logDir/ml-env.sh` or `$logDir/ce-env.sh`. Content in these two scripts will be run before starting the service. `logDir` will default to `$HOME/ALICE/alien-logs` if a `LOGDIR` is not defined in LDAP.
#!/bin/bash
# JAliEn Startup Scripts - CE
# v1.0
# Authors: Kalana Dananjaya, Maarten Litmaath, Costin Grigoras(kwijethu@cern.ch,Maarten.Litmaath@cern.ch,Costin.Grigoras@cern.ch)
# 2021-08-08
ceClassName=alien.site.ComputingElement
##############################################
# Write log to file
# Globals:
# setupLogFile: Log file for MonaLisa setup
# Arguments:
# $1: String to log
###############################################
function write_log(){
echo $1 >> $setupLogFile
}
#############################################################################################
# Stop CE
# Globals:
# ceClassName : Computing Element classname
#############################################################################################
function stop_ce() {
echo "Stopping JAliEn CE..."
pkill -TERM -f $ceClassName
sleep 3
status_ce || return 0
echo "Killing JAliEn CE..."
pkill -KILL -f $ceClassName
! status_ce
}
#############################################################################################
# CE liveness check
# Returns:
# 0 if process is running,else 1
#############################################################################################
function check_liveness_ce(){
if ps uxwww | grep "[ ]$ceClassName" > /dev/null
then
return 0
else
return 1
fi
}
###################################
# Check CE status
# Arguments:
# $command: "status" or "mlstatus"
# Returns:
# 0 if process is running,else 1
###################################
function status_ce() {
command=$1
check_liveness_ce
exit_code=$?
[[ $exit_code == 0 ]] && not= || not=' Not'
if [[ "$command" == mlstatus ]]
then
echo -e "Status\t$exit_code\tMessage\tCE$not Running"
else
echo -e "CE$not Running"
fi
return $exit_code
}
#############################################################################################
# Start MonaLisa
# Globals:
# siteConfiguration: Associative array of site configuration parameters in LDAP
# commonConfiguration: Associative array of JAliEn local configuration parameters
# Arguments:
# confDir: AliEn configuration directory
# ldapHostname: LDAP hostname
# ldapPort: LDAP port
# hostname: Site hostname
#############################################################################################
function start_ce(){
confDir=$1
ldapHostname=$2
ldapPort=$3
hostname=$4
nl='
'
nl=${nl:0:1}
if check_liveness_ce
then
echo "JAliEn CE already running"
return 0
fi
# Obtain site related configurations from LDAP
ldapBase="ou=Sites,o=alice,dc=cern,dc=ch"
ldapFilter="(&(objectClass=AliEnHostConfig)(host=$hostname))"
siteLDAPQuery=$(
ldapsearch -x -LLL -h $ldapHostname -p $ldapPort -b $ldapBase "$ldapFilter" |
perl -p00e 's/\n //g' | envsubst
)
declare -A siteConfiguration
while IFS= read -r line
do
#Ignore empty lines and create an associative array from LDAP configuration
if [[ ! -z $line ]]
then
key=$(echo "$line" | cut -d ":" -f 1 )
val=$(echo "$line" | cut -d ":" -f 2- | sed s/.//)
key=${key^^}
prev=${siteConfiguration[$key]}
prev=${prev:+$prev$nl}
siteConfiguration[$key]=$prev$val
fi
done <<< "$siteLDAPQuery"
baseLogDir=$(echo "${siteConfiguration[LOGDIR]}" | envsubst)
if [[ -z $baseLogDir ]]
then
baseLogDir="$HOME/ALICE/alien-logs"
echo "LDAP doesn't define a particular log location, using the default ($baseLogDir)"
fi
logDir="$baseLogDir/CE"
setupLogFile="$logDir/CE-config-inputs.txt"
commonConf="$confDir/version.properties"
ceEnv="$confDir/CE.env"
envCommand="/cvmfs/alice.cern.ch/bin/alienv printenv JAliEn"
> $setupLogFile
# Read JAliEn config files
if [[ -f "$commonConf" ]]
then
declare -A commonConfiguration
while IFS= read -r line
do
if [[ ! $line = \#* ]] && [[ ! -z $line ]]
then
key=$(echo "$line" | cut -d "=" -f 1 )
val=$(echo "$line" | cut -d "=" -f 2- )
key=${key^^}
prev=${commonConfiguration[$key]}
prev=${prev:+$prev$nl}
commonConfiguration[$key]=$prev$val
fi
done < "$commonConf"
fi
write_log ""
write_log "===================== Local Configuration start ==================="
for x in "${!commonConfiguration[@]}"
do
printf "[%s]=%s\n" "$x" "${commonConfiguration[$x]}" >> $setupLogFile
done
write_log "===================== Local Configuration end ==================="
write_log ""
envFile="$logDir/CE-env.sh"
pidFile="$logDir/CE.pid"
if ! mkdir -p $logDir
then
echo "Unable to create log directory at $logDir"
return 1
fi
# Reset the environment
> $envFile
# Bootstrap the environment e.g. with the correct X509_USER_PROXY
[[ -f "$ceEnv" ]] && cat "$ceEnv" >> $envFile
# Check for JAliEn version
if [[ -n "${commonConfiguration[JALIEN]}" ]]
then
envCommand="$envCommand/${commonConfiguration[JALIEN]}"
fi
$envCommand | grep . >> $envFile || return 1
logFile="$logDir/CE-jvm-$(date '+%y%m%d-%H%M%S')-$$-log.txt"
echo -e "Starting JAliEn CE...\nJVM log:$logFile"
(
# In a subshell, to get the process detached from the parent
source $envFile
cd $logDir
nohup jalien $ceClassName > "$logFile" 2>&1 < /dev/null &
echo $! > "$pidFile"
)
sleep 3
status_ce
}
function run_ce() {
command=$1
if [[ $command = "start" ]]
then
confDir=$2
ldapHostname=$3
ldapPort=$4
hostname=$5
start_ce $confDir $ldapHostname $ldapPort $hostname
elif [[ $command = "stop" ]]
then
stop_ce
elif [[ $command = "restart" ]]
then
stop_ce
start_ce $confDir $ldapHostname $ldapPort $hostname
elif [[ $command =~ "status" ]]
then
status_ce $command
else
echo "Command must be one of: 'start', 'stop', 'restart' or '(ml)status'"
return 2
fi
}
#!/bin/bash
# JAliEn Startup Scripts
# v1.0
# Authors: Kalana Dananjaya, Maarten Litmaath, Costin Grigoras(kwijethu@cern.ch,Maarten.Litmaath@cern.ch,Costin.Grigoras@cern.ch)
# 2021-08-08
ldapHostname="alice-ldap.cern.ch"
ldapPort="8389"
hostname=`hostname -f`
dir="$(cd `dirname -- "$0"` &>/dev/null && pwd)"
source $dir/jalien-ce.sh
source $dir/monalisa.sh
cmds='start status stop restart mlstatus'
svcs='ce monalisa'
confDir="${HOME}/.alien/config"
usage()
{
exec >&2
echo ""
echo "Usage: jalien-vobox <Command> [<Service>]"
echo ""
echo "<Command> is one of: $cmds"
echo "<Service> is one of: $svcs (defaulting to both if not specified)"
echo ""
exit 2
}
for cmd in $cmds
do
[[ "$1" = $cmd ]] && break
done
[[ "$1" = $cmd ]] || usage
for svc in $svcs
do
[[ "$2" = $svc ]] && break
done
[[ "$2" = $svc ]] || [[ "$2" = "" ]] || usage
for svc in ${2:-$svcs}
do
if [[ $svc = "monalisa" ]]
then
run_monalisa $cmd $confDir $ldapHostname $ldapPort $hostname
elif [[ $svc = "ce" ]]
then
run_ce $cmd $confDir $ldapHostname $ldapPort $hostname
else
usage
fi
done
#!/bin/bash
# JAliEn Startup Scripts - MonaLisa
# v1.0
# Authors: Kalana Dananjaya, Maarten Litmaath, Costin Grigoras(kwijethu@cern.ch,Maarten.Litmaath@cern.ch,Costin.Grigoras@cern.ch)
# 2021-08-08
##############################################
# Write log to file
# Globals:
# setupLogFile: Log file for MonaLisa setup
# Arguments:
# $1: String to log
###############################################
function write_log(){
echo $1 >> $setupLogFile
}
####################################################################################
# Templates a given configuration files(Add, delete or change content)
# Globals:
# add: Array of lines to add to file
# rmv: Array of lines to be removed from file
# changes: Associative array of line to be changed {original_text:change_to_text}
# Arguments:
# srcFile: Source file
# destFile: Destination file
####################################################################################
function template(){
srcFile=$1
destFile=$2
write_log "=========== Templating the File ==========="
write_log "+ Source File: $srcFile"
write_log "+ Destination File: $destFile"
write_log ""
# Create backup of the original file if it exists
[ -f $destFile ] && cp -f $destFile "$destFile.orig"
cp $srcFile $destFile
# Apply lines changes
write_log ">>> Applying Changes"
for key in "${!changes[@]}"
do
# Find partial matches and replace
write_log "Change key: $key to value: ${changes[$key]}"
sed -i "s|$key|${changes[$key]}|" $destFile
done
unset changes && write_log ""
# Append new Lines
write_log ">>> Adding new lines"
for i in "${add[@]}"
do
write_log "+++ $i"
echo "$i" >> $destFile
done
unset add && write_log ""
# Remove existing lines
write_log ">>> Removing existing lines"
for i in "${rmv[@]}"
do
# Find exact word matches and delete the line
write_log "--- $i"
sed -i "/$i\b/d" $destFile
done
unset rmv && write_log ""
write_log " --- Templating Complete ---"
write_log ""
}
#############################################################################################
# Setup MonaLisa
# Globals:
# monalisaLDAPconfiguration: Associative array of MonaLisa configuration parameters in LDAP
# baseLogDir: MonaLisa Log file. Defaults to ~/ALICE/alien-logs
# ceLogFile: CE Log File
# Arguments:
# farmHome: MonaLisa base package location
# logDir: MonaLisa log directory
#############################################################################################
function setup() {
farmHome=$1
logDir=$2
add=()
rmv=()
declare -Ag changes
# Copy base templates to the local directory
mkdir -p "$logDir/myFarm/"
# ===================================================================================
# myFarm.conf
# Convert multi-valued attribute to array
while IFS= read -r line ; do add+=($line); done <<< "${siteConfiguration[MONALISA_ADDMODULES_LIST]}"
add+=("^monLogTail{Cluster=AliEnServicesLogs,Node=CE,command=tail -n 15 -F $ceLogFile 2>&1}%3")
add+=("*AliEnServicesStatus{monStatusCmd, localhost, \"logDir=$baseLogDir $(cd `dirname -- "$0"` &>/dev/null && pwd)/jalien-vobox.sh mlstatus ce,timeout=800\"}%900")
template "$farmHome/Service/myFarm/myFarm.conf" "$logDir/myFarm/myFarm.conf"
# ========================================================================================
# ml.properties
declare -Ag changes
# Convert multi-valued attribute to array
while IFS= read -r line ; do add+=($line); done <<< "${monalisaLDAPconfiguration[ADDPROPERTIES]}"
location=${monalisaLDAPconfiguration[LOCATION]-${monalisaLDAPconfiguration[SITE_LOCATION]}} || ""
country=${monalisaLDAPconfiguration[COUNTRY]-${monalisaLDAPconfiguration[SITE_COUNTRY]}} || ""
long=${monalisaLDAPconfiguration[LONGITUDE]-${monalisaLDAPconfiguration[SITE_LONGITUDE]}} || "N/A"
lat=${monalisaLDAPconfiguration[LATITUDE]-${monalisaLDAPconfiguration[SITE_LATITUDE]}} || "N/A"
admin=${monalisaLDAPconfiguration[ADMINISTRATOR]-${monalisaLDAPconfiguration[SITE_ADMINISTRATOR]}} || "N/A"
changes["^MonaLisa.Location.*"]="MonaLisa.Location=$location"
changes["^MonaLisa.Country.*"]="MonaLisa.Country=$country"
changes["^MonaLisa.LAT.*"]="MonaLisa.LAT=$lat"
changes["^MonaLisa.LONG.*"]="MonaLisa.LONG=$long"
changes["^MonaLisa.ContactEmail.*"]="MonaLisa.ContactEmail=$admin"
template "$farmHome/Service/myFarm/ml.properties" "$logDir/myFarm/ml.properties"
# ===================================================================================
# ml.env
declare -Ag changes
changes["^FARM_NAME.*"]="FARM_NAME=\"${monalisaLDAPconfiguration[NAME]}\""
changes["^FARM_HOME.*"]="FARM_HOME=\"$logDir/myFarm\""
changes["^MONALISA_USER.*"]="MONALISA_USER=\"$(id -u -n)\""
changes["^MonaLisa_HOME.*"]="MonaLisa_HOME=\"$MonaLisa_HOME\""
template "$farmHome/Service/CMD/ml_env" "$logDir/myFarm/ml_env"
# ============================= Export variables =====================================
export CONFDIR="$logDir/myFarm"
export ALICE_LOGDIR=$baseLogDir
export JAVA_OPTS=${monalisaLDAPconfiguration[JAVAOPTS]}
# ===================================================================================
}
#####################################
# MonaLisa liveness check
# Returns:
# 0 if process is running,else 1
#####################################
function check_liveness_ml(){
pid=$(pgrep -n -u `id -u` -f -- "-DMonaLisa_HOME=")
if [[ -z $pid ]]
then
return 1
else
return 0
fi
}
#############################################################################################
# Start MonaLisa
# Globals:
# siteConfiguration: Associative array of site configuration parameters in LDAP
# monalisaLDAPconfiguration: Associative array of MonaLisa configuration parameters in LDAP
# commonConfiguration: Associative array of JAliEn local configuration parameters
# Arguments:
# confDir: AliEn configuration directory
# ldapHostname: LDAP hostname
# ldapPort: LDAP port
# hostname: Site hostname
#############################################################################################
function start_ml(){
# Check if there is an existing instance
check_liveness_ml
if [[ $? == 0 ]]
then
echo "Existing instance of MonaLisa already running..." && exit 1
fi
# ======================== Config generation from LDAP ========================
confDir=$1
ldapHostname=$2
ldapPort=$3
hostname=$4
nl='
'
nl=${nl:0:1}
# Obtain site related configurations from LDAP
siteLDAPQuery=$(ldapsearch -x -LLL -h $ldapHostname -p $ldapPort -b "host=$hostname,ou=Config,ou=CERN,ou=Sites,o=alice,dc=cern,dc=ch" 2> /dev/null )
declare -A siteConfiguration
while IFS= read -r line
do
#Ignore empty lines and create an associative array from ldap configuration
if [[ ! -z $line ]]
then
key=$(echo "$line" | cut -d ":" -f 1 )
val=$(echo "$line" | cut -d ":" -f 2- | sed s/.//)
key=${key^^}
prev=${siteConfiguration[$key]}
prev=${prev:+$prev$nl}
siteConfiguration[$key]=$prev$val
fi
done <<< "$siteLDAPQuery"
# Obtain MonAlisa service related configurations from LDAP
siteName=${siteConfiguration[MONALISA]}
if [[ -z $siteName ]]
then
echo "LDAP Configuration for MonaLisa configuration not found. Please set it up and try again." && exit 1
fi
ldapBase="ou=MonaLisa,ou=Services,ou=CERN,ou=Sites,o=alice,dc=cern,dc=ch"
ldapFilter="(&(objectClass=AliEnMonaLisa)(name=$siteName))"
monalisaLDAPQuery=$(ldapsearch -x -LLL -h $ldapHostname -p $ldapPort -b $ldapBase "$ldapFilter" |
perl -p00e 's/\n //g' | envsubst
)
declare -A monalisaLDAPconfiguration
while IFS= read -r line
do
if [[ ! -z $line ]]
then
key=$(echo "$line" | cut -d ":" -f 1)
val=$(echo "$line" | cut -d ":" -f 2- | sed s/.//)
key=${key^^}
prev=${monalisaLDAPconfiguration[$key]}
prev=${prev:+$prev$nl}
monalisaLDAPconfiguration[$key]=$prev$val
fi
done <<< "$monalisaLDAPQuery"
baseLogDir=$(echo "${siteConfiguration[LOGDIR]}" | envsubst)
if [[ -z $baseLogDir ]]
then
baseLogDir="$HOME/ALICE/alien-logs"
echo "LDAP doesn't define a particular log location, using the default ($baseLogDir)"
fi
logDir="$baseLogDir/MonaLisa"
if ! mkdir -p $logDir
then
echo "Unable to create log directory at $logDir"
return 1
fi
setupLogFile="$logDir/ML-config-inputs.txt"
ceLogFile="$baseLogDir/CE.log.0"
envFile="$logDir/ml-env.sh"
commonConf="$confDir/version.properties"
mlEnv="$confDir/ml.env"
envCommand="/cvmfs/alice.cern.ch/bin/alienv printenv MonaLisa"
> $setupLogFile
write_log "========== VObox Config =========="
for x in "${!siteConfiguration[@]}"; do printf "[%s]=%s\n" "$x" "${siteConfiguration[$x]}" >> $setupLogFile ; done
write_log ""
write_log "========== MonaLisa Config =========="
for x in "${!monalisaLDAPconfiguration[@]}"; do printf "[%s]=%s\n" "$x" "${monalisaLDAPconfiguration[$x]}" >> $setupLogFile ; done
write_log ""
# Read MonaLisa config files
if [[ -f "$commonConf" ]]
then
declare -A commonConfiguration
while IFS= read -r line
do
if [[ ! $line = \#* ]] && [[ ! -z $line ]]
then
key=$(echo "$line" | cut -d "=" -f 1 )
val=$(echo "$line" | cut -d "=" -f 2- )
key=${key^^}
prev=${commonConfiguration[$key]}
prev=${prev:+$prev$nl}
commonConfiguration[$key]=$prev$val
fi
done < "$commonConf"
fi
write_log ""
write_log "========== Local Configuration start =========="
for x in "${!commonConfiguration[@]}"
do
printf "[%s]=%s\n" "$x" "${commonConfiguration[$x]}" >> $setupLogFile
done
write_log "========== Local Configuration end =========="
write_log ""