neutron-db-manage: sync HEADS file with 'current' output

alembic.get_heads() returns all heads for all branches it can find in
scripts dir, while in alembic_version table, it does not store any heads
that were overridden by other branches, even if those depends_on it
instead of having it as down_revision.

To keep 'current' output in sync with what is in HEADS file, we can
attach liberty_* branches explicitly to kilo revision.

It's also a good idea to have a separate 'heads' command that would show
the latest alembic heads based on scripts dir state. See [1] for more
details.

While at it, since different subprojects can link their expand/contract
branches to kilo in different way (some using depends_on the previous
release branch, while others, as suggested in this patch, thru
down_revision to kilo), we kill the check on the number of heads
returned by script.get_heads() since it may differ. If we want to
validate that we don't branch more than twice from kilo, we may add a
separate validation just for that.

[1]: https://review.openstack.org/#/c/204551/

Change-Id: If551633ab26e0eac549c1e13cfa0771383a1a060
Partially-Implements: blueprint online-schema-migrations
This commit is contained in:
Ihar Hrachyshka 2015-08-20 11:50:09 +02:00
parent 194489b0f4
commit 905064eb61
5 changed files with 3 additions and 22 deletions

View File

@ -1,3 +1,2 @@
2a16083502f3
9859ac9c136
kilo

View File

@ -21,8 +21,7 @@ Create Date: 2015-06-22 00:00:00.000000
# revision identifiers, used by Alembic.
revision = '30018084ec99'
down_revision = None
depends_on = ('kilo',)
down_revision = 'kilo'
branch_labels = ('liberty_contract',)

View File

@ -23,9 +23,8 @@ Create Date: 2015-04-19 14:59:15.102609
# revision identifiers, used by Alembic.
revision = '354db87e3225'
down_revision = None
down_revision = 'kilo'
branch_labels = ('liberty_expand',)
depends_on = ('kilo',)
from alembic import op
import sqlalchemy as sa

View File

@ -255,12 +255,7 @@ def validate_labels(config):
def _get_sorted_heads(script):
'''Get the list of heads for all branches, sorted.'''
heads = script.get_heads()
# +1 stands for the core 'kilo' branch, the one that didn't have branches
if len(heads) > len(MIGRATION_BRANCHES) + 1:
alembic_util.err(_('No new branches are allowed except: %s') %
' '.join(MIGRATION_BRANCHES))
return sorted(heads)
return sorted(script.get_heads())
def validate_heads_file(config):

View File

@ -324,17 +324,6 @@ class TestCli(base.BaseTestCase):
mock_open.return_value.write.assert_called_once_with(
'\n'.join(sorted(heads)))
def test_update_heads_file_excessive_heads_negative(self):
with mock.patch('alembic.script.ScriptDirectory.from_config') as fc:
heads = ('b', 'a', 'c', 'kilo')
fc.return_value.get_heads.return_value = heads
self.assertRaises(
SystemExit,
cli.update_heads_file,
mock.sentinel.config
)
self.mock_alembic_err.assert_called_once_with(mock.ANY)
@mock.patch('os.path.exists')
@mock.patch('os.remove')
def test_update_heads_file_success(self, *os_mocks):