-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjnr.sh
executable file
·297 lines (260 loc) · 8.03 KB
/
jnr.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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
#!/bin/bash
jnr_path="$HOME/.RemoteJupyter"
filename="$jnr_path/status.txt"
tmp_filename="$jnr_path/status.tmp"
tmp_filename1="$jnr_path/tmp1.tmp"
tmp_filename2="$jnr_path/tmp2.tmp"
have_to_kill=false
have_to_spawn=true
refresh=false
restore=false
port=false
hostname=false
show_list=false
# setup log file if it doesn't exist
if [[ ! -f "$filename" ]] ; then
echo "port PID Hostname" > "$filename"
fi
# check if there are arguments
if [[ $# -eq 0 ]] ; then
have_to_spawn=false
# retrieve alias from setup file
while IFS='' read -r line ; do
IFS='~' read jnr_alias _rest <<< "$line"
done < "$jnr_path/setup.txt"
echo "****************************************************************"
echo "* Remote Jupyter *"
echo "* *"
echo "* a helper to run jupyter notebooks and labs over ssh *"
echo "* https://github.com/AlessandroLovo/RemoteJupyter *"
echo "****************************************************************"
echo "================================================"
echo "Usage:"
echo "To spawn a new process:"
echo " $jnr_alias -h <[user@]host> [-p <port> (default 8888)]"
echo "To kill a process:"
echo " $jnr_alias -kh <[user@]host> or $jnr_alias -kp <port>"
echo "To view the list of running processes:"
echo " $jnr_alias -v"
echo "To refresh [and view] the list of processes (in case some died on their own):"
echo " $jnr_alias -r[v]"
echo "To restore all dead processes:"
echo " $jnr_alias -R"
echo "================================================"
echo
echo "-------------------"
echo "General Wrokflow:"
echo "1. (local machine): spawn a new process as shown above"
echo "2. The terminal automatically moves to the remote machine"
echo "3. (remote machine): start a jupyter notebook or lab with the aliases you set up when configuring RemoteJupyter on the remote machine"
echo " for example with"
echo " jnr 8888"
echo " which launches a jupyter notebook on port 8888"
echo "4. (remote machine): copy the url that contains 'localhost'"
echo "5. (local machine): open a browser and paste the url"
echo "6. Do your work"
echo "7. (remote machine): Stop the notebook/lab by double tapping ctrl-c"
echo "[8. (remote machine): exit]"
echo "9. (local machine): kill the port forwarding process as shown above"
echo "-------------------"
exit 0
fi
# parse arguments
while getopts ":kh:p:vrR" opt; do
case $opt in
v) # show_what="$OPTARG"
show_list=true
have_to_spawn=false
;;
r) refresh=true
;;
R) restore=true
;;
k) have_to_kill=true
have_to_spawn=false
;;
h) hostname="$OPTARG"
if [[ "$have_to_spawn" == true && "$port" == false ]] ; then
port=8888
fi
;;
p) port="$OPTARG"
;;
\?) echo "Invalid option -$OPTARG" >&2
exit 1
;;
esac
done
# refresh
if [[ "$refresh" == true ]] ; then
while IFS='' read -r line ; do
IFS=' ' read _port _pid _hostname <<< "$line"
remove=false
if [[ "$_port" != "port" ]] ; then
ps ax | grep "ssh -NfL localhost:$_port:" > "$tmp_filename1"
wc -l "$tmp_filename1" > "$tmp_filename2" # read lenght of file tmp_filename1
while IFS='' read -r line2 ; do
IFS=' ' read _linecount _rest <<< "$line2"
done < "$tmp_filename2"
rm "$tmp_filename1"
rm "$tmp_filename2"
if [[ $_linecount -le 1 ]] ; then # tmp_filename1 contains only one line: the port forwarding has died
remove=true
fi
fi
# remove the process
if [[ "$remove" == true ]] ; then
echo
echo "Removing dead process on port $_port: PID $_pid, Hostname: $_hostname"
echo
else
echo "$line" >> "$tmp_filename"
fi
done < "$filename"
mv "$tmp_filename" "$filename"
fi
# restore dead process
if [[ "$restore" == true ]] ; then
count=0
while IFS='' read -r line ; do
IFS=' ' read _port _pid _hostname <<< "$line"
remove=false
if [[ "$_port" != "port" ]] ; then
ps ax | grep "ssh -NfL localhost:$_port:" > "$tmp_filename1"
wc -l "$tmp_filename1" > "$tmp_filename2" # read lenght of file tmp_filename1
while IFS='' read -r line2 ; do
IFS=' ' read _linecount _rest <<< "$line2"
done < "$tmp_filename2"
rm "$tmp_filename1"
rm "$tmp_filename2"
if [[ $_linecount -le 1 ]] ; then # tmp_filename1 contains only one line: the port forwarding has died
remove=true
fi
fi
# remove the process
if [[ "$remove" == true ]] ; then
count=$(( count + 1 ))
echo
echo "Restoring dead process on port $_port: old PID $_pid, Hostname: $_hostname"
# spawn port forwarding and save its PID
ssh -NfL localhost:$_port:localhost:$_port $_hostname
# get new process PID and write to file
ps ax | grep "ssh -NfL localhost:$_port:" | head -n 1 > "$tmp_filename1"
while IFS='' read -r line ; do
IFS=' ' read _pid _rest <<< "$line"
done < "$tmp_filename1"
echo "$_port $_pid $_hostname" >> "$tmp_filename"
rm "$tmp_filename1"
echo "New PID: $_pid"
echo
else
echo "$line" >> "$tmp_filename"
fi
done < "$filename"
mv "$tmp_filename" "$filename"
if [[ $count == 0 ]] ; then
echo
echo "No dead processes to restore"
echo
else
echo
echo "Connecting to host $_hostname"
echo
ssh $_hostname
fi
fi
# show list of running processes
if [[ "$show_list" == true ]] ; then
echo
# check if there are active processes
wc -l "$filename" > "$tmp_filename" # write to tmp_filename the length of filename
while IFS='' read -r line ; do
IFS=' ' read _linecount _rest <<< "$line"
done < "$tmp_filename"
rm "$tmp_filename"
if [[ $_linecount -le 1 ]] ; then
echo "No active processes"
echo
exit 0
fi
while IFS='' read -r line ; do
echo $line
done < "$filename"
echo
exit 0
fi
# kill port forwarding process
if [[ "$have_to_kill" == true ]] ; then
rm -f "$tmp_filename"
nothing_to_kill=true
# read status file to see if there is a process to kill
while IFS='' read -r line ; do
IFS=' ' read _port _pid _hostname <<< "$line"
do_kill=false
# search matching for port or hostname
if [[ "$_port" != "port" ]] ; then # not the first line
if [[ "$port" != false ]] ; then # \/ skip the first line
if [[ "$_port" == "$port" || "$port" == "all" ]] ; then
do_kill=true
fi
elif [[ "$hostname" != false ]] ; then # \/ skip the first line
if [[ "$_hostname" == "$hostname" || "$hostname" == "all" ]] ; then
do_kill=true
fi
else
echo "Use -kh <hostname> or -kp <port>"
exit 1
fi
fi
# kill the process
if [[ "$do_kill" == true ]] ; then
nothing_to_kill=false
echo
echo "Killing process on port $_port: PID $_pid, Hostname: $_hostname"
echo
kill "$_pid"
else
echo "$line" >> "$tmp_filename"
fi
done < "$filename"
mv "$tmp_filename" "$filename"
# warn the user if no process is found
if [ "$nothing_to_kill" == true ] ; then
if [[ ! "$hostname" == false ]] ; then
echo "No active process on host $hostname"
elif [[ "$port" != false ]] ; then
echo "No active process on port $port"
fi
exit 1
fi
exit 0
fi
# spawn a port forwarding and connect to the host
if [[ "$have_to_spawn" == true && "$port" != false ]] ; then
# check if port or hostname are already busy
while IFS='' read -r line ; do
IFS=' ' read _port _pid _hostname <<< "$line"
if [[ "$_port" == "$port" ]] ; then
echo "Port $port is already busy with host $hostname"
exit 1
elif [[ "$_hostname" == "$hostname" ]] ; then
echo "WARNING: You are already connected to host $hostname on port $_port"
fi
done < "$filename"
#spawn the new process
echo
echo "Spawning process on port $port"
echo
# spawn port forwarding and save its PID
ssh -NfL localhost:$port:localhost:$port $hostname
# get process PID and write to file
ps ax | grep "ssh -NfL localhost:$port:" | head -n 1 > "$tmp_filename"
while IFS='' read -r line ; do
IFS=' ' read _pid _rest <<< "$line"
done < "$tmp_filename"
echo "$port $_pid $hostname" >> "$filename"
rm "$tmp_filename"
# ssh to the host
ssh $hostname
exit 0
fi