From 385284dad93ea3d2f6e41b60c133250b78e9680f Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Tue, 30 Jun 2015 15:09:26 -0700 Subject: [PATCH] Block subtractive operations in migrations for Kilo and beyond In Kilo, we made a point to not allow any subtractive DB migrations. That gave us a lot of flexibility for upgrades from Juno. Reviewers did the awesome job of keeping to that plan. However, we need a mechanical filter to prevent regressions. This adds that in the form of a banned-ops fixture in test_migrations. It excludes migrations from pre-Kilo times, as well as excludes a few migrations that are already in place and do reaspnable things. In general, we need to be extremely careful about letting migrations put themselves on the exclusion list, so I added scary words around it. Change-Id: Iefe678d0aeb1ad898fc5a0cee10fd55ccb7e06db --- nova/tests/fixtures.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/nova/tests/fixtures.py b/nova/tests/fixtures.py index 88c258678..a922aa7dc 100644 --- a/nova/tests/fixtures.py +++ b/nova/tests/fixtures.py @@ -29,6 +29,7 @@ import six from nova.db import migration from nova.db.sqlalchemy import api as session +from nova import exception from nova.objects import base as obj_base from nova import rpc from nova import service @@ -412,3 +413,26 @@ class SpawnIsSynchronousFixture(fixtures.Fixture): super(SpawnIsSynchronousFixture, self).setUp() self.useFixture(fixtures.MonkeyPatch( 'nova.utils.spawn_n', lambda f, *a, **k: f(*a, **k))) + + +class BannedDBSchemaOperations(fixtures.Fixture): + """Ban some operations for migrations""" + def __init__(self, banned_resources=None): + super(BannedDBSchemaOperations, self).__init__() + self._banned_resources = banned_resources or [] + + @staticmethod + def _explode(resource, op): + raise exception.DBNotAllowed( + 'Operation %s.%s() is not allowed in a database migration' % ( + resource, op)) + + def setUp(self): + super(BannedDBSchemaOperations, self).setUp() + for thing in self._banned_resources: + self.useFixture(fixtures.MonkeyPatch( + 'sqlalchemy.%s.drop' % thing, + lambda *a, **k: self._explode(thing, 'drop'))) + self.useFixture(fixtures.MonkeyPatch( + 'sqlalchemy.%s.alter' % thing, + lambda *a, **k: self._explode(thing, 'alter')))