]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Allow to specify branch for creating new migration
authorYuji <azama-yuji@mxe.nes.nec.co.jp>
Wed, 16 Sep 2015 02:45:27 +0000 (11:45 +0900)
committerHenry Gessau <gessau@cisco.com>
Thu, 22 Oct 2015 15:50:32 +0000 (11:50 -0400)
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
neutron/db/migration/cli.py
neutron/tests/unit/db/test_migration.py

index 65dd63bc332930c01106a5eda43f3143576c3de0..1fdc9aeb9eabc2858ed7ace8f3880e7e203f9f7b 100644 (file)
@@ -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
index d2edc9d54e8d2e02c89f9486964087e559e0bc3b..7a2fbbeb482a77700f1a4033972abeaa9bbffd54 100644 (file)
@@ -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)
 
 
index 62b794bedc3a70846484528c2db9446af107eb1d..c57bd3a564f3d04ed8c0999b99bd2950be7b0f4c 100644 (file)
@@ -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()