summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorJohannes Erdfelt <johannes.erdfelt@rackspace.com>2011-09-14 22:31:00 +0000
committerJohannes Erdfelt <johannes.erdfelt@rackspace.com>2011-09-14 22:31:00 +0000
commita5b339fb75e1e5f525a758ea1fb2fb35d1b9044a (patch)
tree27dfb0bf08b60206e606715a3aad580542b87e05 /nova
parented0d8bfd0fd7bbe81dd5e39683ec3e90fc86c16c (diff)
downloadnova-a5b339fb75e1e5f525a758ea1fb2fb35d1b9044a.tar.gz
nova-a5b339fb75e1e5f525a758ea1fb2fb35d1b9044a.tar.xz
nova-a5b339fb75e1e5f525a758ea1fb2fb35d1b9044a.zip
Cleanup state management to use vm_state instead of task_state
Add schedule_delete() method so delete() actually does what it says it does
Diffstat (limited to 'nova')
-rw-r--r--nova/api/ec2/cloud.py1
-rw-r--r--nova/api/openstack/common.py3
-rw-r--r--nova/api/openstack/servers.py10
-rw-r--r--nova/compute/api.py55
-rw-r--r--nova/compute/manager.py8
-rw-r--r--nova/compute/task_states.py4
-rw-r--r--nova/compute/vm_states.py1
7 files changed, 58 insertions, 24 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index 0efb90d6e..ee9d658e8 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -89,6 +89,7 @@ _STATE_DESCRIPTION_MAP = {
vm_states.BUILDING: 'pending',
vm_states.REBUILDING: 'pending',
vm_states.DELETED: 'terminated',
+ vm_states.SOFT_DELETE: 'terminated',
vm_states.STOPPED: 'stopped',
vm_states.MIGRATING: 'migrate',
vm_states.RESIZING: 'resize',
diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py
index a836a584c..66e18c557 100644
--- a/nova/api/openstack/common.py
+++ b/nova/api/openstack/common.py
@@ -78,6 +78,9 @@ _STATE_MAP = {
vm_states.DELETED: {
'default': 'DELETED',
},
+ vm_states.SOFT_DELETE: {
+ 'default': 'DELETED',
+ },
}
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py
index 5affd1f33..c81deb3ac 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/servers.py
@@ -169,6 +169,12 @@ class Controller(object):
server['server']['adminPass'] = extra_values['password']
return server
+ def _delete(self, context, id):
+ if FLAGS.reclaim_instance_interval:
+ self.compute_api.soft_delete(context, id)
+ else:
+ self.compute_api.delete(context, id)
+
@scheduler_api.redirect_handler
def update(self, req, id, body):
"""Update server then pass on to version-specific controller"""
@@ -566,7 +572,7 @@ class ControllerV10(Controller):
def delete(self, req, id):
""" Destroys a server """
try:
- self.compute_api.delete(req.environ['nova.context'], id)
+ self._delete(req.environ['nova.context'], id)
except exception.NotFound:
raise exc.HTTPNotFound()
return webob.Response(status_int=202)
@@ -644,7 +650,7 @@ class ControllerV11(Controller):
def delete(self, req, id):
""" Destroys a server """
try:
- self.compute_api.delete(req.environ['nova.context'], id)
+ self._delete(req.environ['nova.context'], id)
except exception.NotFound:
raise exc.HTTPNotFound()
diff --git a/nova/compute/api.py b/nova/compute/api.py
index ba314efb6..1a34b41a6 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -96,9 +96,9 @@ def _is_queued_delete(instance, instance_id):
vm_state = instance["vm_state"]
task_state = instance["task_state"]
- if task_state != task_states.QUEUED_DELETE:
- LOG.warn(_("Instance %(instance_id)s is not in a 'queued deleted' "
- "state. It is currently %(task_state)s. Action aborted.") %
+ if vm_state != vm_states.SOFT_DELETE:
+ LOG.warn(_("Instance %(instance_id)s is not in a 'soft delete' "
+ "state. It is currently %(vm_state)s. Action aborted.") %
locals())
return False
@@ -764,36 +764,54 @@ class API(base.Base):
{'instance_id': instance_id, 'action_str': action_str})
raise
- @scheduler_api.reroute_compute("delete")
- def delete(self, context, instance_id):
+ @scheduler_api.reroute_compute("soft_delete")
+ def soft_delete(self, context, instance_id):
"""Terminate an instance."""
- LOG.debug(_("Going to try to terminate %s"), instance_id)
- instance = self._get_instance(context, instance_id, 'terminating')
+ LOG.debug(_("Going to try to soft delete %s"), instance_id)
+ instance = self._get_instance(context, instance_id, 'soft delete')
if not _is_able_to_shutdown(instance, instance_id):
return
+ # NOTE(jerdfelt): The compute daemon handles reclaiming instances
+ # that are in soft delete. If there is no host assigned, there is
+ # no daemon to reclaim, so delete it immediately.
host = instance['host']
- if FLAGS.reclaim_instance_interval and host:
+ if host:
self.update(context,
instance_id,
- vm_state=vm_states.DELETED,
- task_state=task_states.QUEUED_DELETE,
+ vm_state=vm_states.SOFT_DELETE,
+ task_state=task_states.POWERING_OFF,
deleted_at=utils.utcnow())
self._cast_compute_message('power_off_instance', context,
- instance_id, host)
+ instance_id, host)
else:
+ LOG.warning(_("No host for instance %s, deleting immediately"),
+ instance_id)
+ 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."""
+ LOG.debug(_("Going to try to terminate %s"), instance_id)
+ instance = self._get_instance(context, instance_id, 'delete')
+
+ 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)
- 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._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("restore")
def restore(self, context, instance_id):
@@ -811,6 +829,9 @@ class API(base.Base):
host = instance['host']
if host:
+ self.update(context,
+ instance_id,
+ task_state=task_states.POWERING_ON)
self._cast_compute_message('power_on_instance', context,
instance_id, host)
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 91236dd3c..3692be922 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -531,7 +531,8 @@ class ComputeManager(manager.SchedulerDependentManager):
current_power_state = self._get_power_state(context, instance)
self._instance_update(context,
instance_id,
- power_state=current_power_state)
+ power_state=current_power_state,
+ task_state=None)
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
@checks_instance_lock
@@ -542,7 +543,8 @@ class ComputeManager(manager.SchedulerDependentManager):
current_power_state = self._get_power_state(context, instance)
self._instance_update(context,
instance_id,
- power_state=current_power_state)
+ power_state=current_power_state,
+ task_state=None)
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
@checks_instance_lock
@@ -1755,7 +1757,7 @@ class ComputeManager(manager.SchedulerDependentManager):
seconds=FLAGS.reclaim_instance_interval)
curtime = utils.utcnow()
for instance in instances:
- if instance['task_state'] == task_states.QUEUED_DELETE and \
+ if instance['vm_state'] == vm_states.SOFT_DELETE and \
(curtime - instance['deleted_at']) >= queue_time:
LOG.info('Deleting %s' % instance['name'])
self._delete_instance(context, instance['id'])
diff --git a/nova/compute/task_states.py b/nova/compute/task_states.py
index 0337b2641..b52140bf8 100644
--- a/nova/compute/task_states.py
+++ b/nova/compute/task_states.py
@@ -50,12 +50,12 @@ PAUSING = 'pausing'
UNPAUSING = 'unpausing'
SUSPENDING = 'suspending'
RESUMING = 'resuming'
+POWERING_OFF = 'powering-off'
+POWERING_ON = 'powering-on'
RESCUING = 'rescuing'
UNRESCUING = 'unrescuing'
-QUEUED_DELETE = 'queued_delete'
-
DELETING = 'deleting'
STOPPING = 'stopping'
STARTING = 'starting'
diff --git a/nova/compute/vm_states.py b/nova/compute/vm_states.py
index 6f16c1f09..f219bf7f4 100644
--- a/nova/compute/vm_states.py
+++ b/nova/compute/vm_states.py
@@ -32,6 +32,7 @@ SUSPENDED = 'suspended'
RESCUED = 'rescued'
DELETED = 'deleted'
STOPPED = 'stopped'
+SOFT_DELETE = 'soft-delete'
MIGRATING = 'migrating'
RESIZING = 'resizing'