Optionally migrate database at service startup

In some use cases, notably testing, it can be handy to do database
migrations when the web service starts up. This changes adds that
functionality, controlled by a [placement_database]/sync_on_startup
option that defaults to False.

When True, `migration.upgrade('head')` will be called before the
placement application is made available to the wsgi server. Alembic
protects us against concurrency issues and prevents re-doing already
done migrations.

This means that it is possible, with the help of oslo.config>=6.7.0
to do something like this:

    OS_PLACEMENT_DATABASE__CONNECTION=sqlite:// \
    OS_PLACEMENT_DATABASE__SYNC_ON_STARTUP=True \
    OS_API__AUTH_STRATEGY=noauth2 \
    .tox/py36/bin/placement-api

and have a ready to go placement api using an in-RAM sql database.

A reno is added.

Change-Id: Ie43a69be8b75250d9deca6a911eda7b722ef8648
This commit is contained in:
Chris Dent 2018-11-20 17:39:05 +00:00 committed by Eric Fried
parent 8723768a41
commit da36ad16e1
5 changed files with 24 additions and 4 deletions

View File

@ -93,6 +93,10 @@ placement_db_opts = [
help=''),
cfg.IntOpt('pool_timeout',
help=''),
cfg.BoolOpt('sync_on_startup',
default=False,
help='If True, database schema migrations will be attempted when the'
' web service starts.'),
] # noqa

View File

@ -21,7 +21,10 @@ placement_context_manager = enginefacade.transaction_context()
def _get_db_conf(conf_group):
return dict(conf_group.items())
conf_dict = dict(conf_group.items())
# Remove the 'sync_on_startup' conf setting, enginefacade does not use it.
del conf_dict['sync_on_startup']
return conf_dict
@run_once("TransactionFactory already started, not reconfiguring.",

View File

@ -16,6 +16,7 @@ import oslo_middleware
from oslo_middleware import cors
from placement import auth
from placement.db.sqlalchemy import migration
from placement import db_api
from placement import fault_wrap
from placement import handler
@ -91,10 +92,12 @@ def deploy(conf):
return application
def update_database():
def update_database(conf):
"""Do any database updates required at process boot time, such as
updating the traits table.
"""
if conf.placement_database.sync_on_startup:
migration.upgrade('head')
ctx = db_api.DbContext()
resource_provider.ensure_trait_sync(ctx)
resource_provider.ensure_resource_classes_sync(ctx)
@ -117,5 +120,5 @@ def loadapp(config, project_name=NAME):
backwards compatibility
"""
application = deploy(config)
update_database()
update_database(config)
return application

View File

@ -70,7 +70,7 @@ class Database(test_fixtures.GeneratesSchema, test_fixtures.AdHocDbFixture):
self.cleanup()
# Sync traits and resource classes.
deploy.update_database()
deploy.update_database(self.conf_fixture.conf)
def cleanup(self):
resource_provider._TRAITS_SYNCED = False

View File

@ -0,0 +1,10 @@
---
features:
- |
A configuration setting ``[placement_database]/sync_on_startup`` is added
which, if set to ``True``, will cause database schema migrations to be
called when the placement web application is started. This avoids the need
to call ``placement-manage db sync`` separately.
To preserve backwards compatbility and avoid unexpected changes, the
default of the setting is ``False``.