summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell Bryant <rbryant@redhat.com>2013-01-11 11:56:09 -0500
committerRussell Bryant <rbryant@redhat.com>2013-01-11 18:06:54 -0500
commit42f3d0bdbda3c54c0d3490e0f407e7dbb8f574ca (patch)
treec5a05b4050bc47ec94fed6965ecef44dd399525a
parent6ea308295a158b4700f4081913f66596fc769b36 (diff)
downloadnova-42f3d0bdbda3c54c0d3490e0f407e7dbb8f574ca.tar.gz
nova-42f3d0bdbda3c54c0d3490e0f407e7dbb8f574ca.tar.xz
nova-42f3d0bdbda3c54c0d3490e0f407e7dbb8f574ca.zip
Make pinging conductor a part of conductor API.
This patch moves the loop that pings the conductor over rpc until it responds to be a part of the conductor API. This will allow it to be used elsewhere in the code as needed. Part of bp no-db-compute. Change-Id: Ie027adef4a3af3059b4ab586e927c93ae1a86fe9
-rw-r--r--nova/compute/manager.py30
-rw-r--r--nova/conductor/api.py36
-rw-r--r--nova/tests/compute/test_compute.py15
-rw-r--r--nova/tests/conductor/test_conductor.py21
4 files changed, 61 insertions, 41 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index f138a3708..98ed1286e 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -358,32 +358,6 @@ class ComputeManager(manager.SchedulerDependentManager):
'trying to set it to ERROR'),
instance_uuid=instance_uuid)
- def _get_instances_at_startup(self, context):
- '''Get instances for this host during service init.'''
- attempt = 0
- timeout = 10
- while True:
- # NOTE(danms): Try ten times with a short timeout, and then punt
- # to the configured RPC timeout after that
- if attempt == 10:
- timeout = None
- attempt += 1
-
- # NOTE(russellb): This is running during service startup. If we
- # allow an exception to be raised, the service will shut down.
- # This may fail the first time around if nova-conductor wasn't
- # running when nova-compute started.
- try:
- self.conductor_api.ping(context, '1.21 GigaWatts',
- timeout=timeout)
- break
- except rpc_common.Timeout as e:
- LOG.exception(_('Timed out waiting for nova-conductor. '
- 'Is it running? Or did nova-compute start '
- 'before nova-conductor?'))
-
- return self.conductor_api.instance_get_all_by_host(context, self.host)
-
def _get_instances_on_driver(self, context):
"""Return a list of instance records that match the instances found
on the hypervisor.
@@ -504,6 +478,10 @@ class ComputeManager(manager.SchedulerDependentManager):
LOG.warning(_('Hypervisor driver does not support '
'firewall rules'), instance=instance)
+ def _get_instances_at_startup(self, context):
+ self.conductor_api.wait_until_ready(context)
+ return self.conductor_api.instance_get_all_by_host(context, self.host)
+
def init_host(self):
"""Initialization for a standalone compute service."""
self.driver.init_host(host=self.host)
diff --git a/nova/conductor/api.py b/nova/conductor/api.py
index 04a4f3d9c..228876682 100644
--- a/nova/conductor/api.py
+++ b/nova/conductor/api.py
@@ -20,6 +20,7 @@ from nova.conductor import manager
from nova.conductor import rpcapi
from nova import exception as exc
from nova.openstack.common import cfg
+from nova.openstack.common import log as logging
from nova.openstack.common.rpc import common as rpc_common
conductor_opts = [
@@ -39,6 +40,8 @@ CONF = cfg.CONF
CONF.register_group(conductor_group)
CONF.register_opts(conductor_opts, conductor_group)
+LOG = logging.getLogger(__name__)
+
class ExceptionHelper(object):
"""Class to wrap another and translate the ClientExceptions raised by its
@@ -68,6 +71,10 @@ class LocalAPI(object):
# other/future users of this sort of functionality.
self._manager = ExceptionHelper(manager.ConductorManager())
+ def wait_until_ready(self, context, *args, **kwargs):
+ # nothing to wait for in the local case.
+ pass
+
def ping(self, context, arg, timeout=None):
return self._manager.ping(context, arg)
@@ -255,6 +262,35 @@ class API(object):
def __init__(self):
self.conductor_rpcapi = rpcapi.ConductorAPI()
+ def wait_until_ready(self, context, early_timeout=10, early_attempts=10):
+ '''Wait until a conductor service is up and running.
+
+ This method calls the remote ping() method on the conductor topic until
+ it gets a response. It starts with a shorter timeout in the loop
+ (early_timeout) up to early_attempts number of tries. It then drops
+ back to the globally configured timeout for rpc calls for each retry.
+ '''
+ attempt = 0
+ timeout = early_timeout
+ while True:
+ # NOTE(danms): Try ten times with a short timeout, and then punt
+ # to the configured RPC timeout after that
+ if attempt == early_attempts:
+ timeout = None
+ attempt += 1
+
+ # NOTE(russellb): This is running during service startup. If we
+ # allow an exception to be raised, the service will shut down.
+ # This may fail the first time around if nova-conductor wasn't
+ # running when this service started.
+ try:
+ self.ping(context, '1.21 GigaWatts', timeout=timeout)
+ break
+ except rpc_common.Timeout as e:
+ LOG.exception(_('Timed out waiting for nova-conductor. '
+ 'Is it running? Or did this service start '
+ 'before nova-conductor?'))
+
def ping(self, context, arg, timeout=None):
return self.conductor_rpcapi.ping(context, arg, timeout)
diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py
index bf619bbec..23df703be 100644
--- a/nova/tests/compute/test_compute.py
+++ b/nova/tests/compute/test_compute.py
@@ -3121,21 +3121,6 @@ class ComputeTestCase(BaseTestCase):
instance = self._create_fake_instance(params)
self.compute._instance_update(self.context, instance['uuid'])
- def test_startup_conductor_ping(self):
- timeouts = []
- calls = dict(count=0)
-
- def fake_ping(context, message, timeout):
- timeouts.append(timeout)
- calls['count'] += 1
- if calls['count'] < 15:
- raise rpc_common.Timeout("fake")
-
- self.stubs.Set(self.compute.conductor_api, 'ping', fake_ping)
- self.compute._get_instances_at_startup(self.context)
- self.assertEqual(timeouts.count(10), 10)
- self.assertTrue(None in timeouts)
-
def test_destroy_evacuated_instances(self):
fake_context = context.get_admin_context()
diff --git a/nova/tests/conductor/test_conductor.py b/nova/tests/conductor/test_conductor.py
index ffe09c95e..7986fc583 100644
--- a/nova/tests/conductor/test_conductor.py
+++ b/nova/tests/conductor/test_conductor.py
@@ -650,6 +650,23 @@ class ConductorAPITestCase(_BaseTestCase, test.TestCase):
def test_service_get_all_compute_by_host(self):
self._test_stubbed('service_get_all_compute_by_host', 'host')
+ def test_ping(self):
+ timeouts = []
+ calls = dict(count=0)
+
+ def fake_ping(_self, context, message, timeout):
+ timeouts.append(timeout)
+ calls['count'] += 1
+ if calls['count'] < 15:
+ raise rpc_common.Timeout("fake")
+
+ self.stubs.Set(conductor_api.API, 'ping', fake_ping)
+
+ self.conductor.wait_until_ready(self.context)
+
+ self.assertEqual(timeouts.count(10), 10)
+ self.assertTrue(None in timeouts)
+
class ConductorLocalAPITestCase(ConductorAPITestCase):
"""Conductor LocalAPI Tests."""
@@ -667,6 +684,10 @@ class ConductorLocalAPITestCase(ConductorAPITestCase):
self.assertRaises(KeyError,
self._do_update, instance['uuid'], foo='bar')
+ def test_ping(self):
+ # Override test in ConductorAPITestCase
+ pass
+
class ConductorImportTest(test.TestCase):
def test_import_conductor_local(self):