Fix some minor issues due to premature merge of original code.

Consolidate duplicated code between delete() and force_delete(). Treat soft
deleted instances like hard deleted instances in queries. Fix running unit
tests individually do to using flags from a non-imported module.

blueprint deferred-delete-instance

Change-Id: Id58b607320536364867ee5c8d347b250406d9a2d
This commit is contained in:
Johannes Erdfelt
2011-09-25 22:23:15 +00:00
parent 8be1c68f80
commit 6c52cffab5
3 changed files with 42 additions and 28 deletions

View File

@@ -47,6 +47,7 @@ LOG = logging.getLogger('nova.compute.api')
FLAGS = flags.FLAGS
flags.DECLARE('vncproxy_topic', 'nova.vnc')
flags.DECLARE('reclaim_instance_interval', 'nova.compute.manager')
flags.DEFINE_integer('find_host_timeout', 30,
'Timeout after NN seconds when looking for a host.')
@@ -798,6 +799,20 @@ class API(base.Base):
terminate_volumes(self.db, context, instance_id)
self.db.instance_destroy(context, instance_id)
def _delete(self, context, instance):
host = instance['host']
if host:
self.update(context,
instance['id'],
task_state=task_states.DELETING,
progress=0)
self._cast_compute_message('terminate_instance', context,
instance['id'], host)
else:
terminate_volumes(self.db, context, instance['id'])
self.db.instance_destroy(context, instance['id'])
@scheduler_api.reroute_compute("delete")
def delete(self, context, instance_id):
"""Terminate an instance."""
@@ -807,17 +822,7 @@ class API(base.Base):
if not _is_able_to_shutdown(instance, instance_id):
return
host = instance['host']
if host:
self.update(context,
instance_id,
task_state=task_states.DELETING)
self._cast_compute_message('terminate_instance', context,
instance_id, host)
else:
terminate_volumes(self.db, context, instance_id)
self.db.instance_destroy(context, instance_id)
self._delete(context, instance)
@scheduler_api.reroute_compute("restore")
def restore(self, context, instance_id):
@@ -849,18 +854,7 @@ class API(base.Base):
if not _is_queued_delete(instance, instance_id):
return
self.update(context,
instance_id,
task_state=task_states.DELETING,
progress=0)
host = instance['host']
if host:
self._cast_compute_message('terminate_instance', context,
instance_id, host)
else:
terminate_volumes(self.db, context, instance_id)
self.db.instance_destroy(context, instance_id)
self._delete(context, instance)
@scheduler_api.reroute_compute("stop")
def stop(self, context, instance_id):

View File

@@ -1277,6 +1277,18 @@ def instance_get_all_by_filters(context, filters):
query_prefix = query_prefix.\
filter(models.Instance.updated_at > changes_since)
if 'deleted' in filters:
# Instances can be soft or hard deleted and the query needs to
# include or exclude both
if filters.pop('deleted'):
deleted = or_(models.Instance.deleted == True,
models.Instance.vm_state == vm_states.SOFT_DELETE)
query_prefix = query_prefix.filter(deleted)
else:
query_prefix = query_prefix.\
filter_by(deleted=False).\
filter(models.Instance.vm_state != vm_states.SOFT_DELETE)
if not context.is_admin:
# If we're not admin context, add appropriate filter..
if context.project_id:
@@ -1287,7 +1299,7 @@ def instance_get_all_by_filters(context, filters):
# Filters for exact matches that we can do along with the SQL query...
# For other filters that don't match this, we will do regexp matching
exact_match_filter_names = ['project_id', 'user_id', 'image_ref',
'vm_state', 'instance_type_id', 'deleted', 'uuid']
'vm_state', 'instance_type_id', 'uuid']
query_filters = [key for key in filters.iterkeys()
if key in exact_match_filter_names]

View File

@@ -507,10 +507,12 @@ class CloudTestCase(test.TestCase):
"""Makes sure describe_instances works and filters results."""
inst1 = db.instance_create(self.context, {'reservation_id': 'a',
'image_ref': 1,
'host': 'host1'})
'host': 'host1',
'vm_state': 'active'})
inst2 = db.instance_create(self.context, {'reservation_id': 'a',
'image_ref': 1,
'host': 'host2'})
'host': 'host2',
'vm_state': 'active'})
comp1 = db.service_create(self.context, {'host': 'host1',
'availability_zone': 'zone1',
'topic': "compute"})
@@ -535,9 +537,15 @@ class CloudTestCase(test.TestCase):
db.service_destroy(self.context, comp2['id'])
def test_describe_instances_deleted(self):
args1 = {'reservation_id': 'a', 'image_ref': 1, 'host': 'host1'}
args1 = {'reservation_id': 'a',
'image_ref': 1,
'host': 'host1',
'vm_state': 'active'}
inst1 = db.instance_create(self.context, args1)
args2 = {'reservation_id': 'b', 'image_ref': 1, 'host': 'host1'}
args2 = {'reservation_id': 'b',
'image_ref': 1,
'host': 'host1',
'vm_state': 'active'}
inst2 = db.instance_create(self.context, args2)
db.instance_destroy(self.context, inst1.id)
result = self.cloud.describe_instances(self.context)