Skip soft-deleted records in 330_enforce_mitaka_online_migrations
The 330_enforce_mitaka_online_migrations migration considers soft-deleted records as unmigrated (the blocker migration uses the select function from sqlalchemy), but the online migrations only migrate non-deleted records (the migrations use the model_query function which defaults to read_deleted='no'). So even after running all of the online migrations, operators can get stuck until they can hard delete any soft-deleted compute_nodes, aggregates, and pci_devices records they have. Closes-Bug: #1665719 Change-Id: I2285005098b7dab7753366f53667ff8d4532d668
This commit is contained in:
parent
227a4dff25
commit
6d64b72744
|
@ -10,7 +10,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from sqlalchemy import MetaData, Table, func, select
|
from sqlalchemy import MetaData, Table, and_, func, select
|
||||||
|
|
||||||
from nova import exception
|
from nova import exception
|
||||||
from nova.i18n import _
|
from nova.i18n import _
|
||||||
|
@ -27,8 +27,9 @@ def upgrade(migrate_engine):
|
||||||
aggregates = Table('aggregates', meta, autoload=True)
|
aggregates = Table('aggregates', meta, autoload=True)
|
||||||
|
|
||||||
for table in (compute_nodes, aggregates):
|
for table in (compute_nodes, aggregates):
|
||||||
count = select([func.count()]).select_from(table).where(
|
count = select([func.count()]).select_from(table).where(and_(
|
||||||
table.c.uuid == None).execute().scalar() # NOQA
|
table.c.deleted == 0,
|
||||||
|
table.c.uuid == None)).execute().scalar() # NOQA
|
||||||
if count > 0:
|
if count > 0:
|
||||||
msg = WARNING_MSG % {
|
msg = WARNING_MSG % {
|
||||||
'count': count,
|
'count': count,
|
||||||
|
@ -37,8 +38,9 @@ def upgrade(migrate_engine):
|
||||||
raise exception.ValidationError(detail=msg)
|
raise exception.ValidationError(detail=msg)
|
||||||
|
|
||||||
pci_devices = Table('pci_devices', meta, autoload=True)
|
pci_devices = Table('pci_devices', meta, autoload=True)
|
||||||
count = select([func.count()]).select_from(pci_devices).where(
|
count = select([func.count()]).select_from(pci_devices).where(and_(
|
||||||
pci_devices.c.parent_addr == None).execute().scalar() # NOQA
|
pci_devices.c.deleted == 0,
|
||||||
|
pci_devices.c.parent_addr == None)).execute().scalar() # NOQA
|
||||||
if count > 0:
|
if count > 0:
|
||||||
msg = WARNING_MSG % {
|
msg = WARNING_MSG % {
|
||||||
'count': count,
|
'count': count,
|
||||||
|
|
|
@ -281,6 +281,31 @@ class TestNewtonCheck(test.TestCase):
|
||||||
self.assertRaises(exception.ValidationError,
|
self.assertRaises(exception.ValidationError,
|
||||||
self.migration.upgrade, self.engine)
|
self.migration.upgrade, self.engine)
|
||||||
|
|
||||||
|
def test_deleted_not_migrated(self):
|
||||||
|
cn_values = dict(vcpus=1, memory_mb=512, local_gb=10,
|
||||||
|
vcpus_used=0, memory_mb_used=256,
|
||||||
|
local_gb_used=5, hypervisor_type='HyperDanVM',
|
||||||
|
hypervisor_version='34', cpu_info='foo')
|
||||||
|
cn = db_api.compute_node_create(self.context, cn_values)
|
||||||
|
agg_values = dict(name='foo')
|
||||||
|
agg = db_api.aggregate_create(self.context, agg_values)
|
||||||
|
pd = db_api.pci_device_update(self.context, 1, 'foo:bar',
|
||||||
|
{'parent_addr': None,
|
||||||
|
'compute_node_id': 1,
|
||||||
|
'address': 'foo:bar',
|
||||||
|
'vendor_id': '123',
|
||||||
|
'product_id': '456',
|
||||||
|
'dev_type': 'foo',
|
||||||
|
'label': 'foobar',
|
||||||
|
'status': 'whatisthis?'})
|
||||||
|
db_api.compute_node_delete(self.context, cn['id'])
|
||||||
|
db_api.aggregate_delete(self.context, agg['id'])
|
||||||
|
db_api.pci_device_destroy(self.context, pd['compute_node_id'],
|
||||||
|
pd['address'])
|
||||||
|
|
||||||
|
# blocker should not block on soft-deleted records
|
||||||
|
self.migration.upgrade(self.engine)
|
||||||
|
|
||||||
|
|
||||||
class TestOcataCheck(test.TestCase):
|
class TestOcataCheck(test.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
Loading…
Reference in New Issue