summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDolph Mathews <dolph.mathews@gmail.com>2011-12-19 14:05:59 -0600
committerDolph Mathews <dolph.mathews@gmail.com>2011-12-19 16:32:59 -0600
commita1d15b05a9d3b95bc41397982fc97dbf2e364e05 (patch)
tree12a95143249279182c858a3c2952ba22c270ec35
parent0391b44478ca38ce23929c40a472f885bbbd7c84 (diff)
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
-rw-r--r--doc/source/migration.rst21
-rw-r--r--keystone/backends/sqlalchemy/migration.py45
-rw-r--r--keystone/manage/__init__.py26
3 files changed, 73 insertions, 19 deletions
diff --git a/doc/source/migration.rst b/doc/source/migration.rst
index b2bafdcc..460d980b 100644
--- a/doc/source/migration.rst
+++ b/doc/source/migration.rst
@@ -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>
diff --git a/keystone/backends/sqlalchemy/migration.py b/keystone/backends/sqlalchemy/migration.py
index b1810179..db652daf 100644
--- a/keystone/backends/sqlalchemy/migration.py
+++ b/keystone/backends/sqlalchemy/migration.py
@@ -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
diff --git a/keystone/manage/__init__.py b/keystone/manage/__init__.py
index f39c6f20..518a00e0 100644
--- a/keystone/manage/__init__.py
+++ b/keystone/manage/__init__.py
@@ -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: