From f3a280959a0237fc3b0f3eeaaa3154566f8620c0 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Mon, 28 Nov 2016 07:24:21 -0800 Subject: [PATCH] Check deleted flag in Instance.create() An attempt to create an instance with the deleted flag set will not work as intended, especially from instance.create(), which can't properly pass the yet-to-be-determined deleted=id protocol. This makes Instance.create() throw an error like the one for being already created, and fixes the one test where we depend on this working. Change-Id: I60d18ca694a2eb7f333c0cf2a898cf8f17eb83dd Closes-Bug: #1644513 --- nova/objects/instance.py | 3 +++ nova/tests/unit/compute/test_compute.py | 12 ++++++++---- nova/tests/unit/network/test_manager.py | 2 +- nova/tests/unit/objects/test_instance.py | 7 +++++++ 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/nova/objects/instance.py b/nova/objects/instance.py index 7fd0087071..b9068bccbd 100644 --- a/nova/objects/instance.py +++ b/nova/objects/instance.py @@ -479,6 +479,9 @@ class Instance(base.NovaPersistentObject, base.NovaObject, if self.obj_attr_is_set('id'): raise exception.ObjectActionError(action='create', reason='already created') + if self.obj_attr_is_set('deleted') and self.deleted: + raise exception.ObjectActionError(action='create', + reason='already deleted') updates = self.obj_get_changes() expected_attrs = [attr for attr in INSTANCE_DEFAULT_FIELDS if attr in updates] diff --git a/nova/tests/unit/compute/test_compute.py b/nova/tests/unit/compute/test_compute.py index 782376df0f..8a392ea0fe 100644 --- a/nova/tests/unit/compute/test_compute.py +++ b/nova/tests/unit/compute/test_compute.py @@ -6279,10 +6279,14 @@ class ComputeTestCase(BaseTestCase): admin_context = context.get_admin_context() deleted_at = (timeutils.utcnow() - datetime.timedelta(hours=1, minutes=5)) - instance1 = self._create_fake_instance_obj({"deleted_at": deleted_at, - "deleted": True}) - instance2 = self._create_fake_instance_obj({"deleted_at": deleted_at, - "deleted": True}) + instance1 = self._create_fake_instance_obj() + instance2 = self._create_fake_instance_obj() + + timeutils.set_time_override(deleted_at) + instance1.destroy() + instance2.destroy() + timeutils.clear_time_override() + self.flags(running_deleted_instance_timeout=3600, running_deleted_instance_action=action) diff --git a/nova/tests/unit/network/test_manager.py b/nova/tests/unit/network/test_manager.py index fd20a25e60..721400e107 100644 --- a/nova/tests/unit/network/test_manager.py +++ b/nova/tests/unit/network/test_manager.py @@ -3006,8 +3006,8 @@ class FloatingIPTestCase(test.TestCase): lambda *args, **kwargs: None) instance = objects.Instance(context=self.context) instance.project_id = self.project_id - instance.deleted = True instance.create() + instance.destroy() network = db.network_create_safe(self.context.elevated(), { 'project_id': self.project_id, 'host': CONF.host, diff --git a/nova/tests/unit/objects/test_instance.py b/nova/tests/unit/objects/test_instance.py index d2f98af89d..e166008f52 100644 --- a/nova/tests/unit/objects/test_instance.py +++ b/nova/tests/unit/objects/test_instance.py @@ -1058,6 +1058,13 @@ class _TestInstanceObject(object): inst2 = objects.Instance.get_by_uuid(self.context, inst1.uuid) self.assertEqual('foo-host', inst2.host) + def test_create_deleted(self): + inst1 = objects.Instance(context=self.context, + user_id=self.context.user_id, + project_id=self.context.project_id, + deleted=True) + self.assertRaises(exception.ObjectActionError, inst1.create) + def test_create_with_extras(self): inst = objects.Instance(context=self.context, uuid=self.fake_instance['uuid'], -- 2.39.5