-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbackground-command-processor.sh
executable file
·192 lines (169 loc) · 4.89 KB
/
background-command-processor.sh
1
2
3
4
5
6
7
8
9
10
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
106
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
#!/bin/bash
# Executes commands in file placed by some other process on shared
# NFS. The result is placed in the same file. The format of the file is:
# {command text}
# EOCommand
# {command result text}
# EOResult
# Information is only appended to the file. Polling is done on the
# EOCommand and EOResult tags to wait for complete info.
initialize-teacher-notebooks()
{
teacherid="$1"
shift
if ! [ -d "/home/$teacherid" ]; then
echo "No teacher with id=$studentid"
return
fi
studentid="$*"
if [ "$studentid" != "$teacherid" ]; then
echo "Required first parameter should be the teacher id (i.e. $teacherid)"
return
fi
echo "Deleting existing notebooks of $studentid."
rm "/home/$studentid"/* -fr # TODO: rethink this
echo "Initializing notebooks for $studentid."
/srv/adapt-notebooks-for-user.sh "$studentid"
echo "Done."
}
clear-notebooks()
{
teacherid="$1"
shift
if ! [ -d "/home/$teacherid" ]; then
echo "No teacher with id=$studentid"
return
fi
for studentid in "$@"; do
if ! [ -d "/home/$studentid" ]; then
echo "No student with id=$studentid"
continue
fi
echo "Deleting existing notebooks of $studentid."
rm "/home/$studentid"/* -fr # TODO: rethink this
echo "Done."
done
}
distribute-notebooks()
{
teacherid="$1"
shift
if ! [ -d "/home/$teacherid" ]; then
echo "No teacher with id=$teacherid"
return
fi
for studentid in "$@"; do
if ! [ -d "/home/$studentid" ]; then
echo "No student with id=$studentid"
continue
fi
echo "Deleting existing notebooks of $studentid."
rm "/home/$studentid"/* -fr # TODO: rethink this
# Copy teacher notebooks to student container via NFS:
echo "Copying notebooks..."
cp -a "/home/$teacherid"/* "/home/$studentid/"
chown -R "$studentid:$studentid" "/home/$studentid/"
# Also make read-only copy:
echo "Creating role_model directory..."
rm -fr "/home/$studentid/role_model"
ln -sf "/home/.others/$teacherid" "/home/$studentid/role_model"
echo "Done."
done
}
process-one-command()
{
set -x
justcmd="${cmdtext/EOCommand/}"
case "$justcmd" in
fortesting*)
bash <<<"${justcmd/fortesting/}" >>"$cmdfile"
;;
distribute-notebooks*)
read stripcmd teacherid sids <<<"$justcmd"
distribute-notebooks $teacherid $sids >>"$cmdfile"
;;
clear-notebooks*)
read stripcmd teacherid sids <<<"$justcmd"
clear-notebooks $teacherid $sids >>"$cmdfile"
;;
initialize-teacher-notebooks*)
read stripcmd teacherid sids <<<"$justcmd"
initialize-teacher-notebooks $teacherid $sids >>"$cmdfile"
;;
esac
echo EOResult >>"$cmdfile"
set +x
}
scan-for-commands()
{
shopt -s nullglob
for cmdfile in /home/*/.commands/*-queued; do
cmdtext="$(< "$cmdfile")"
[[ "$cmdtext" == *EOCommand* ]] || continue # skip if client has not finished writing
[[ "$cmdtext" == *EOResult* ]] && continue # skip if already processed
process-one-command
done
}
students-home-dir-hack()
{
# This is probably temporary and will be moved/rewritten when the design
# stabilizes.
# Make sure user directories have the symbolic links
shopt -s nullglob
for udir in /mnt/nfs/home/*; do
userid="${udir##*/}"
# skip known administrators and the teacher
[ "$userid" = "potter" ] && continue
[ "$userid" = "ubuntu" ] && continue
[ -f "/jupyter/admin/$userid" ] && continue
for link in textbook tools info; do
if ! [ -h "$udir/$link" ]; then
ln -s "/jupyter/admin/$link" "$udir/$link" 2>/dev/null
chown -h "$userid:$userid" "$udir/$link" 2>/dev/null
fi
done
for dir in private_info; do
if ! [ -d "$udir/$dir" ]; then
mkdir -p "$udir/$dir" 2>/dev/null
chown -h "$userid:$userid" "$udir/$dir" 2>/dev/null
fi
done
ipycfg="$udir/.ipython/profile_default/ipython_config.py"
[ -f "$ipycfg" ] || {
mkdir -p "${ipycfg%/*}"
echo "c.InteractiveShellApp.matplotlib = 'inline'" >>"$ipycfg"
chown -R "$userid:$userid" "$udir/.ipython"
}
# Hopefully this next one will be very temporary:
# Make user dirs world writable so teacher can copy in notebooks with
# simple unix commands. Do this every time so teacher can also
# copy out new files that the student might put in.
# TODO: avoid this, using groups, perhaps.
(
# Put in exception to skip ssh related things that should not be world readable/writable
# and also skip symbol links.
if cd "$udir"; then
shopt -s nullglob
shopt -s dotglob
for p in * ; do
[ -L "$p" ] && continue
[ "$p" = .ssh ] && continue
[[ "$p" = *key* ]] && continue
chmod -R a+wr "$p"
done
fi
)
# the directory itself needs to be writable or else the jupyter server container does not launch
# Note: no "-R" here
chmod a+wr "$udir"
done
}
if [ "$(whoami)" != root ]; then
echo "Must be root" 1>&2
exit 1
fi
while true; do
scan-for-commands
students-home-dir-hack
sleep 5
done