Added: ./keystone-manage database goto <version>

- Jumps to a given version without performing migrations
- Analog of `UPDATE migrate_version SET version=<version>;`

Change-Id: I682d3c2d83b22bcd30e672a11a35c8804dd5a1ea
This commit is contained in:
Dolph Mathews 2011-12-19 14:05:59 -06:00
parent 0391b44478
commit a1d15b05a9
3 changed files with 73 additions and 19 deletions

View File

@ -44,17 +44,18 @@ support::
$ ./bin/keystone-manage database version_control
This command simply creates a ``migrate_version`` table, set at version 0,
which indicates that no migrations have been applied.
This command simply creates a ``migrate_version`` table, set at
``version_number`` 0, which indicates that no migrations have been applied.
If you are starting with an existing schema, you can set your database to
the current schema version using a SQL command. For example, if you're
starting from a diablo-compatible database, set your current
database version to ``1``::
If you are starting with an existing schema, you can jump to a specific
schema version without performing migrations using the ``database goto``
command. For example, if you're starting from a diablo-compatible
database, set your current database ``version_number`` to ``1`` using::
UPDATE migrate_version SET version=1;
$ ./bin/keystone-manage database goto <version_number>
Determine your appropriate database ``version`` by referencing the following table:
Determine your appropriate database ``version_number`` by referencing the
following table:
+------------+-------------+
| Release | ``version`` |
@ -94,6 +95,10 @@ Check your current schema version::
$ ./bin/keystone-manage database version
Jump to a specific version without performing migrations::
$ ./bin/keystone-manage database goto <version_number>
Upgrade to a specific version::
$ ./bin/keystone-manage database upgrade <version_number>

View File

@ -32,6 +32,14 @@ from keystone.logic.types import fault
logger = logging.getLogger(__name__)
def get_migrate_repo_path():
"""Get the path for the migrate repository."""
path = os.path.join(os.path.abspath(os.path.dirname(__file__)),
'migrate_repo')
assert os.path.exists(path)
return path
def get_migrate_repo(repo_path):
return versioning_api.repository.Repository(repo_path)
@ -48,6 +56,35 @@ def get_db_version(engine, repo_path):
return get_schema(engine, repo_path).version
def db_goto_version(options, version):
"""
Jump to a specific database version without performing migrations.
:param options: options dict
:param version: version to jump to
"""
@versioning_api.with_engine
def set_db_version(url, repository, old_v, new_v, **opts):
engine = opts.pop('engine')
schema = get_schema(engine, repo_path)
schema.update_repository_table(old_v, new_v)
return True
repo_path = get_migrate_repo_path()
sql_connection = options['sql_connection']
new_version = int(version)
try:
old_version = versioning_api.db_version(sql_connection, repo_path)
if new_version != old_version:
return set_db_version(sql_connection, repo_path, old_version,
new_version)
except versioning_exceptions.DatabaseNotControlledError:
msg = (_("database '%(sql_connection)s' is not under "
"migration control") % locals())
raise fault.DatabaseMigrationError(msg)
def db_version(options):
"""
Return the database's current migration number
@ -137,11 +174,3 @@ def db_sync(options, version=None):
pass
upgrade(options, version=version)
def get_migrate_repo_path():
"""Get the path for the migrate repository."""
path = os.path.join(os.path.abspath(os.path.dirname(__file__)),
'migrate_repo')
assert os.path.exists(path)
return path

View File

@ -40,9 +40,9 @@ logger = logging.getLogger(__name__)
# CLI feature set
OBJECTS = ['user', 'tenant', 'role', 'service',
'endpointTemplates', 'token', 'endpoint', 'credentials', 'database']
ACTIONS = ['add', 'list', 'disable', 'delete', 'grant',
'revoke',
'sync', 'downgrade', 'upgrade', 'version_control', 'version']
ACTIONS = ['add', 'list', 'disable', 'delete', 'grant', 'revoke',
'sync', 'downgrade', 'upgrade', 'version_control', 'version',
'goto']
# Messages
@ -342,6 +342,18 @@ def process(*args):
raise optparse.OptParseError(
'SQL alchemy backend not specified in config')
elif (object_type, action) == ('database', 'goto'):
require_args(args, 1, 'Jumping database versions requires a '
'version #')
backend_names = options.get('backends', None)
if backend_names:
if 'keystone.backends.sqlalchemy' in backend_names.split(','):
do_db_goto_version(options['keystone.backends.sqlalchemy'],
version=args[2])
else:
raise optparse.OptParseError(
'SQL alchemy backend not specified in config')
else:
# Command recognized but not handled: should never reach this
raise NotImplementedError()
@ -355,6 +367,14 @@ def do_db_version(options):
print migration.db_version(options)
def do_db_goto_version(options, version):
"""Override the database's current migration level"""
if migration.db_goto_version(options, version):
msg = ('Jumped to version=%s (without performing intermediate '
'migrations)') % version
print msg
def do_db_upgrade(options, args):
"""Upgrade the database's migration level"""
try: