Skip to content

Instantly share code, notes, and snippets.

@activeeon-bot
Last active November 15, 2023 19:03
Show Gist options
  • Save activeeon-bot/dcbe0758c9da6bdb3f4a5dfb7e87af0f to your computer and use it in GitHub Desktop.
Save activeeon-bot/dcbe0758c9da6bdb3f4a5dfb7e87af0f to your computer and use it in GitHub Desktop.
#!/bin/bash
# This script is used as internalCustomStartupScript to setup the VM of the Azure Scale Set.
# This setup is for CENTOS 7, and involves:
# - setting up Docker and Docker-Compose
# - setting up ProActive Node service with PNP
# - starting the ProActive Node service
# - install and setup the required packages/libs for the various script engine
# mount /tmp folder
systemctl start tmp.mount
# while ! [ -f /tmp/go ];
# do
# sleep 1
# done
# Be sure the variables below is OK, depending on your context
# The URL from where to retrieve the JRE tarball
JRE_TARBALL_URL="https://s3.amazonaws.com/ci-materials/Latest_jre/jre-8u382b05-linux-x64.tar.gz"
set -x
set -e
# Prerequisites: Install Docker and Docker Compose, add 'activeeon' user to docker group
# yum install -y yum-utils \
# device-mapper-persistent-data \
# lvm2
# yum-config-manager \
# --add-repo \
# https://download.docker.com/linux/rhel/docker-ce.repo
# yum install -y docker-ce docker-ce-cli containerd.io
# groupadd docker
# usermod -aG docker activeeon
# curl -L "https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
###############################
# Downloads and install ProActive Node as a Systemd service
###############################
mkdir -p /opt/proactive
mkdir -p /tmp/node
cd /tmp/node
# Install dependencies
yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
yum install -y jq
# Install Java 8
# [MODIFY] modify if needed the URL to get the JRE
wget --no-clobber $JRE_TARBALL_URL
tar zxf jre-8u382b05-linux-x64.tar.gz
ln -s /tmp/node/jre1.8.0_382b05 /tmp/node/java
# making Java 8 available system-wide
update-alternatives --install /usr/bin/java java /tmp/node/java/bin/java 1
update-alternatives --set java /tmp/node/java/bin/java
# Retrieve NS config from CustomData
if [ -f /var/lib/waagent/CustomData ]; then
JSONCONFIG=$(base64 -d /var/lib/waagent/CustomData)
elif [ -f /var/lib/cloud/instance/user-data.txt ]; then
JSONCONFIG=$(cat /var/lib/cloud/instance/user-data.txt)
elif [ -f /var/lib/waagent/ovf-env.xml ]; then
JSONCONFIG=$(grep -oP '<ns1:CustomData>\K.*?(?=</ns1:CustomData>)' /var/lib/waagent/ovf-env.xml | base64 -d)
else
JSONCONFIG=""
echo "Custom data not found in the system, aborting"
exit 1
fi
echo "Json Config:"
echo "$JSONCONFIG"
export RMURL=$(echo $JSONCONFIG | jq '.rmurl' -r)
export CREDVALUE=$(echo $JSONCONFIG | jq '.credentials' -r)
export NODESOURCENAME=$(echo $JSONCONFIG | jq '.nodesourcename' -r)
export STORAGEACCOUNT=$(echo $JSONCONFIG | jq '.storageaccount' -r)
export SASKEY=$(echo $JSONCONFIG | jq '.saskey' -r)
export USERCUSTOMSCRIPTURL=$(echo $JSONCONFIG | jq '.usercustomscripturl' -r)
export EXTERNALSTORAGEACCOUNT=$(echo $JSONCONFIG | jq '.externalstorageaccount' -r)
export JVMPARAMETERS=$(echo $JSONCONFIG | jq '.jvmparameters' -r)
export NODEPRECOMMAND=$(echo $JSONCONFIG | jq '.nodeprecommand' -r | sed -e 's/\\\\n/\n/g')
###############################
# Bash function used by the VM to send debug messages to the dedicated Azure Queue
###############################
function debug {
DEBUGCONTENT=`echo $1 | base64 -w 0`
DEBUGMESSAGE="<QueueMessage><MessageText>$DEBUGCONTENT</MessageText></QueueMessage>"
curl -X POST -d "$DEBUGMESSAGE" "https://$STORAGEACCOUNT.queue.core.windows.net/debug/messages?$SASKEY"
}
# debug
debug "$HOSTNAME INFO: CustomData read properly (as I can write this message)"
# Override custom script if specified
if [ ! -z "$USERCUSTOMSCRIPTURL" ]; then
curl -X GET "$USERCUSTOMSCRIPTURL" > user_custom_script.sh
chmod +x user_custom_script.sh
./user_custom_script.sh >> user_script_stdout 2>>user_script_stderr
if [ $? -ne 0 ]; then
debug "$HOSTNAME FATAL: User custom script exited with error: $?"
fi
fi
# Getting node.jar
curl -X GET "https://$STORAGEACCOUNT.blob.core.windows.net/nodefiles/node.jar?$SASKEY" > node.jar
# Change ownership to /tmp/node
chown -R activeeon:activeeon /tmp/node
# debug
NOW=$(date)
debug "$HOSTNAME INFO: Start filling the Table on $NOW"
start_time=$(date +%s)
# Max time to try de delete msg from queue
timeout_minutes=30
isValidMessage="false"
while [[ "$isValidMessage" == "false" ]];
do
# Read Azure Queue to get node name Deletion is performed on NS Side when nodes are properly registered
msg=$(curl "https://$STORAGEACCOUNT.queue.core.windows.net/nodeconfig/messages?visibilitytimeout=300&$SASKEY")
JSONMSG=`echo $msg | grep -oP '<MessageText>\K[^<]+' | base64 -d`
msgId=`echo $msg | grep -oP '<MessageId>\K[^<]+'`
popReceipt=`echo $msg | grep -oP '<PopReceipt>\K[^<]+'`
# Encode popReceipt query param
popReceipt=$(echo $popReceipt | jq -R -r @uri)
dequeueCount=`echo $msg | grep -oP '<DequeueCount>\K[^<]+'`
NODEBASENAME=`echo $JSONMSG | jq '.nodebasename' -r`
NODEINSTANCES=`echo $JSONMSG | jq '.nodeinstances' -r`
if [ -z "$NODEBASENAME" ]; then
echo "$HOSTNAME ERROR: Unable to retrieve node configuration from 'nodeconfig' queue message $msg"
# Check if 30 minutes have passed
current_time=$(date +%s)
elapsed_time=$((current_time - start_time))
if [ "$elapsed_time" -ge $((timeout_minutes * 60)) ]; then
echo "Timeout of $timeout_minutes minutes reached for azure queue deletion."
exit 5
fi
echo "Retrying..."
sleep 10
continue
#halt #sleep 9999 #exit -1
fi
# Try to delete message from queue
URL="https://${STORAGEACCOUNT}.queue.core.windows.net/nodeconfig/messages/${msgId}?popreceipt=${popReceipt}&${SASKEY}"
delete_response=$(curl -w "%{http_code}" -X DELETE $URL)
echo "$delete_response"
http_code=$(tail -n1 <<< "$delete_response")
if [[ $http_code -ne 204 ]];
then
echo "$HOSTNAME WARN: Could not delete Azure message from queue"
fi
if [[ "$dequeueCount" == "1" ]];
then
isValidMessage="true"
fi
done
# Retrieve instance metadata
INSTANCE_NAME=$(curl -H Metadata:true "http://169.254.169.254/metadata/instance/compute?api-version=2017-12-01" | jq .name | sed 's/"//g')
INSTANCE_ID=$(echo -n "$INSTANCE_NAME" | rev | cut -d'_' -f1 | rev)
# Update Azure Table
ENTITY="{'PartitionKey':'$HOSTNAME','RowKey':'$NODEBASENAME', 'NodesCount':'$NODEINSTANCES', 'InstanceId': '$INSTANCE_ID'}"
curl -H "Content-Type: application/json" -d "$ENTITY" -X POST "https://$STORAGEACCOUNT.table.core.windows.net/nodesperhost?$SASKEY"
if [ $? -ne 0 ]; then
debug "$HOSTNAME FATAL: Unable to register the host into 'nodesperhost' table"
exit 3
fi
NOW=$(date)
debug "$HOSTNAME INFO: Terminated to fill the Table on $NOW"
# Install py4j
# curl -O https://bootstrap.pypa.io/get-pip.py
# python2 get-pip.py
# pip install py4j
# pip install numpy
# Generate the ExecStartPre commands if they were provided by the user
EXECSTARTPRE=''
if [ ! -z "$NODEPRECOMMAND" ]; then
while read -r line; do
EXECSTARTPRE=$EXECSTARTPRE`echo "ExecStartPre=$line"`$'\n'
done <<< "$NODEPRECOMMAND"
fi
# Generate proactive-node systemd service unit file
cat > /etc/systemd/system/proactive-node.service <<EOL
[Unit]
After=sshd.service
[Service]
WorkingDirectory=/tmp/node
EnvironmentFile=-/etc/environment
${EXECSTARTPRE}ExecStart=/usr/bin/java -jar /tmp/node/node.jar ${JVMPARAMETERS} -Dpython.path=/tmp/node/lib/jython-standalone-2.7.0.jar/Lib -v ${CREDVALUE} -w ${NODEINSTANCES} -r ${RMURL} -n ${NODEBASENAME} -s ${NODESOURCENAME}
User=activeeon
[Install]
WantedBy=default.target
EOL
chmod 664 /etc/systemd/system/proactive-node.service
# Install ProActive Node Service
systemctl daemon-reload
systemctl enable proactive-node.service
sysctl fs.inotify.max_user_watches=524288 # Support for large number of nodes
# Debug message posted on debug queue
IP=$(hostname -i)
debug "$HOSTNAME INFO: Service is ready to start: $IP , $NODEBASENAME , $NODEINSTANCES"
###############################
###############################
# Let's start the ProActive node service
###############################
systemctl start proactive-node.service
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment