-
Notifications
You must be signed in to change notification settings - Fork 2
/
notebook.py
executable file
·71 lines (60 loc) · 2.44 KB
/
notebook.py
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
#!/usr/bin/env python3
import socket, errno
import os
import sys
import time
import re
from contextlib import closing
from subprocess import Popen, PIPE
def find_free_port():
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 0))
return s.getsockname()[1]
ports = [str(find_free_port()) for _ in range(4)]
if "--" not in sys.argv:
firstargs = sys.argv[1:]
secondargs = []
else:
index = sys.argv.index("--")
firstargs = sys.argv[1:index]
secondargs = sys.argv[index + 1:]
with Popen(['sbatch'] + firstargs + ['notebookjob.sh'] + ports + secondargs, stdin=PIPE, stdout=PIPE, stderr=PIPE) as proc:
jobline = proc.stdout.readline().decode()
jobline = jobline.strip()
vals = jobline.split(';')
jobid = int(vals[0])
joblist = []
if len(vals) > 1:
jobcluster = vals[1]
joblist = ['-M', jobcluster]
print(f'Waiting for job ID {jobid} to start')
url = ""
while url == "":
try:
with open(f'slurm-{jobid}.out') as file:
for line in file:
index = line.find("http://")
if index >= 0:
url = line[index:]
if url == "":
print("Job started, valid URL not yet provided by Jupyter. This should be pretty fast.")
except FileNotFoundError:
print("Output file not yet found. Waiting for job to start.")
time.sleep(10)
port = int(re.search(':([0-9]+)/', url).group(1))
with Popen(['squeue', '-o', '%N', '-j', str(jobid)] + joblist, stdin=PIPE, stdout=PIPE, stderr=PIPE) as proc:
lines = proc.stdout.readlines()
node = lines[-1].decode().strip()
with Popen(['ssh', node, '-L', f'127.0.0.1:{port}:127.0.0.1:{port}', '-T'], stdin=PIPE, stdout=PIPE, stderr=PIPE) as proc:
print('If you can open a web browser on the login node using e.g. Thinlinc, you can now open this URL:')
print(url)
print('If not, run the following ssh command locally and leave that secondary ssh shell open:')
print(f'ssh {socket.gethostname()} -L 127.0.0.1:{port}:127.0.0.1:{port}')
print()
print("When you've done this, you can open the url in a normal web browser.")
print("Press Enter in this terminal when you're done. The job has a default time limit of 59 minutes.")
input()
proc.terminate()
with Popen(['scancel', str(jobid)] + joblist, stdin=PIPE, stdout=PIPE, stderr=PIPE) as proc:
pass