Merge "Fix hard-delete of instance with soft-deleted referential constraints"

This commit is contained in:
Zuul 2019-05-30 05:55:07 +00:00 committed by Gerrit Code Review
commit d6a699ca1d
2 changed files with 21 additions and 3 deletions

View File

@ -1792,7 +1792,11 @@ def instance_destroy(context, instance_uuid, constraint=None,
key = 'instance_uuid' if model not in filtered_by_uuid else 'uuid'
filter_ = {key: instance_uuid}
if hard_delete:
model_query(context, model).filter_by(**filter_).delete()
# We need to read any soft-deleted related records to make sure
# and clean those up as well otherwise we can fail with ForeignKey
# constraint errors when hard deleting the instance.
model_query(context, model, read_deleted='yes').filter_by(
**filter_).delete()
else:
model_query(context, model).filter_by(**filter_).soft_delete()

View File

@ -3070,13 +3070,27 @@ class InstanceTestCase(test.TestCase, ModelsObjectComparatorMixin):
bdm_values = {
'instance_uuid': uuid,
'device_name': 'fake_device',
'device_name': '/dev/vda',
'source_type': 'volume',
'destination_type': 'volume',
}
block_dev = block_device.BlockDeviceDict(bdm_values)
db.block_device_mapping_create(self.ctxt, block_dev, legacy=False)
# Crate a second BDM that is soft-deleted to simulate that the
# volume was detached and the BDM was deleted before the instance
# was hard destroyed.
bdm2_values = {
'instance_uuid': uuid,
'device_name': '/dev/vdb',
'source_type': 'volume',
'destination_type': 'volume',
}
block_dev2 = block_device.BlockDeviceDict(bdm2_values)
bdm2 = db.block_device_mapping_create(
self.ctxt, block_dev2, legacy=False)
db.block_device_mapping_destroy(self.ctxt, bdm2.id)
migration_values = {
"status": "finished",
"instance_uuid": uuid,
@ -3122,7 +3136,7 @@ class InstanceTestCase(test.TestCase, ModelsObjectComparatorMixin):
self.assertEqual(0, len(instance_faults[uuid]))
inst_bdms = db.block_device_mapping_get_all_by_instance(ctxt, uuid)
self.assertEqual(0, len(inst_bdms))
filters = {"isntance_uuid": uuid}
filters = {"instance_uuid": uuid}
inst_migrations = db.migration_get_all_by_filters(ctxt, filters)
self.assertEqual(0, len(inst_migrations))
vifs = db.virtual_interface_get_by_instance(ctxt, uuid)