]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Tag the alembic migration revisions for Liberty
authorHenry Gessau <gessau@cisco.com>
Sun, 27 Sep 2015 19:36:59 +0000 (15:36 -0400)
committerHenry Gessau <gessau@cisco.com>
Tue, 29 Sep 2015 14:48:29 +0000 (10:48 -0400)
Previously when we had one repo with one alembic branch we would
create a milestone revision on that single branch. Now we have
multiple repos and expand/contract branches for each repo.

So from now on we tag the final revision on every branch when we make
a milestone release. Update the cli to support the command:
  neutron-db-manage upgrade <milestone>
where <milestone> becomes an alias for all the revisions for a
milestone.

Partial-Bug: #1499033

Change-Id: I38623986dd574bec01fe147f9c6a747f3f512bb7

neutron/db/migration/__init__.py
neutron/db/migration/alembic_migrations/versions/liberty/contract/4af11ca47297_drop_cisco_monolithic_tables.py
neutron/db/migration/alembic_migrations/versions/liberty/expand/34af2b5c5a59_add_dns_name_to_port.py
neutron/db/migration/cli.py
neutron/tests/unit/db/test_migration.py

index 5561e884d59b765daff15f82afdfde05d921c920..81b491083083b4fe19a39bf33ff216e65437cd35 100644 (file)
@@ -21,6 +21,13 @@ from alembic import op
 import sqlalchemy as sa
 from sqlalchemy.engine import reflection
 
+# Neutron milestones for upgrade aliases
+LIBERTY = 'liberty'
+
+NEUTRON_MILESTONES = [
+    # earlier milestones were not tagged
+    LIBERTY,
+]
 
 CREATION_OPERATIONS = (sa.sql.ddl.CreateIndex,
                        sa.sql.ddl.CreateTable,
index ee39fa9529143baa03da037989d67540f2d8a01d..7a91b79b31e798543ff768e4243f35a77f2fccff 100644 (file)
@@ -21,11 +21,17 @@ Create Date: 2015-08-13 08:01:19.709839
 
 """
 
+from alembic import op
+
+from neutron.db import migration
+
+
 # revision identifiers, used by Alembic.
 revision = '4af11ca47297'
 down_revision = '11926bcfe72d'
 
-from alembic import op
+# milestone identifier, used by neutron-db-manage
+neutron_milestone = [migration.LIBERTY]
 
 
 def upgrade():
index ba523ae655b99c68e6746aeefbe509c1aab25d77..3b2707c74b9039cd2c2cb772e536998e70e62b6e 100644 (file)
@@ -21,16 +21,21 @@ Create Date: 2015-08-23 00:22:47.618593
 
 """
 
-# revision identifiers, used by Alembic.
-revision = '34af2b5c5a59'
-down_revision = '9859ac9c136'
-
 from alembic import op
 import sqlalchemy as sa
 
+from neutron.db import migration
 from neutron.extensions import dns
 
 
+# revision identifiers, used by Alembic.
+revision = '34af2b5c5a59'
+down_revision = '9859ac9c136'
+
+# milestone identifier, used by neutron-db-manage
+neutron_milestone = [migration.LIBERTY]
+
+
 def upgrade():
     op.add_column('ports',
                   sa.Column('dns_name',
index c04205e443386c0c0440603f482ae9bcc70b77d0..b998a082c004330153513ed695944ac97b500e6d 100644 (file)
@@ -26,11 +26,12 @@ from oslo_utils import importutils
 import pkg_resources
 
 from neutron.common import utils
+from neutron.db import migration
 
 
 HEAD_FILENAME = 'HEAD'
 HEADS_FILENAME = 'HEADS'
-CURRENT_RELEASE = "liberty"
+CURRENT_RELEASE = migration.LIBERTY
 
 EXPAND_BRANCH = 'expand'
 CONTRACT_BRANCH = 'contract'
@@ -131,8 +132,20 @@ def add_alembic_subparser(sub, cmd):
     return sub.add_parser(cmd, help=getattr(alembic_command, cmd).__doc__)
 
 
+def _find_milestone_revisions(config, milestone, branch=None):
+    """Return the revision(s) for a given milestone."""
+    script = alembic_script.ScriptDirectory.from_config(config)
+    return [
+        (m.revision, label)
+        for m in _get_revisions(script)
+        for label in (m.branch_labels or [None])
+        if milestone in getattr(m.module, 'neutron_milestone', []) and
+        (branch is None or branch in m.branch_labels)
+    ]
+
+
 def do_upgrade(config, cmd):
-    desc = None
+    branch = None
 
     if ((CONF.command.revision or CONF.command.delta) and
         (CONF.command.expand or CONF.command.contract)):
@@ -140,11 +153,11 @@ def do_upgrade(config, cmd):
             'Phase upgrade options do not accept revision specification'))
 
     if CONF.command.expand:
-        desc = EXPAND_BRANCH
+        branch = EXPAND_BRANCH
         revision = _get_branch_head(EXPAND_BRANCH)
 
     elif CONF.command.contract:
-        desc = CONTRACT_BRANCH
+        branch = CONTRACT_BRANCH
         revision = _get_branch_head(CONTRACT_BRANCH)
 
     elif not CONF.command.revision and not CONF.command.delta:
@@ -170,10 +183,16 @@ def do_upgrade(config, cmd):
         if revision == 'head':
             revision = 'heads'
 
-    if not CONF.command.sql:
-        run_sanity_checks(config, revision)
-    do_alembic_command(config, cmd, revision=revision,
-                       desc=desc, sql=CONF.command.sql)
+    if revision in migration.NEUTRON_MILESTONES:
+        revisions = _find_milestone_revisions(config, revision, branch)
+    else:
+        revisions = [(revision, branch)]
+
+    for revision, branch in revisions:
+        if not CONF.command.sql:
+            run_sanity_checks(config, revision)
+        do_alembic_command(config, cmd, revision=revision,
+                           desc=branch, sql=CONF.command.sql)
 
 
 def no_downgrade(config, cmd):
index a2129f567071cad678eefd9650cae892a1a68f6e..d5e0eda7581926ac06e7077214a8c32c303a8141 100644 (file)
@@ -49,6 +49,7 @@ class FakeRevision(object):
         self.down_revision = down_revision
         self.is_branch_point = is_branch_point
         self.revision = tools.get_random_string()
+        self.module = mock.MagicMock()
 
 
 class MigrationEntrypointsMemento(fixtures.Fixture):
@@ -643,6 +644,45 @@ class TestCli(base.BaseTestCase):
     def test__use_separate_migration_branches_with_branch_points(self, *mocks):
         self.assertTrue(cli._use_separate_migration_branches(self.configs[0]))
 
+    @mock.patch('alembic.script.ScriptDirectory.walk_revisions')
+    def test__find_milestone_revisions_one_branch(self, walk_mock):
+        c_revs = [FakeRevision(labels={cli.CONTRACT_BRANCH}) for r in range(5)]
+        c_revs[1].module.neutron_milestone = [migration.LIBERTY]
+
+        walk_mock.return_value = c_revs
+        m = cli._find_milestone_revisions(self.configs[0], 'liberty',
+                                          cli.CONTRACT_BRANCH)
+        self.assertEqual(1, len(m))
+        m = cli._find_milestone_revisions(self.configs[0], 'liberty',
+                                          cli.EXPAND_BRANCH)
+        self.assertEqual(0, len(m))
+
+    @mock.patch('alembic.script.ScriptDirectory.walk_revisions')
+    def test__find_milestone_revisions_two_branches(self, walk_mock):
+        c_revs = [FakeRevision(labels={cli.CONTRACT_BRANCH}) for r in range(5)]
+        c_revs[1].module.neutron_milestone = [migration.LIBERTY]
+        e_revs = [FakeRevision(labels={cli.EXPAND_BRANCH}) for r in range(5)]
+        e_revs[3].module.neutron_milestone = [migration.LIBERTY]
+
+        walk_mock.return_value = c_revs + e_revs
+        m = cli._find_milestone_revisions(self.configs[0], 'liberty')
+        self.assertEqual(2, len(m))
+
+        m = cli._find_milestone_revisions(self.configs[0], 'mitaka')
+        self.assertEqual(0, len(m))
+
+    @mock.patch('alembic.script.ScriptDirectory.walk_revisions')
+    def test__find_milestone_revisions_branchless(self, walk_mock):
+        revisions = [FakeRevision() for r in range(5)]
+        revisions[2].module.neutron_milestone = [migration.LIBERTY]
+
+        walk_mock.return_value = revisions
+        m = cli._find_milestone_revisions(self.configs[0], 'liberty')
+        self.assertEqual(1, len(m))
+
+        m = cli._find_milestone_revisions(self.configs[0], 'mitaka')
+        self.assertEqual(0, len(m))
+
 
 class TestSafetyChecks(base.BaseTestCase):