root: auto-migrate on startup, lock database using pg_advisory_lock
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
caa5dc1d14
commit
7b8e5c4272
|
@ -43,29 +43,6 @@ spec:
|
||||||
values:
|
values:
|
||||||
- web
|
- web
|
||||||
topologyKey: "kubernetes.io/hostname"
|
topologyKey: "kubernetes.io/hostname"
|
||||||
initContainers:
|
|
||||||
- name: authentik-database-migrations
|
|
||||||
image: "{{ .Values.image.name }}:{{ .Values.image.tag }}"
|
|
||||||
imagePullPolicy: "{{ .Values.image.pullPolicy }}"
|
|
||||||
args: [migrate]
|
|
||||||
envFrom:
|
|
||||||
- configMapRef:
|
|
||||||
name: {{ include "authentik.fullname" . }}-config
|
|
||||||
prefix: AUTHENTIK_
|
|
||||||
- secretRef:
|
|
||||||
name: {{ include "authentik.fullname" . }}-secret-key
|
|
||||||
prefix: AUTHENTIK_
|
|
||||||
env:
|
|
||||||
- name: AUTHENTIK_REDIS__PASSWORD
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: "{{ .Release.Name }}-redis"
|
|
||||||
key: redis-password
|
|
||||||
- name: AUTHENTIK_POSTGRESQL__PASSWORD
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: "{{ .Release.Name }}-postgresql"
|
|
||||||
key: postgresql-password
|
|
||||||
containers:
|
containers:
|
||||||
- name: {{ .Chart.Name }}
|
- name: {{ .Chart.Name }}
|
||||||
image: "{{ .Values.image.name }}:{{ .Values.image.tag }}"
|
image: "{{ .Values.image.name }}:{{ .Values.image.tag }}"
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
python -m lifecycle.wait_for_db
|
python -m lifecycle.wait_for_db
|
||||||
printf '{"event": "Bootstrap completed", "level": "info", "logger": "bootstrap", "command": "%s"}\n' "$@" > /dev/stderr
|
printf '{"event": "Bootstrap completed", "level": "info", "logger": "bootstrap", "command": "%s"}\n' "$@" > /dev/stderr
|
||||||
if [[ "$1" == "server" ]]; then
|
if [[ "$1" == "server" ]]; then
|
||||||
|
python -m lifecycle.migrate
|
||||||
gunicorn -c /lifecycle/gunicorn.conf.py authentik.root.asgi:application
|
gunicorn -c /lifecycle/gunicorn.conf.py authentik.root.asgi:application
|
||||||
elif [[ "$1" == "worker" ]]; then
|
elif [[ "$1" == "worker" ]]; then
|
||||||
celery -A authentik.root.celery worker --autoscale 3,1 -E -B -s /tmp/celerybeat-schedule -Q authentik,authentik_scheduled,authentik_events
|
celery -A authentik.root.celery worker --autoscale 3,1 -E -B -s /tmp/celerybeat-schedule -Q authentik,authentik_scheduled,authentik_events
|
||||||
elif [[ "$1" == "migrate" ]]; then
|
elif [[ "$1" == "migrate" ]]; then
|
||||||
# Run system migrations first, run normal migrations after
|
printf "DEPERECATED: database migrations are now executed automatically on startup."
|
||||||
python -m lifecycle.migrate
|
python -m lifecycle.migrate
|
||||||
python -m manage migrate
|
|
||||||
elif [[ "$1" == "backup" ]]; then
|
elif [[ "$1" == "backup" ]]; then
|
||||||
python -m manage dbbackup --clean
|
python -m manage dbbackup --clean
|
||||||
elif [[ "$1" == "restore" ]]; then
|
elif [[ "$1" == "restore" ]]; then
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
"""System Migration handler"""
|
"""System Migration handler"""
|
||||||
|
import os
|
||||||
from importlib.util import module_from_spec, spec_from_file_location
|
from importlib.util import module_from_spec, spec_from_file_location
|
||||||
from inspect import getmembers, isclass
|
from inspect import getmembers, isclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
@ -11,6 +12,7 @@ from structlog.stdlib import get_logger
|
||||||
from authentik.lib.config import CONFIG
|
from authentik.lib.config import CONFIG
|
||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
|
ADV_LOCK_UID = 1000
|
||||||
|
|
||||||
|
|
||||||
class BaseMigration:
|
class BaseMigration:
|
||||||
|
@ -40,18 +42,36 @@ if __name__ == "__main__":
|
||||||
host=CONFIG.y("postgresql.host"),
|
host=CONFIG.y("postgresql.host"),
|
||||||
)
|
)
|
||||||
curr = conn.cursor()
|
curr = conn.cursor()
|
||||||
|
# lock an advisory lock to prevent multiple instances from migrating at once
|
||||||
|
LOGGER.info("waiting to acquire database lock")
|
||||||
|
curr.execute("SELECT pg_advisory_lock(%s)", (ADV_LOCK_UID,))
|
||||||
|
try:
|
||||||
|
for migration in (
|
||||||
|
Path(__file__).parent.absolute().glob("system_migrations/*.py")
|
||||||
|
):
|
||||||
|
spec = spec_from_file_location("lifecycle.system_migrations", migration)
|
||||||
|
mod = module_from_spec(spec)
|
||||||
|
# pyright: reportGeneralTypeIssues=false
|
||||||
|
spec.loader.exec_module(mod)
|
||||||
|
|
||||||
for migration in Path(__file__).parent.absolute().glob("system_migrations/*.py"):
|
for name, sub in getmembers(mod, isclass):
|
||||||
spec = spec_from_file_location("lifecycle.system_migrations", migration)
|
if name != "Migration":
|
||||||
mod = module_from_spec(spec)
|
continue
|
||||||
# pyright: reportGeneralTypeIssues=false
|
migration = sub(curr, conn)
|
||||||
spec.loader.exec_module(mod)
|
if migration.needs_migration():
|
||||||
|
LOGGER.info("Migration needs to be applied", migration=sub)
|
||||||
for name, sub in getmembers(mod, isclass):
|
migration.run()
|
||||||
if name != "Migration":
|
LOGGER.info("Migration finished applying", migration=sub)
|
||||||
continue
|
LOGGER.info("applying django migrations")
|
||||||
migration = sub(curr, conn)
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "authentik.root.settings")
|
||||||
if migration.needs_migration():
|
try:
|
||||||
LOGGER.info("Migration needs to be applied", migration=sub)
|
from django.core.management import execute_from_command_line
|
||||||
migration.run()
|
except ImportError as exc:
|
||||||
LOGGER.info("Migration finished applying", migration=sub)
|
raise ImportError(
|
||||||
|
"Couldn't import Django. Are you sure it's installed and "
|
||||||
|
"available on your PYTHONPATH environment variable? Did you "
|
||||||
|
"forget to activate a virtual environment?"
|
||||||
|
) from exc
|
||||||
|
execute_from_command_line(["", "migrate"])
|
||||||
|
finally:
|
||||||
|
curr.execute("SELECT pg_advisory_unlock(%s)", (ADV_LOCK_UID,))
|
||||||
|
|
Reference in New Issue