Add blocker alembic migration for null root_provider_ids

This adds an alembic migration script which will block a db_sync
if the online data migration has not been run.

Change-Id: I74c49d286dfc62f49af24303ed1cb18489e7e89d
Story: 2005613
Task: 30921
This commit is contained in:
Matt Riedemann 2019-05-09 14:47:58 -04:00
parent 4af1df9408
commit 4606e55d19
2 changed files with 71 additions and 0 deletions

View File

@ -0,0 +1,42 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Block on null root_provider_id
Revision ID: 611cd6dffd7b
Revises: b4ed3a175331
Create Date: 2019-05-09 13:57:04.874293
"""
from alembic import context
import sqlalchemy as sa
from sqlalchemy import func as sqlfunc
from sqlalchemy import MetaData, Table, select
# revision identifiers, used by Alembic.
revision = '611cd6dffd7b'
down_revision = 'b4ed3a175331'
branch_labels = None
depends_on = None
def upgrade():
connection = context.get_bind()
metadata = MetaData(bind=connection)
resource_providers = Table('resource_providers', metadata, autoload=True)
query = select([sqlfunc.count()]).select_from(resource_providers).where(
resource_providers.c.root_provider_id == sa.null())
if connection.scalar(query):
raise Exception('There is at least one resource provider table '
'record which is missing its root provider id. '
'Run the "placement-manage db '
'online_data_migrations" command.')

View File

@ -28,8 +28,11 @@ from alembic import script
import mock
from oslo_db.sqlalchemy import test_fixtures
from oslo_db.sqlalchemy import test_migrations
from oslo_db.sqlalchemy import utils as db_utils
from oslo_log import log as logging
from oslo_utils.fixture import uuidsentinel as uuids
from oslotest import base as test_base
import six
import testtools
from placement.db.sqlalchemy import migration
@ -164,6 +167,32 @@ class MigrationCheckersMixin(object):
v2 = self.migration_api.version()
self.assertNotEqual(v1, v2)
def test_block_on_null_root_provider_id(self):
"""Upgrades the schema to b4ed3a175331 (initial), injects a resource
provider with no root provider and then tries to upgrade to head which
should fail on the 611cd6dffd7b blocker migration.
"""
# Upgrade to populate the schema.
self.migration_api.upgrade('b4ed3a175331')
# Now insert a resource provider with no root.
rps = db_utils.get_table(self.engine, 'resource_providers')
rp_id = rps.insert(values={
'name': 'fake-rp-name', 'uuid': uuids.rp_uuid
}).execute().inserted_primary_key[0]
# Now run the blocker migration and it should raise an error.
ex = self.assertRaises( # noqa H202
Exception, self.migration_api.upgrade, '611cd6dffd7b')
# Make sure it's the error we expect.
self.assertIn('There is at least one resource provider table '
'record which is missing its root provider id.',
six.text_type(ex))
# Now update the resource provider with a root_provider_id.
rps.update(
values={'root_provider_id': rp_id}).where(
rps.c.id == rp_id).execute()
# Re-run the upgrade and it should be OK.
self.migration_api.upgrade('611cd6dffd7b')
class PlacementOpportunisticFixture(object):
def get_enginefacade(self):