Skip to content
Snippets Groups Projects
Commit 7870788b authored by Arie Peterson's avatar Arie Peterson
Browse files

Replace init lock and make sure to init only once

parent d3099abb
No related branches found
No related tags found
No related merge requests found
......@@ -37,6 +37,7 @@ import cluster_config
from config import *
import logging
import migration_reset
import os
import sys
# Configure logging.
......@@ -69,35 +70,49 @@ cors = CORS(app)
db.init_app(app)
# We'll now perform some initialization routines. Because these have to be done
# once at startup, not for every gunicorn worker, we take a machine-wide lock
# for this.
init_lock = NamedAtomicLock('dashboard_init')
if init_lock.acquire():
def init_routines():
with app.app_context():
# We have reset the alembic migration history at Stackspin version 2.2.
# This checks whether we need to prepare the database to follow that
# change.
migration_reset.reset()
flask_migrate.Migrate(app, db)
try:
with app.app_context():
# We have reset the alembic migration history at Stackspin version 2.2.
# This checks whether we need to prepare the database to follow that
# change.
migration_reset.reset()
flask_migrate.Migrate(app, db)
try:
with app.app_context():
flask_migrate.upgrade()
except Exception as e:
app.logger.info(f"upgrade failed: {type(e)}: {e}")
sys.exit(2)
# We need this app context in order to talk the database, which is managed by
# flask-sqlalchemy, which assumes a flask app context.
with app.app_context():
# Load the list of apps from a configmap and store any missing ones in the
# database.
cluster_config.populate_apps()
# Same for the list of oauthclients.
cluster_config.populate_oauthclients()
finally:
init_lock.release()
flask_migrate.upgrade()
# TODO: actually flask_migrate.upgrade will catch any errors and
# exit the program :/
except Exception as e:
app.logger.info(f"upgrade failed: {type(e)}: {e}")
sys.exit(2)
# We need this app context in order to talk the database, which is managed by
# flask-sqlalchemy, which assumes a flask app context.
with app.app_context():
# Load the list of apps from a configmap and store any missing ones in the
# database.
cluster_config.populate_apps()
# Same for the list of oauthclients.
cluster_config.populate_oauthclients()
# `init_routines` has to run only once per dashboard instance, or at least not
# concurrently. We used to have locking in place to prevent concurrent
# executions of this code, but we now rely on proper configuration of gunicorn
# and/or flask to make sure this is run only once. In particular:
# * we have "preload" on for gunicorn, so this file is loaded only once, before
# workers are forked;
# * we make sure that in development mode we run this only once, even though
# this file is loaded twice by flask for some reason.
if DEV_MODE:
logging.info("WERKZEUG_RUN_MAIN: {}".format(os.environ.get("WERKZEUG_RUN_MAIN", "unset")))
if os.environ.get("WERKZEUG_RUN_MAIN") == "true":
logging.info("Running initialization code (dev mode).")
init_routines()
else:
logging.info("Not running initialization code (dev mode).")
else:
logging.info("Running initialization code (production mode).")
init_routines()
app.register_blueprint(api_v1)
app.register_blueprint(web)
......
......@@ -21,5 +21,9 @@ SQLALCHEMY_TRACK_MODIFICATIONS = False
# running in a Kubernetes pod. Set it to "false" to load the config from the
# `KUBECONFIG` environment variable.
LOAD_INCLUSTER_CONFIG = os.environ.get("LOAD_INCLUSTER_CONFIG").lower() == "true"
# We use this to detect whether we run in production mode (gunicorn, as
# specified in the docker image) or dev mode (flask run, as specified in docker
# compose config).
DEV_MODE = os.environ.get("DASHBOARD_DEV_MODE", "False").lower() in ('true', '1')
DEMO_INSTANCE = os.environ.get("DASHBOARD_DEMO_INSTANCE", "False").lower() in ('true', '1')
......@@ -54,7 +54,7 @@ services:
- "$KUBECONFIG:/.kube/config"
depends_on:
- kube_port_mysql
entrypoint: ["bash", "-c", "flask run --host $$(hostname -i)"]
entrypoint: ["bash", "-c", "DASHBOARD_DEV_MODE=true flask run --host $$(hostname -i)"]
kube_port_kratos_admin:
image: bitnami/kubectl:1.27.2
user: "${KUBECTL_UID}:${KUBECTL_GID}"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment