-
-
Notifications
You must be signed in to change notification settings - Fork 82
/
docker-entrypoint.py
executable file
·148 lines (131 loc) · 4.87 KB
/
docker-entrypoint.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
145
146
147
148
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
import random
import subprocess
import sys
import time
import warnings
try:
random = random.SystemRandom()
except NotImplementedError:
warnings.warn('No secure pseudo random number generator available.')
def wait_for_db(env):
i = 0
while True:
try:
subprocess.run(['python', 'server/manage.py', 'shell', '-c',
'import django;django.db.connection.ensure_connection()'],
stderr=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
check=True,
env=env)
except subprocess.CalledProcessError:
retry_delay = min(20, (i + 1)) * random.uniform(0.8, 1.2)
warnings.warn(f"Cannot connect to DB! Sleep {retry_delay:.1f}s…")
time.sleep(retry_delay)
i += 1
else:
break
print("DB connection OK")
def wait_for_db_migration():
i = 0
while True:
try:
subprocess.run(['python', 'server/manage.py', 'migrate', '--noinput'], check=True)
except subprocess.CalledProcessError:
retry_delay = min(20, (i + 1)) * random.uniform(0.8, 1.2)
warnings.warn(f"Can't migrate DB! Sleep {retry_delay:.1f}s…")
time.sleep(retry_delay)
i += 1
else:
break
print("DB migration OK")
def wait_for_provisioning():
i = 0
while True:
try:
subprocess.run(['python', 'server/manage.py', 'provision'], check=True)
except subprocess.CalledProcessError:
retry_delay = min(20, (i + 1)) * random.uniform(0.8, 1.2)
warnings.warn(f"Can't do provisioning! Sleep {retry_delay:.1f}s…")
time.sleep(retry_delay)
i += 1
else:
break
print("Provisioning OK")
def django_collectstatic():
subprocess.run(['python', 'server/manage.py', 'collectstatic', '-v0', '--noinput'], check=True)
def create_zentral_superuser():
username = os.environ.get("ZENTRAL_ADMIN_USERNAME")
email = os.environ.get("ZENTRAL_ADMIN_EMAIL")
if username and email:
print("Found admin username and email in environment. "
"Create superuser if missing.", flush=True)
args = ['python', 'server/manage.py', 'create_zentral_user', '--superuser']
force = os.environ.get("ZENTRAL_FORCE_ADMIN_PASSWORD_RESET")
if not force or force.upper() not in ("1", "TRUE", "YES", "Y"):
args.append("--skip-if-existing")
args.extend([username, email])
try:
subprocess.run(args, check=True)
except subprocess.CalledProcessError:
print("Could not create superuser!!!", flush=True)
else:
print("Admin username and email not found", flush=True)
KNOWN_COMMANDS = {
"runserver": ["python", 'server/manage.py', 'runserver', '0.0.0.0:8000'],
"gunicorn": ["gunicorn",
"--worker-tmp-dir", "/dev/shm",
"--error-logfile", "-",
"--chdir", "/zentral/server", "server.wsgi"],
"runworker": ["python", 'server/manage.py', 'runworker'],
"runworkers": ["python", 'server/manage.py', 'runworkers'],
"celery": ["celery", "-A", "server", "worker"],
# extras
"shell": ["python", 'server/manage.py', 'shell'],
"tests": ["python", 'server/manage.py', 'test', 'tests/'],
"tests_with_coverage": ["coverage", "run", 'server/manage.py', 'test', 'tests/'],
"coverage_lcov": ["coverage", "lcov"],
"createuser": ["python", 'server/manage.py', 'create_zentral_user'],
}
KNOWN_COMMANDS_EXTRA_ENV = {
"tests": {"ZENTRAL_PROBES_SYNC": "0",
"ZENTRAL_CONF_DIR": "/zentral/tests/conf"},
"tests_with_coverage": {"ZENTRAL_PROBES_SYNC": "0",
"ZENTRAL_CONF_DIR": "/zentral/tests/conf"}
}
KNOWN_COMMANDS_CHDIR = {
"celery": "/zentral/server"
}
KNOWN_COMMANDS_TRIGGERING_COLLECTSTATIC = {
'gunicorn', # the staticfiles manifest is needed!
'runserver',
}
if __name__ == '__main__':
if len(sys.argv) < 2:
warnings.warn("Not enough arguments.")
sys.exit(2)
cmd = sys.argv[1]
env = os.environ.copy()
args = KNOWN_COMMANDS.get(cmd, None)
if args:
filename = args[0]
args.extend(sys.argv[2:])
env.update(KNOWN_COMMANDS_EXTRA_ENV.get(cmd, {}))
if cmd != "tests":
wait_for_db_migration()
create_zentral_superuser()
else:
wait_for_db(env)
wait_for_provisioning()
if cmd in KNOWN_COMMANDS_TRIGGERING_COLLECTSTATIC:
django_collectstatic()
wd = KNOWN_COMMANDS_CHDIR.get(cmd)
if wd:
os.chdir(wd)
print('Launch known command "{}"'.format(cmd), flush=True)
else:
filename = cmd
args = sys.argv[1:]
os.execvpe(filename, args, env)