From c3cbf16fd1276f5de57d8970f1a033e1fc51e912 Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Mon, 13 Aug 2018 08:34:34 -0400 Subject: [PATCH] Delete instance_id_mappings record in instance_destroy The instance_create DB API creates an instance_id_mappings record but instance_destroy was not cleaning it up when the instance is deleted; this adds that delete code. Otherwise those records never get moved to shadow tables so you can't archive and purge them. Change-Id: Idfe52d3c2f987b9aac551f013a0990423d87fad3 Closes-Bug: #1786298 --- nova/db/sqlalchemy/api.py | 2 ++ nova/tests/unit/db/test_db_api.py | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 59f0a8c..5384a07 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1819,6 +1819,8 @@ def instance_destroy(context, instance_uuid, constraint=None): model_query(context, models.Migration).\ filter_by(instance_uuid=instance_uuid).\ soft_delete() + model_query(context, models.InstanceIdMapping).filter_by( + uuid=instance_uuid).soft_delete() # NOTE(snikitin): We can't use model_query here, because there is no # column 'deleted' in 'tags' or 'console_auth_tokens' tables. context.session.query(models.Tag).filter_by( diff --git a/nova/tests/unit/db/test_db_api.py b/nova/tests/unit/db/test_db_api.py index cc87bfb..5c180ff 100644 --- a/nova/tests/unit/db/test_db_api.py +++ b/nova/tests/unit/db/test_db_api.py @@ -2864,6 +2864,20 @@ class InstanceTestCase(test.TestCase, ModelsObjectComparatorMixin): self.assertEqual({}, db.instance_metadata_get(ctxt, inst_uuid)) self.assertEqual([], db.instance_tag_get_by_instance_uuid( ctxt, inst_uuid)) + + @sqlalchemy_api.pick_context_manager_reader + def _assert_instance_id_mapping(_ctxt): + # NOTE(mriedem): We can't use ec2_instance_get_by_uuid to assert + # the instance_id_mappings record is gone because it hard-codes + # read_deleted='yes' and will read the soft-deleted record. So we + # do the model_query directly here. See bug 1061166. + inst_id_mapping = sqlalchemy_api.model_query( + _ctxt, models.InstanceIdMapping).filter_by( + uuid=inst_uuid).first() + self.assertFalse(inst_id_mapping, + 'instance_id_mapping not deleted for ' + 'instance: %s' % inst_uuid) + _assert_instance_id_mapping(ctxt) ctxt.read_deleted = 'yes' self.assertEqual(values['system_metadata'], db.instance_system_metadata_get(ctxt, inst_uuid)) -- 2.7.4