diff options
Diffstat (limited to 'src/lib/Bcfg2/DBSettings.py')
-rw-r--r-- | src/lib/Bcfg2/DBSettings.py | 86 |
1 files changed, 78 insertions, 8 deletions
diff --git a/src/lib/Bcfg2/DBSettings.py b/src/lib/Bcfg2/DBSettings.py index 3e101405d..03e34bbc3 100644 --- a/src/lib/Bcfg2/DBSettings.py +++ b/src/lib/Bcfg2/DBSettings.py @@ -50,8 +50,7 @@ settings = dict( # pylint: disable=C0103 MIDDLEWARE_CLASSES=( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.middleware.doc.XViewMiddleware'), + 'django.contrib.auth.middleware.AuthenticationMiddleware'), ROOT_URLCONF='Bcfg2.Reporting.urls', AUTHENTICATION_BACKENDS=('django.contrib.auth.backends.ModelBackend'), LOGIN_URL='/login', @@ -65,10 +64,23 @@ settings = dict( # pylint: disable=C0103 'django.core.context_processors.i18n', 'django.core.context_processors.media', 'django.core.context_processors.request'), - DATABASE_ROUTERS=['Bcfg2.DBSettings.PerApplicationRouter']) - -if HAS_SOUTH: + DATABASE_ROUTERS=['Bcfg2.DBSettings.PerApplicationRouter'], + TEST_RUNNER='django.test.simple.DjangoTestSuiteRunner') + +if HAS_DJANGO and django.VERSION[0] == 1 and django.VERSION[1] >= 6: + settings['MIDDLEWARE_CLASSES'] += \ + ('django.contrib.admindocs.middleware.XViewMiddleware',) +elif HAS_SOUTH: + settings['MIDDLEWARE_CLASSES'] += \ + ('django.middleware.doc.XViewMiddleware',) + +if HAS_DJANGO and django.VERSION[0] == 1 and django.VERSION[1] >= 7: + settings['INSTALLED_APPS'] += ('Bcfg2.Reporting',) +elif HAS_SOUTH: settings['INSTALLED_APPS'] += ('south', 'Bcfg2.Reporting') + settings['SOUTH_MIGRATION_MODULES'] = { + 'Bcfg2.Reporting': 'Bcfg2.Reporting.south_migrations' + } if 'BCFG2_LEGACY_MODELS' in os.environ: settings['INSTALLED_APPS'] += ('Bcfg2.Server.Reports.reports',) @@ -142,6 +154,10 @@ def finalize_django_config(opts=None, silent=False): def sync_databases(**kwargs): """ Synchronize all databases that we know about. """ + if django.VERSION[0] == 1 and django.VERSION[1] >= 7: + # Nothing needed here, it's all handled with migrate + return + logger = logging.getLogger() for database in settings['DATABASES']: logger.debug("Syncing database %s" % (database)) @@ -149,11 +165,56 @@ def sync_databases(**kwargs): **kwargs) +def upgrade_to_django_migrations(database, logger): + """ + Get the migration state from south and move django migrations to + the same state by fake applying the same migration. + + Note: We cannot use south directly here, because this functions + runs on django-1.7 or higher, that is not supported by south. + """ + + last_migration = None + try: + # get latest south migration + cursor = django.db.connections[database].cursor() + cursor.cursor.execute('SELECT migration FROM south_migrationhistory') + applied_migrations = [name for (name,) in cursor.fetchall()] + last_migration = sorted(applied_migrations).pop() + except: # pylint: disable=W0702 + # django.db.DatabaseError is not working here, because we are + # using the low level api to interact directly with the database + logger.debug("No south migration detected for database: %s." % + database) + + if last_migration is not None: + # fake-apply matching django migrations + django.core.management.call_command( + "migrate", 'Reporting', last_migration, + database=database, fake=True) + + +def initial_django_migration(database): + """ Check if we ever executed an initial django migration. """ + from django.db.migrations import loader # pylint: disable=E0611 + loader = loader.MigrationLoader(django.db.connections[database]) + return len(loader.applied_migrations) == 0 + + def migrate_databases(**kwargs): """ Do South migrations on all databases that we know about. """ logger = logging.getLogger() for database in settings['DATABASES']: logger.debug("Migrating database %s" % (database)) + if django.VERSION[0] == 1 and django.VERSION[1] >= 7: + django.setup() # pylint: disable=E1101 + if initial_django_migration(database): + logger.warning( + "No applied django migrations found for database %s. " + "Trying to get the state from south migration in case " + "you just upgraded your django version." % database) + upgrade_to_django_migrations(database, logger) + django.core.management.call_command("migrate", database=database, **kwargs) @@ -196,7 +257,14 @@ class PerApplicationRouter(object): def allow_syncdb(self, *_): """ Called when Django wants to determine which models to sync to a given database. Take the cowards way out and sync all models to all - databases to allow for easy migrations. """ + databases to allow for easy migrations. This method is replaced with + allow_migrate in django 1.7 and higher. """ + return True + + def allow_migrate(self, *_args, **_kwargs): + """ Called when Django wants to determine which migrations should + be run on a given database. Take the cowards way out and run all + migrations to all databases to allow for easy migrations. """ return True @@ -278,7 +346,8 @@ class _OptionContainer(object): def component_parsed_hook(opts): """ Finalize the Django config after this component's options are parsed. """ - finalize_django_config(opts=opts) + if HAS_DJANGO: + finalize_django_config(opts=opts) @staticmethod def options_parsed_hook(): @@ -287,6 +356,7 @@ class _OptionContainer(object): early enough in option parsing to be parsed in the 'early' phase. Chances are good that things will break if that happens, but we do our best to be a good citizen. """ - finalize_django_config(silent=True) + if HAS_DJANGO: + finalize_django_config(silent=True) Bcfg2.Options.get_parser().add_component(_OptionContainer) |