Use stevedore for scheduler host manager

Avoid having to configure the full class path of host manager using
classloader. Change to load the class by stevedore driver plugin using
entrypoints.

Change 'scheduler_host_manager' to use entrypoint with the namespace
'nova.scheduler.host_manager' in 'setup.cfg'. Meanwhile, still maintain
the compatibility for class path configuration until the next major
release.

UpgradeImpact - see the reno file attached.
Change-Id: I3fd42ead44487a21eb5cfaf5a91209277ce30ad0
Partially-Implements: blueprint scheduler-driver-use-stevedore
This commit is contained in:
Yingxin 2015-11-17 07:27:34 +00:00
parent a943c8b833
commit 158c6d64c2
5 changed files with 104 additions and 7 deletions

View File

@ -245,12 +245,20 @@ configuration.
""")
sched_driver_host_mgr_opt = cfg.StrOpt("scheduler_host_manager",
default="nova.scheduler.host_manager.HostManager",
default="host_manager",
help="""
The scheduler host manager class to use. Aside from the default, the only other
option as of the Mitaka release is
'nova.scheduler.ironic_host_manager.IronicHostManager', which should be used if
you're using Ironic to provision bare-metal instances.
The scheduler host manager to use, which manages the in-memory picture of the
hosts that the scheduler uses.
The option value should be chosen from one of the entrypoints under the
namespace 'nova.scheduler.host_manager' of file 'setup.cfg'. For example,
'host_manager' is the default setting. Aside from the default, the only other
option as of the Mitaka release is 'ironic_host_manager', which should be used
if you're using Ironic to provision bare-metal instances.
This option also supports a full class path style, for example
"nova.scheduler.host_manager.HostManager", but note this support is deprecated
and will be dropped in the N release.
* Services that use this:

View File

@ -21,23 +21,49 @@ Scheduler base class that all Schedulers should inherit from
import abc
from oslo_log import log as logging
from oslo_utils import importutils
import six
from stevedore import driver
import nova.conf
from nova.i18n import _, _LW
from nova import objects
from nova import servicegroup
CONF = nova.conf.CONF
LOG = logging.getLogger(__name__)
@six.add_metaclass(abc.ABCMeta)
class Scheduler(object):
"""The base class that all Scheduler classes should inherit from."""
def __init__(self):
self.host_manager = importutils.import_object(
CONF.scheduler_host_manager)
try:
self.host_manager = driver.DriverManager(
"nova.scheduler.host_manager",
CONF.scheduler_host_manager,
invoke_on_load=True).driver
# TODO(Yingxin): Change to catch stevedore.exceptions.NoMatches
# after stevedore v1.9.0
except RuntimeError:
# NOTE(Yingxin): Loading full class path is deprecated and
# should be removed in the N release.
try:
self.host_manager = importutils.import_object(
CONF.scheduler_host_manager)
LOG.warning(_LW("DEPRECATED: scheduler_host_manager uses "
"classloader to load %(path)s. This legacy "
"loading style will be removed in the "
"N release."),
{'path': CONF.scheduler_host_manager})
except (ImportError, ValueError):
raise RuntimeError(
_("Cannot load host manager from configuration "
"scheduler_host_manager = %(conf)s."),
{'conf': CONF.scheduler_host_manager})
self.servicegroup_api = servicegroup.API()
def run_periodic_tasks(self, context):

View File

@ -21,7 +21,9 @@ import mock
from nova import context
from nova import objects
from nova.scheduler import driver
from nova.scheduler import host_manager
from nova.scheduler import ironic_host_manager
from nova.scheduler import manager
from nova import servicegroup
from nova import test
@ -117,6 +119,54 @@ class SchedulerManagerTestCase(test.NoDBTestCase):
mock.sentinel.instance_uuids)
class SchedulerInitTestCase(test.NoDBTestCase):
"""Test case for base scheduler driver initiation."""
driver_cls = fakes.FakeScheduler
@mock.patch.object(host_manager.HostManager, '_init_instance_info')
@mock.patch.object(host_manager.HostManager, '_init_aggregates')
def test_init_using_default_hostmanager(self,
mock_init_agg,
mock_init_inst):
manager = self.driver_cls().host_manager
self.assertIsInstance(manager, host_manager.HostManager)
@mock.patch.object(host_manager.HostManager, '_init_instance_info')
@mock.patch.object(host_manager.HostManager, '_init_aggregates')
def test_init_using_ironic_hostmanager(self,
mock_init_agg,
mock_init_inst):
self.flags(scheduler_host_manager='ironic_host_manager')
manager = self.driver_cls().host_manager
self.assertIsInstance(manager, ironic_host_manager.IronicHostManager)
@mock.patch.object(host_manager.HostManager, '_init_instance_info')
@mock.patch.object(host_manager.HostManager, '_init_aggregates')
def test_init_nonexist_hostmanager(self,
mock_init_agg,
mock_init_inst):
self.flags(scheduler_host_manager='nonexist_host_manager')
self.assertRaises(RuntimeError, self.driver_cls)
# NOTE(Yingxin): Loading full class path is deprecated and should be
# removed in the N release.
@mock.patch.object(driver.LOG, 'warning')
@mock.patch.object(host_manager.HostManager, '_init_instance_info')
@mock.patch.object(host_manager.HostManager, '_init_aggregates')
def test_init_using_classpath_to_hostmanager(self,
mock_init_agg,
mock_init_inst,
mock_warning):
self.flags(
scheduler_host_manager=
'nova.scheduler.ironic_host_manager.IronicHostManager')
manager = self.driver_cls().host_manager
self.assertIsInstance(manager, ironic_host_manager.IronicHostManager)
warn_args, kwargs = mock_warning.call_args
self.assertIn("DEPRECATED", warn_args[0])
class SchedulerTestCase(test.NoDBTestCase):
"""Test case for base scheduler driver class."""

View File

@ -0,0 +1,9 @@
---
upgrade:
- |
The option ``scheduler_host_manager`` is now changed to use entrypoint
instead of full class path. Set one of the entrypoints under the namespace
'nova.scheduler.host_manager' in 'setup.cfg'. Its default value is
'host_manager'. The full class path style is still supported in current
release. But it is not recommended because class path can be changed and
this support will be dropped in the next major release.

View File

@ -187,6 +187,10 @@ nova.ipv6_backend =
rfc2462 = nova.ipv6.rfc2462
account_identifier = nova.ipv6.account_identifier
nova.scheduler.host_manager =
host_manager = nova.scheduler.host_manager:HostManager
ironic_host_manager = nova.scheduler.ironic_host_manager:IronicHostManager
[build_sphinx]
all_files = 1
build-dir = doc/build