diff options
| author | Dolph Mathews <dolph.mathews@gmail.com> | 2011-12-19 14:05:59 -0600 |
|---|---|---|
| committer | Dolph Mathews <dolph.mathews@gmail.com> | 2011-12-19 16:32:59 -0600 |
| commit | a1d15b05a9d3b95bc41397982fc97dbf2e364e05 (patch) | |
| tree | 12a95143249279182c858a3c2952ba22c270ec35 | |
| parent | 0391b44478ca38ce23929c40a472f885bbbd7c84 (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.rst | 21 | ||||
| -rw-r--r-- | keystone/backends/sqlalchemy/migration.py | 45 | ||||
| -rw-r--r-- | keystone/manage/__init__.py | 26 |
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: |
