Something went wrong on our end
get-config 10.70 KiB
#!/bin/bash
API_BASE_URL=https://labmanager-api.edu-al.unipmn.it/api/1.0
# curl uses an increasing delay. 5 retries are tried in about 30 seconds,
# so it's too quick for us. I increased it to 7, which is about 2 minutes.
# Note: the same variable was also used in the `retry` function.
MAX_RETRY=7
RETRY_DELAY=5
NORMAL_CONFIG_NAME=normale
DEBUG=0
# Sysadmin can override local vars here:
CONFFILE=/etc/sysconfig/labmanager
# Load configuration override if present:
if [ -e ${CONFFILE} ]; then
. ${CONFFILE}
fi
if [[ "-d" == "$2" ]]; then
DEBUG=1
fi
# execute a task and on fail execute it again MAX_RETRY times every RETRY_DELAY seconds
function retry {
local n=1
local max=$MAX_RETRY
local delay=$RETRY_DELAY
while true; do
"$@"
if [[ $? == 0 ]]; then
break
else
if [[ $n -lt $max ]]; then
((n++))
echo "Failed. Attempt $n/$max..." >&2
sleep $delay;
else
echo "Command failed after $n attempts." >&2
exit 1
fi
fi
done
}
function debug() {
if [[ "${DEBUG}" == 1 ]]; then
echo >&2 "$@"
fi
}
# authenticate and get the token
function getTokenJSON() {
# store the whole response with the status at the end
HTTP_RESPONSE=$(curl --retry-all-errors --retry ${MAX_RETRY} -s -k -w "HTTPSTATUS:%{http_code}" --max-time 10 -X POST -H "Content-Type: application/json" -d "{\"login\":\"guest\",\"pwd\":\"\"}" ${API_BASE_URL}/login)
ret=$?
if [[ $ret != 0 ]]; then
echo "Invalid authentication request!"
return $ret
fi
# extract the status
HTTP_STATUS=$(echo "$HTTP_RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
# check the status
if [[ $HTTP_STATUS -ne 200 ]]; then
echo "Authentication failed!"
return 1
else
# extract the body
HTTP_BODY=$(echo "$HTTP_RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
echo $HTTP_BODY
fi
}
# extract a value from a JSON structure
function jsonValue() {
KEY=$1
num=$2
awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/\042'$KEY'\042/){print $(i+1)}}}' | tr -d '"' | sed -n ${num}p
}
stop() {
if [[ "$1" == "bootstop" ]]; then
echo "STOP esame-get-config-boot"
else
echo "STOP esame-get-config"
fi
}
# get configuration from WS
getConfigVars() {
echo "Authenticating to WS..."
TOKEN_JSON=`getTokenJSON`
if [[ "$TOKEN_JSON" == "" ]]; then
return 2
fi
TOKEN=`echo ${TOKEN_JSON} | jsonValue token 1`
MACHINE_NAME=`hostname`
echo "Getting machine configuration..."
MACHINE_JSON=`/usr/bin/curl --retry-all-errors --retry ${MAX_RETRY} -s -k --max-time 10 -H "Authorization: Bearer ${TOKEN}" -X GET ${API_BASE_URL}/machines/name/${MACHINE_NAME}`
MACHINE_ID=`echo $MACHINE_JSON | jsonValue id 1`
MACHINE_CONFIGS_ID=`echo $MACHINE_JSON | jsonValue configs_id 1`
CONFIG_NAME=`echo $MACHINE_JSON | jsonValue name 2`
if [[ "$CONFIG_NAME" == "" ]]; then
echo "Error fetching machine configuration!"
return 1
fi
MACHINE_CONFIGS_ID_PREV=''
CONFIG_NAME_PREV=''
if [[ -e /local/config_name ]]
then
CONFIG_NAME_PREV=`cat /local/config_name`
fi
}
getConfigFile() {
echo "Downloading machine config file..."
# get configuration file
if [[ "${MACHINE_ID}" == "" ]]; then
echo "Error downloading config file (machine_id empty, maybe it is not in LabManager's DB)"
return 1
fi
HTTP_STATUS=`/usr/bin/curl --retry-all-errors --retry ${MAX_RETRY} -s -k -w "%{http_code}" -o /local/esame-machine.conf --max-time 10 --header "Authorization: Bearer ${TOKEN}" -X GET ${API_BASE_URL}/machines/${MACHINE_ID}/configfile`
if [[ $HTTP_STATUS -ne 200 ]]
then
echo "Error downloading config file (http_status=$HTTP_STATUS)"
return 1
else
echo "Downloaded config file (http_status=$HTTP_STATUS)"
fi
}
getIpConfigFile() {
echo "Downloading machine iptables config file..."
# get ipconfig file
HTTP_STATUS=`/usr/bin/curl --retry-all-errors --retry ${MAX_RETRY} -s -k -w "%{http_code}" -o /local/iptables --max-time 10 --header "Authorization: Bearer ${TOKEN}" -X GET ${API_BASE_URL}/machines/${MACHINE_ID}/ipconfigfile`
if [[ $HTTP_STATUS -ne 200 ]]
then
echo "Error downloading iptables config file (http_status=$HTTP_STATUS)"
return 1
else
echo "Downloaded iptables config file (http_status=$HTTP_STATUS)"
fi
}
updateCurrentConfigId() {
# Update this machine's current config id
HTTP_STATUS=`/usr/bin/curl --retry-all-errors --retry ${MAX_RETRY} -s -k -w "%{http_code}" -o /dev/null --max-time 10 -H "Content-Type: application/json" -H "Authorization: Bearer ${TOKEN}" \
-X PUT -d "{\"current_configs_id\":\"$MACHINE_CONFIGS_ID\"}" ${API_BASE_URL}/machines/${MACHINE_ID}/currentconfig`
if [[ $HTTP_STATUS -ne 200 ]]
then
echo "Error updating current config (http_status=$HTTP_STATUS)"
exit 1
else
echo "Updated current config (http_status=$HTTP_STATUS)"
fi
}
function getConfig() {
getConfigVars
while [[ $? != 0 ]]; do
echo "Error fetching machine info!"
echo "If this is a new machine, did you add it into labmanager-admin?"
sleep 30;
getConfigVars
done
# back config files up
cp -f /local/esame-machine.conf /local/esame-machine.conf.prev >/dev/null 2>&1
cp -f /local/iptables /local/iptables.prev >/dev/null 2>&1
getConfigFile
if [[ $? != 0 ]]; then
echo "Error fetching machine config file!"
return 1
fi
getIpConfigFile
if [[ $? != 0 ]]; then
echo "Error fetching machine iptables file!"
return 1
fi
return 0
}
start() {
if [[ "$1" == "boot" ]]; then
echo "START esame-get-config-boot"
else
echo "START esame-get-config"
fi
getConfig
RESULT=$?
#echo "TOKEN_JSON: $TOKEN_JSON"
#echo "TOKEN: $TOKEN"
#echo "MACHINE_NAME: $MACHINE_NAME"
#echo "MACHINE_JSON: $MACHINE_JSON"
#echo "MACHINE_ID: $MACHINE_ID"
#echo "MACHINE_CONFIGS_ID: $MACHINE_CONFIGS_ID"
#echo "MACHINE_CONFIGS_ID_PREV: $MACHINE_CONFIGS_ID_PREV"
if [[ -n "$CONFIG_NAME" ]]; then
echo "Configuration: $CONFIG_NAME"
fi
if [[ $RESULT != 0 ]]; then
if [[ "$1" == "boot" ]]; then
echo "Fatal error(s): aborting esame and switching machine to normal state..."
# reset and remove exam configuration files
echo "$NORMAL_CONFIG_NAME" > /local/config_name
rm /local/esame-machine.conf >/dev/null 2>&1
rm /local/esame-machine.conf.prev >/dev/null 2>&1
rm /local/iptables >/dev/null 2>&1
rm /local/iptables.prev >/dev/null 2>&1
rm /local/mk-homedir >/dev/null 2>&1
/usr/bin/systemctl start graphical.target && exit 0
fi
echo "Fatal error(s): missing or wrong web service reply, abort."
exit 1
fi
# configuration profile is changed
if [[ "$CONFIG_NAME" != "$CONFIG_NAME_PREV" ]]
then
# update config_name file
echo "${CONFIG_NAME}" > /local/config_name
# no exam, set normal target
if [[ "$CONFIG_NAME" == "$NORMAL_CONFIG_NAME" ]]
then
# stop some services to revert system files
rm /local/esame-machine.conf >/dev/null 2>&1
rm /local/esame-machine.conf.prev >/dev/null 2>&1
rm /local/iptables >/dev/null 2>&1
rm /local/iptables.prev >/dev/null 2>&1
rm /local/mk-homedir >/dev/null 2>&1
echo "Normal!"
#systemctl isolate graphical && exit 0
/usr/bin/systemctl reboot
#--force
else
echo "Exam!"
touch /local/mk-homedir
#systemctl isolate esame.target && exit 0
/usr/bin/systemctl reboot
#--force
fi
else
# at boot time choose the correct target
if [[ "$1" == "boot" ]]
then
# we have just rebooted, update the current configuration via web service
updateCurrentConfigId
case "$CONFIG_NAME" in
$NORMAL_CONFIG_NAME) # normal
systemctl start graphical.target && exit 0
;;
'kiosk-dir' | 'kiosk-dir-esami' | 'kiosk-escher' | 'kiosk-freebrowsing' | 'kiosk-teco') # kiosk mode
systemctl start esamekiosk.target && exit 0
;;
'show') # show mode, an exam mode with no limitations on USB ports and network
systemctl start esameshow.target && exit 0
;;
*) # all full desktop exams
systemctl start esame.target && exit 0
;;
esac
fi
fi
# Runtime parameters
if [[ "$CONFIG_NAME" != "$NORMAL_CONFIG_NAME" ]]
then
# check if parameters are changed
cmp --silent /local/esame-machine.conf /local/esame-machine.conf.prev
if [[ $? -ne 0 ]]
then
/usr/bin/systemctl daemon-reload
echo "Configuration parameters changed: restart some services... "
# restart some exam services
#echo -n "USB..."
#/usr/bin/systemctl restart esame-usb
#echo " done."
KIOSK_URL_CHANGED=$(diff /local/esame-machine.conf /local/esame-machine.conf.prev | grep ESAME_KIOSK_URL -c)
if [[ $KIOSK_URL_CHANGED -ne 0 ]]
then
echo -n "Firefox Home..."
FIREFOX_PID=$(pgrep firefox)
if [[ "${FIREFOX_PID}" != "" ]]
then
FIREFOX_USER=$(ps -o user= -p ${FIREFOX_PID})
rm -f /local/${FIREFOX_USER}/.mozilla/firefox/44bu2eyb.default/lock
pkill firefox
sleep 2
/usr/bin/systemctl restart esame-firefox-home
echo " done."
# no way to restart firefox, I must miss something :(
#echo -n "Restarting Firefox..."
#su - ${FIREFOX_USER} -c 'nohup /usr/bin/firefox --display=:0.0 &'
#echo " done."
else
/usr/bin/systemctl restart esame-firefox-home
echo " done."
fi
fi
echo
echo "All done."
fi
fi
}
args=("$@")
case "$1" in
'bootstart')
start "boot"
;;
'bootstop')
stop "boot"
;;
'start')
start
;;
'stop')
stop
;;
'restart')
stop
start
;;
*)
echo "Usage: $0 { bootstart | bootstop | start | stop | restart }";
exit 1;
;;
esac
exit 0