-
Notifications
You must be signed in to change notification settings - Fork 104
/
run.py
executable file
·144 lines (126 loc) · 5.36 KB
/
run.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
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
#!/usr/bin/env python3
import os, tempfile, time, shutil, subprocess, sys
# Where the PostgreSQL data is stored
PGDATA = '/projects/postgres/data'
PGHOST = os.path.join(PGDATA, 'socket')
os.environ['PGHOST'] = PGHOST
os.environ['PGUSER'] = 'smc'
# ensure that everything we spawn has this umask, which is more secure.
os.umask(0o077)
join = os.path.join
def log(*args):
print(*args)
sys.stdout.flush()
def run(v, shell=False, path='.', get_output=False, env=None, verbose=1):
t = time.time()
if isinstance(v, str):
cmd = v
shell = True
else:
cmd = ' '.join([(x if len(x.split())<=1 else '"%s"'%x) for x in v])
if path != '.':
cur = os.path.abspath(os.curdir)
if verbose:
print('chdir %s'%path)
os.chdir(path)
try:
if verbose:
print(cmd)
if shell:
kwds = {'shell':True, 'executable':'/bin/bash', 'env':env}
else:
kwds = {'env':env}
if get_output:
output = subprocess.Popen(v, stdout=subprocess.PIPE, **kwds).stdout.read().decode()
else:
if subprocess.call(v, **kwds):
raise RuntimeError("error running '{cmd}'".format(cmd=cmd))
output = None
seconds = time.time() - t
if verbose > 1:
print("TOTAL TIME: {seconds} seconds -- to run '{cmd}'".format(seconds=seconds, cmd=cmd))
return output
finally:
if path != '.':
os.chdir(cur)
def self_signed_cert(target= 'nopassphrase.pem'):
if os.path.exists('/projects/conf/nopassphrase.pem'):
log("installing cert at '/projects/conf/nopassphrase.pem'")
run("cp /projects/conf/nopassphrase.pem {target} && chmod og-rwx {target}".format(target=target))
return
log("create self_signed_cert")
with tempfile.TemporaryDirectory() as tmp:
run(['openssl', 'req', '-new', '-x509', '-nodes', '-out', 'server.crt',
'-keyout', 'server.key',
'-subj', '/C=US/ST=WA/L=WA/O=Network/OU=IT Department/CN=sagemath'], path=tmp)
s = open(join(tmp, 'server.crt')).read() + open(join(tmp, 'server.key')).read()
open(target,'w').write(s)
run("chmod og-rwx {target} && mkdir -p /projects/conf && cp {target} /projects/conf/nopassphrase.pem".format(target=target))
def init_projects_path():
log("initialize /projects path")
if not os.path.exists('/projects'):
log("WARNING: container data will be EPHEMERAL -- in /projects")
os.makedirs('/projects')
# Ensure that users can see their own home directories:
os.system("chmod a+rx /projects")
for path in ['conf']:
full_path = join('/projects', path)
if not os.path.exists(full_path):
log("creating ", full_path)
os.makedirs(full_path)
run("chmod og-rwx '%s'"%full_path)
def start_services():
for name in ['haproxy', 'nginx', 'ssh']:
run(['service', name, 'start'])
def root_ssh_keys():
run("rm -rf /root/.ssh/")
run("ssh-keygen -t ecdsa -N '' -f /root/.ssh/id_ecdsa")
run("cp -v /root/.ssh/id_ecdsa.pub /root/.ssh/authorized_keys")
def start_hub():
run(". smc-env && hub start \
--host=localhost \
--port 5000 \
--proxy_port 5001 \
--update \
--single \
--logfile /var/log/hub.log \
--pidfile /run/hub.pid &", \
path='/cocalc/src')
def postgres_perms():
run("mkdir -p /projects/postgres && chown -R sage. /projects/postgres && chmod og-rwx -R /projects/postgres")
def start_postgres():
postgres_perms()
if not os.path.exists(PGDATA): # see comments in smc/src/dev/project/start_postgres.py
run("sudo -u sage pg_ctl init -D '%s'"%PGDATA)
open(os.path.join(PGDATA,'pg_hba.conf'), 'w').write("local all all trust")
conf = os.path.join(PGDATA, 'postgresql.conf')
s = open(conf).read() + "\nunix_socket_directories = '%s'\nlisten_addresses=''\n"%PGHOST
open(conf,'w').write(s)
os.makedirs(PGHOST)
postgres_perms()
run("sudo -u sage postgres -D '%s' >%s/postgres.log 2>&1 &"%(PGDATA, PGDATA))
time.sleep(5)
run("sudo -u sage createuser -h '%s' -sE smc"%PGHOST)
run("sudo -u sage kill %s"%(open(os.path.join(PGDATA, 'postmaster.pid')).read().split()[0]))
time.sleep(3)
os.system("sudo -u sage postgres -D '%s' > /var/log/postgres.log 2>&1 &"%PGDATA)
def start_compute():
run("mkdir -p /projects/conf && chmod og-rwx -R /projects/conf")
run(". smc-env; compute --host=localhost --single start 1>/var/log/compute.log 2>/var/log/compute.err &", path='/cocalc/src')
# Sleep to wait for compute server to start and write port/secret *AND* initialize the schema.
# TODO: should really do this right -- since if the compute-client tries to initialize schema at same, time things get hosed.
run("""sleep 15; . smc-env; echo "require('smc-hub/compute-client').compute_server(cb:(e,s)-> s._add_server_single(cb:->process.exit(0)))" | coffee & """, path='/cocalc/src')
def tail_logs():
run("tail -f /var/log/compute.log /var/log/compute.err /cocalc/logs/*")
def main():
self_signed_cert('/run/haproxy.pem')
init_projects_path()
start_services()
root_ssh_keys()
start_postgres()
start_hub()
start_compute()
while True:
os.wait()
if __name__ == "__main__":
main()