From 6186996c8093e723bdaa0e06664143685050312d Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Tue, 14 Aug 2018 11:05:06 +0800 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 (cherry picked from commit 8a6b57cf741e17d3de54ed8c85d9fb69c43e7432) --- 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 95a5cca4584b..5273045f82f8 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 cc87bfbd5111..5c180ff74b6a 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))