From 9d069c48aed3a087c5c51366c8e70b29f339e794 Mon Sep 17 00:00:00 2001 From: Yuji Date: Wed, 16 Sep 2015 11:45:27 +0900 Subject: [PATCH] Allow to specify branch for creating new migration Add options to 'neutron-db-manage revision' command for specifying a branch. DocImpact Change-Id: I00b00821839b0d77caaaf26b518c5c0c75e01218 Closes-Bug: 1503342 --- doc/source/devref/alembic_migrations.rst | 21 ++++++++++++++++-- neutron/db/migration/cli.py | 27 +++++++++++++++++------- neutron/tests/unit/db/test_migration.py | 23 ++++++++++++++++++++ 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/doc/source/devref/alembic_migrations.rst b/doc/source/devref/alembic_migrations.rst index 65dd63bc3..1fdc9aeb9 100644 --- a/doc/source/devref/alembic_migrations.rst +++ b/doc/source/devref/alembic_migrations.rst @@ -171,12 +171,29 @@ Script Auto-generation This generates a prepopulated template with the changes needed to match the database state with the models. You should inspect the autogenerated template to ensure that the proper models have been altered. +When running the above command you will probably get the following error +message:: + + Multiple heads are present; please specify the head revision on which the + new revision should be based, or perform a merge. + +This is alembic telling you that it does not know which branch (contract or +expand) to generate the revision for. You must decide, based on whether you +are doing contracting or expanding changes to the schema, and provide either +the ``--contract`` or ``--expand`` option. If you have both types of changes, +you must run the command twice, once with each option, and then manually edit +the generated revision scripts to separate the migration operations. In rare circumstances, you may want to start with an empty migration template and manually author the changes necessary for an upgrade. You can create a -blank file via:: +blank file for a branch via:: + + neutron-db-manage revision -m "description of revision" --expand + neutron-db-manage revision -m "description of revision" --contract - neutron-db-manage revision -m "description of revision" +**NOTE:** If you use above command you should check that migration is created +in a directory that is named as current release. If not, please raise the issue +with the development team (IRC, mailing list, launchpad bug). The timeline on each alembic branch should remain linear and not interleave with other branches, so that there is a clear path when upgrading. To verify diff --git a/neutron/db/migration/cli.py b/neutron/db/migration/cli.py index d2edc9d54..7a2fbbeb4 100644 --- a/neutron/db/migration/cli.py +++ b/neutron/db/migration/cli.py @@ -142,6 +142,12 @@ def add_alembic_subparser(sub, cmd): return sub.add_parser(cmd, help=getattr(alembic_command, cmd).__doc__) +def add_branch_options(parser): + group = parser.add_mutually_exclusive_group() + group.add_argument('--expand', action='store_true') + group.add_argument('--contract', action='store_true') + + def _find_milestone_revisions(config, milestone, branch=None): """Return the revision(s) for a given milestone.""" script = alembic_script.ScriptDirectory.from_config(config) @@ -230,10 +236,17 @@ def _check_bootstrap_new_branch(branch, version_path, addn_kwargs): def do_revision(config, cmd): '''Generate new revision files, one per branch.''' - do_alembic_command(config, cmd, - message=CONF.command.message, - autogenerate=CONF.command.autogenerate, - sql=CONF.command.sql) + kwargs = { + 'message': CONF.command.message, + 'autogenerate': CONF.command.autogenerate, + 'sql': CONF.command.sql, + } + if CONF.command.expand: + kwargs['head'] = 'expand@head' + elif CONF.command.contract: + kwargs['head'] = 'contract@head' + + do_alembic_command(config, cmd, **kwargs) update_head_file(config) @@ -392,10 +405,7 @@ def add_command_parsers(subparsers): default='', help='Change MySQL storage engine of current ' 'existing tables') - - group = parser.add_mutually_exclusive_group() - group.add_argument('--expand', action='store_true') - group.add_argument('--contract', action='store_true') + add_branch_options(parser) parser.set_defaults(func=do_upgrade) @@ -412,6 +422,7 @@ def add_command_parsers(subparsers): parser.add_argument('-m', '--message') parser.add_argument('--autogenerate', action='store_true') parser.add_argument('--sql', action='store_true') + add_branch_options(parser) parser.set_defaults(func=do_revision) diff --git a/neutron/tests/unit/db/test_migration.py b/neutron/tests/unit/db/test_migration.py index 62b794bed..c57bd3a56 100644 --- a/neutron/tests/unit/db/test_migration.py +++ b/neutron/tests/unit/db/test_migration.py @@ -236,6 +236,29 @@ class TestCli(base.BaseTestCase): expected_kwargs ) self.assertEqual(len(self.projects), update.call_count) + update.reset_mock() + + for kwarg in expected_kwargs: + kwarg['sql'] = False + kwarg['head'] = 'expand@head' + + self._main_test_helper( + ['prog', 'revision', '-m', 'message', '--expand'], + 'revision', + expected_kwargs + ) + self.assertEqual(len(self.projects), update.call_count) + update.reset_mock() + + for kwarg in expected_kwargs: + kwarg['head'] = 'contract@head' + + self._main_test_helper( + ['prog', 'revision', '-m', 'message', '--contract'], + 'revision', + expected_kwargs + ) + self.assertEqual(len(self.projects), update.call_count) def test_database_sync_revision(self): self._test_database_sync_revision() -- 2.45.2