Newer
Older
#!/bin/bash
API_BASE_URL=https://labmanager-api.edu-al.unipmn.it/api/1.0
MAX_RETRY=5
RETRY_DELAY=5
NORMAL_CONFIG_NAME=normale
DEBUG=0
# Sysadmin can override local vars here:
CONFFILE=/etc/default/labmanager
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# 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 -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=`retry getTokenJSON`
if [[ "$TOKEN_JSON" == "" ]]; then
return 2
fi
TOKEN=`echo ${TOKEN_JSON} | jsonValue token 1`
MACHINE_NAME=`hostname`
echo "Getting machine configuration..."
MACHINE_JSON=`retry /usr/bin/curl -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`
EXAM_ID=`echo $MACHINE_JSON | jsonValue examid 1`
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
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=`retry /usr/bin/curl -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=`retry /usr/bin/curl -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 -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

Alberto LIVIO BECCARIA
committed
# any error?
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
rm /local/examid >/dev/null 2>&1
/usr/bin/systemctl start graphical && exit 0
fi
echo "Fatal error(s): missing or wrong web service reply, abort."
exit 1
fi

Alberto LIVIO BECCARIA
committed
# the PC is already up and running
if [[ "$1" != "boot" ]]; then
# is configuration profile changed?
if [[ "$CONFIG_NAME" != "$CONFIG_NAME_PREV" ]]; then
# reboot => normal
if [[ "$CONFIG_NAME" == "$NORMAL_CONFIG_NAME" ]]; then
echo "Reboot to Normal!"
# reboot => exam
else
echo "Reboot to Exam (exam id: ${EXAM_ID})"

Alberto LIVIO BECCARIA
committed
fi
/usr/bin/systemctl reboot
fi
else

Alberto LIVIO BECCARIA
committed
# at boot time
#if [[ "$CONFIG_NAME" != "$CONFIG_NAME_PREV" ]]; then

Alberto LIVIO BECCARIA
committed
# update config_name file
echo "${CONFIG_NAME}" > /local/config_name
# no exam
if [[ "$CONFIG_NAME" == "$NORMAL_CONFIG_NAME" ]]; then
# remove some files used by exam mode
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
rm /local/examid >/dev/null 2>&1

Alberto LIVIO BECCARIA
committed
else
# if the examid of the session before the boot is different,
# then clean the exam user home (if the profile requires it)
EXAM_ID_PREV=""
# if the exam is already started, get examid from file
if [[ -f /local/examid ]]; then
EXAM_ID_PREV=`cat /local/examid`
# otherwise let's create the file with the current examid
else
echo "${EXAM_ID}" > /local/examid
fi
# different examid?
if [[ ${EXAM_ID} != ${EXAM_ID_PREV} ]]; then
touch /local/mk-homedir
fi

Alberto LIVIO BECCARIA
committed
fi
#fi

Alberto LIVIO BECCARIA
committed
# choose the correct target
# we have just booted/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

Alberto LIVIO BECCARIA
committed
# 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})

Alberto LIVIO BECCARIA
committed
rm -f /local/${FIREFOX_USER}/.mozilla/firefox/n3bac2sw.default-release/lock
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
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