summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Lamar <brian.lamar@rackspace.com>2011-03-28 13:19:16 -0400
committerBrian Lamar <brian.lamar@rackspace.com>2011-03-28 13:19:16 -0400
commitba3bf6a57154fd94ae4279a8e53467f65cd4585f (patch)
tree0ca46668fb6a18d3165448b23ceccfbfecbe870c
parent56b4dd3929448585c15c8d11c5fe1569ce21ea7d (diff)
parentc3c86f994413792cf582df86cf5e16f788005bed (diff)
downloadnova-ba3bf6a57154fd94ae4279a8e53467f65cd4585f.tar.gz
nova-ba3bf6a57154fd94ae4279a8e53467f65cd4585f.tar.xz
nova-ba3bf6a57154fd94ae4279a8e53467f65cd4585f.zip
Merged trunk.
-rw-r--r--nova/compute/manager.py40
-rw-r--r--nova/tests/api/openstack/test_images.py13
-rw-r--r--nova/tests/test_auth.py8
-rw-r--r--nova/virt/driver.py4
4 files changed, 46 insertions, 19 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 468771f46..e0a5e2b3f 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -141,12 +141,6 @@ class ComputeManager(manager.SchedulerDependentManager):
"""
self.driver.init_host(host=self.host)
- def periodic_tasks(self, context=None):
- """Tasks to be run at a periodic interval."""
- super(ComputeManager, self).periodic_tasks(context)
- if FLAGS.rescue_timeout > 0:
- self.driver.poll_rescued_instances(FLAGS.rescue_timeout)
-
def _update_state(self, context, instance_id):
"""Update the state of an instance from the driver info."""
# FIXME(ja): include other fields from state?
@@ -1033,11 +1027,20 @@ class ComputeManager(manager.SchedulerDependentManager):
error_list = []
try:
+ if FLAGS.rescue_timeout > 0:
+ self.driver.poll_rescued_instances(FLAGS.rescue_timeout)
+ except Exception as ex:
+ LOG.warning(_("Error during poll_rescued_instances: %s"),
+ unicode(ex))
+ error_list.append(ex)
+
+ try:
self._poll_instance_states(context)
except Exception as ex:
LOG.warning(_("Error during instance poll: %s"),
unicode(ex))
error_list.append(ex)
+
return error_list
def _poll_instance_states(self, context):
@@ -1051,16 +1054,33 @@ class ComputeManager(manager.SchedulerDependentManager):
for db_instance in db_instances:
name = db_instance['name']
+ db_state = db_instance['state']
vm_instance = vm_instances.get(name)
+
if vm_instance is None:
- LOG.info(_("Found instance '%(name)s' in DB but no VM. "
- "Setting state to shutoff.") % locals())
- vm_state = power_state.SHUTOFF
+ # NOTE(justinsb): We have to be very careful here, because a
+ # concurrent operation could be in progress (e.g. a spawn)
+ if db_state == power_state.NOSTATE:
+ # Assume that NOSTATE => spawning
+ # TODO(justinsb): This does mean that if we crash during a
+ # spawn, the machine will never leave the spawning state,
+ # but this is just the way nova is; this function isn't
+ # trying to correct that problem.
+ # We could have a separate task to correct this error.
+ # TODO(justinsb): What happens during a live migration?
+ LOG.info(_("Found instance '%(name)s' in DB but no VM. "
+ "State=%(db_state)s, so assuming spawn is in "
+ "progress.") % locals())
+ vm_state = db_state
+ else:
+ LOG.info(_("Found instance '%(name)s' in DB but no VM. "
+ "State=%(db_state)s, so setting state to "
+ "shutoff.") % locals())
+ vm_state = power_state.SHUTOFF
else:
vm_state = vm_instance.state
vms_not_found_in_db.remove(name)
- db_state = db_instance['state']
if vm_state != db_state:
LOG.info(_("DB/VM state mismatch. Changing state from "
"'%(db_state)s' to '%(vm_state)s'") % locals())
diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py
index 1cdccadd6..738bdda19 100644
--- a/nova/tests/api/openstack/test_images.py
+++ b/nova/tests/api/openstack/test_images.py
@@ -43,9 +43,14 @@ from nova.tests.api.openstack import fakes
FLAGS = flags.FLAGS
-class BaseImageServiceTests(object):
+class _BaseImageServiceTests(test.TestCase):
"""Tasks to test for all image services"""
+ def __init__(self, *args, **kwargs):
+ super(_BaseImageServiceTests, self).__init__(*args, **kwargs)
+ self.service = None
+ self.context = None
+
def test_create(self):
fixture = self._make_fixture('test image')
num_images = len(self.service.index(self.context))
@@ -116,8 +121,7 @@ class BaseImageServiceTests(object):
return fixture
-class LocalImageServiceTest(test.TestCase,
- BaseImageServiceTests):
+class LocalImageServiceTest(_BaseImageServiceTests):
"""Tests the local image service"""
@@ -147,8 +151,7 @@ class LocalImageServiceTest(test.TestCase,
self.assertEqual(3, len(found_image_ids), len(found_image_ids))
-class GlanceImageServiceTest(test.TestCase,
- BaseImageServiceTests):
+class GlanceImageServiceTest(_BaseImageServiceTests):
"""Tests the Glance image service, in particular that metadata translation
works properly.
diff --git a/nova/tests/test_auth.py b/nova/tests/test_auth.py
index 885596f56..f8a1b1564 100644
--- a/nova/tests/test_auth.py
+++ b/nova/tests/test_auth.py
@@ -80,10 +80,10 @@ class user_and_project_generator(object):
self.manager.delete_project(self.project)
-class AuthManagerTestCase(object):
+class _AuthManagerBaseTestCase(test.TestCase):
def setUp(self):
FLAGS.auth_driver = self.auth_driver
- super(AuthManagerTestCase, self).setUp()
+ super(_AuthManagerBaseTestCase, self).setUp()
self.flags(connection_type='fake')
self.manager = manager.AuthManager(new=True)
@@ -331,11 +331,11 @@ class AuthManagerTestCase(object):
self.assertTrue(user.is_admin())
-class AuthManagerLdapTestCase(AuthManagerTestCase, test.TestCase):
+class AuthManagerLdapTestCase(_AuthManagerBaseTestCase):
auth_driver = 'nova.auth.ldapdriver.FakeLdapDriver'
-class AuthManagerDbTestCase(AuthManagerTestCase, test.TestCase):
+class AuthManagerDbTestCase(_AuthManagerBaseTestCase):
auth_driver = 'nova.auth.dbdriver.DbDriver'
diff --git a/nova/virt/driver.py b/nova/virt/driver.py
index f9cf1b8aa..fcd31861d 100644
--- a/nova/virt/driver.py
+++ b/nova/virt/driver.py
@@ -232,3 +232,7 @@ class ComputeDriver(object):
def inject_network_info(self, instance):
"""inject network info for specified instance"""
raise NotImplementedError()
+
+ def poll_rescued_instances(self, timeout):
+ """Poll for rescued instances"""
+ raise NotImplementedError()