]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Replace Simple/Chance Scheduler with FilterScheduler
authorZhiteng Huang <zhithuang@ebaysf.com>
Tue, 31 Dec 2013 07:00:52 +0000 (15:00 +0800)
committerZhiteng Huang <zhithuang@ebaysf.com>
Tue, 31 Dec 2013 16:10:16 +0000 (00:10 +0800)
This patch replaces SimpleScheduler and ChanceScheduler with
FilterScheduler. Scheduler manager is changed so that when it
detects 'scheduler_driver' is set to SimpleScheduler or
ChanceScheduler, it changes underlying scheduler driver to
FilterScheduler, and then host manager will use a pre-defined
combination of filters & weighers to keep scheduler behavior *MOSTLY*
the same as its old counterparts.

To simulate ChanceScheduler/SimpleScheduler, 'AvailabilityZoneFilter',
'CapacityFilter' and 'CapabilitiesFilter' are chosen to filter
out hosts that isn't in the target AZ, doesn't have sufficient
capacity and doesn't support needed capabilities. And newly
added 'ChanceWeigher' will randomly pick a host from hosts
that passes above filters - just like ChanceScheduler does;
for SimpleScheduler, 'AllocatedCapacityWeigher' will sort hosts
with their 'allocated_capacity' - the one allocates the least
is the winner by default.

So the two new weigher, 'ChanceWeigher' and 'AllocatedCapacityWeigher'
are the key FilterScheduler to act identical when choosing
back-ends to serve requests. The 3 filters on the other hand,
are essential to make sure this 'new' Simple/Chance Scheduler can
support volume types, encryption and QoS.

Partially implements bp: deprecate-chance-and-simple-schedulers

Change-Id: I0538b9692a23af6457ed463447fea8e564570848

cinder/scheduler/host_manager.py
cinder/scheduler/manager.py
cinder/tests/conf_fixture.py
cinder/tests/scheduler/test_scheduler.py

index cfcbfcfa0a716c86394a1f95ce758aa46005c5df..b676f45a6e4530ae2e222b882b4e47ca470b9db2 100644 (file)
@@ -48,6 +48,7 @@ host_manager_opts = [
 
 CONF = cfg.CONF
 CONF.register_opts(host_manager_opts)
+CONF.import_opt('scheduler_driver', 'cinder.scheduler.manager')
 
 LOG = logging.getLogger(__name__)
 
@@ -171,6 +172,23 @@ class HostManager(object):
                                                         'weights')
         self.weight_classes = self.weight_handler.get_all_classes()
 
+        default_filters = ['AvailabilityZoneFilter',
+                           'CapacityFilter',
+                           'CapabilitiesFilter']
+        chance = 'cinder.scheduler.chance.ChanceScheduler'
+        simple = 'cinder.scheduler.simple.SimpleScheduler'
+        if CONF.scheduler_driver == simple:
+            CONF.set_override('scheduler_default_filters', default_filters)
+            CONF.set_override('scheduler_default_weighers',
+                              ['AllocatedCapacityWeigher'])
+        elif CONF.scheduler_driver == chance:
+            CONF.set_override('scheduler_default_filters', default_filters)
+            CONF.set_override('scheduler_default_weighers',
+                              ['ChanceWeigher'])
+        else:
+            # Do nothing when some other scheduler is configured
+            pass
+
     def _choose_host_filters(self, filter_cls_names):
         """Since the caller may specify which filters to use we need
         to have an authoritative list of what is permissible. This
index 515ef8c135720d0446217ddc95571fc2541044bd..a64eaebee25e6c3ecbddb4d9c1394ce631cb2b1d 100644 (file)
@@ -55,6 +55,16 @@ class SchedulerManager(manager.Manager):
                  *args, **kwargs):
         if not scheduler_driver:
             scheduler_driver = CONF.scheduler_driver
+        if scheduler_driver in ['cinder.scheduler.chance.ChanceScheduler',
+                                'cinder.scheduler.simple.SimpleScheduler']:
+            scheduler_driver = ('cinder.scheduler.filter_scheduler.'
+                                'FilterScheduler')
+            LOG.deprecated(_('ChanceScheduler and SimpleScheduler have been '
+                             'deprecated due to lack of support for advanced '
+                             'features like: volume types, volume encryption,'
+                             ' QoS etc. These two schedulers can be fully '
+                             'replaced by FilterScheduler with certain '
+                             'combination of filters and weighers.'))
         self.driver = importutils.import_object(scheduler_driver)
         super(SchedulerManager, self).__init__(*args, **kwargs)
 
index 841ec379124a4ca026814dd952a63da31e497c1c..bc01704a6f6d33e06753ebe7fa145eb35895a20f 100644 (file)
@@ -28,6 +28,7 @@ CONF.import_opt('volume_driver', 'cinder.volume.manager')
 CONF.import_opt('xiv_ds8k_proxy', 'cinder.volume.drivers.xiv_ds8k')
 CONF.import_opt('backup_driver', 'cinder.backup.manager')
 CONF.import_opt('fixed_key', 'cinder.keymgr.conf_key_mgr', group='keymgr')
+CONF.import_opt('scheduler_driver', 'cinder.scheduler.manager')
 
 def_vol_type = 'fake_vol_type'
 
@@ -50,3 +51,5 @@ def set_defaults(conf):
         'cinder.tests.test_xiv_ds8k.XIVDS8KFakeProxyDriver')
     conf.set_default('backup_driver', 'cinder.tests.backup.fake_service')
     conf.set_default('fixed_key', default='0' * 64, group='keymgr')
+    conf.set_default('scheduler_driver',
+                     'cinder.scheduler.filter_scheduler.FilterScheduler')
index 0b3ade1fb538005309888f369de0fdb79d2d0111..4b2e28cd85971ecb89d8ab5474188941046f77d6 100644 (file)
@@ -20,14 +20,19 @@ Tests For Scheduler
 """
 
 import mock
+from oslo.config import cfg
 
 from cinder import context
 from cinder import exception
 from cinder.scheduler import driver
+from cinder.scheduler import filter_scheduler
 from cinder.scheduler import manager
 from cinder import test
 
 
+CONF = cfg.CONF
+
+
 class SchedulerManagerTestCase(test.TestCase):
     """Test case for scheduler manager."""
 
@@ -119,6 +124,38 @@ class SchedulerManagerTestCase(test.TestCase):
         _mock_host_passes.assert_called_once_with(self.context, 'host',
                                                   request_spec, {})
 
+    def test_chance_simple_scheduler_mocked(self):
+        # Test FilterScheduler is loaded and predefined combination
+        # of filters and weighers overrides the default value of config option
+        # scheduler_default_filters and scheduler_default_weighers when
+        # ChanceScheduler or SimpleScheduler is configured as scheduler_driver.
+        chance = 'cinder.scheduler.chance.ChanceScheduler'
+        simple = 'cinder.scheduler.simple.SimpleScheduler'
+        default_filters = ['AvailabilityZoneFilter',
+                           'CapacityFilter',
+                           'CapabilitiesFilter']
+        self.flags(scheduler_driver=chance,
+                   scheduler_default_filters=['CapacityFilter'],
+                   scheduler_default_weighers=['CapacityWeigher'])
+        self.manager = self.manager_cls()
+        self.assertTrue(isinstance(self.manager.driver,
+                                   filter_scheduler.FilterScheduler))
+        self.assertEqual(CONF.scheduler_default_filters,
+                         default_filters)
+        self.assertEqual(CONF.scheduler_default_weighers,
+                         ['ChanceWeigher'])
+
+        self.flags(scheduler_driver=simple,
+                   scheduler_default_filters=['CapacityFilter'],
+                   scheduler_default_weighers=['CapacityWeigher'])
+        self.manager = self.manager_cls()
+        self.assertTrue(isinstance(self.manager.driver,
+                                   filter_scheduler.FilterScheduler))
+        self.assertEqual(CONF.scheduler_default_filters,
+                         default_filters)
+        self.assertEqual(CONF.scheduler_default_weighers,
+                         ['AllocatedCapacityWeigher'])
+
 
 class SchedulerTestCase(test.TestCase):
     """Test case for base scheduler driver class."""