changeset 6614:4e40640c43e5

alembic: check database version before starting kallithea Running kallithea with the wrong database version could be dangerous. Therefore, check for the correct version before starting Kallithea.
author domruf <dominikruf@gmail.com>
date Thu, 06 Apr 2017 21:05:30 +0200
parents 58931c2b6b0c
children 3ed43530d3b8
files kallithea/config/app_cfg.py
diffstat 1 files changed, 31 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/config/app_cfg.py	Wed Jun 15 18:33:27 2016 +0200
+++ b/kallithea/config/app_cfg.py	Thu Apr 06 21:05:30 2017 +0200
@@ -18,12 +18,16 @@
 """
 
 import platform
-import os, sys
+import os, sys, logging
 
 import tg
 from tg import hooks
 from tg.configuration import AppConfig
 from tg.support.converters import asbool
+import alembic
+from alembic.script.base import ScriptDirectory
+from alembic.migration import MigrationContext
+from sqlalchemy import create_engine
 
 from kallithea.lib.middleware.https_fixup import HttpsFixup
 from kallithea.lib.middleware.simplegit import SimpleGit
@@ -38,6 +42,8 @@
 import formencode
 import kallithea
 
+log = logging.getLogger(__name__)
+
 
 class KallitheaAppConfig(AppConfig):
     # Note: AppConfig has a misleading name, as it's not the application
@@ -113,6 +119,30 @@
 def setup_configuration(app):
     config = app.config
 
+    if config.get('ignore_alembic_revision', False):
+        log.warn('database alembic revision checking is disabled')
+    else:
+        dbconf = config['sqlalchemy.url']
+        alembic_cfg = alembic.config.Config()
+        alembic_cfg.set_main_option('script_location', 'kallithea:alembic')
+        alembic_cfg.set_main_option('sqlalchemy.url', dbconf)
+        script_dir = ScriptDirectory.from_config(alembic_cfg)
+        available_heads = sorted(script_dir.get_heads())
+
+        engine = create_engine(dbconf)
+        with engine.connect() as conn:
+            context = MigrationContext.configure(conn)
+            current_heads = sorted(str(s) for s in context.get_current_heads())
+        if current_heads != available_heads:
+            log.error('Failed to run Kallithea:\n\n'
+                      'The database version does not match the Kallithea version.\n'
+                      'Please read the documentation on how to upgrade or downgrade the database.\n'
+                      'Current database version id(s): %s\n'
+                      'Expected database version id(s): %s\n'
+                      'If you are a developer and you know what you are doing, you can add `ignore_alembic_revision = True` '
+                      'to your .ini file to skip the check.\n' % (' '.join(current_heads), ' '.join(available_heads)))
+            sys.exit(1)
+
     # store some globals into kallithea
     kallithea.CELERY_ON = str2bool(config['app_conf'].get('use_celery'))
     kallithea.CELERY_EAGER = str2bool(config['app_conf'].get('celery.always.eager'))