Merge lp:~termie/nova/multi_scheduler into lp:~hudson-openstack/nova/trunk

Proposed by termie
Status: Merged
Approved by: Josh Kearney
Approved revision: 1417
Merged at revision: 1425
Proposed branch: lp:~termie/nova/multi_scheduler
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 147 lines (+98/-4)
3 files modified
nova/scheduler/manager.py (+3/-2)
nova/scheduler/multi.py (+73/-0)
nova/tests/scheduler/test_scheduler.py (+22/-2)
To merge this branch: bzr merge lp:~termie/nova/multi_scheduler
Reviewer Review Type Date Requested Status
Josh Kearney (community) Approve
Vish Ishaya (community) Approve
Review via email: mp+71292@code.launchpad.net

Description of the change

Allow different schedulers for compute and volume.

To post a comment you must log in.
Revision history for this message
Vish Ishaya (vishvananda) wrote :

Awesome, Nice work termie. lgtm

review: Approve
Revision history for this message
Josh Kearney (jk0) wrote :

LGTM

review: Approve
Revision history for this message
termie (termie) wrote :

first time every time

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'nova/scheduler/manager.py'
2--- nova/scheduler/manager.py 2011-08-04 00:26:37 +0000
3+++ nova/scheduler/manager.py 2011-08-11 23:50:24 +0000
4@@ -34,12 +34,13 @@
5 LOG = logging.getLogger('nova.scheduler.manager')
6 FLAGS = flags.FLAGS
7 flags.DEFINE_string('scheduler_driver',
8- 'nova.scheduler.chance.ChanceScheduler',
9- 'Driver to use for the scheduler')
10+ 'nova.scheduler.multi.MultiScheduler',
11+ 'Default driver to use for the scheduler')
12
13
14 class SchedulerManager(manager.Manager):
15 """Chooses a host to run instances on."""
16+
17 def __init__(self, scheduler_driver=None, *args, **kwargs):
18 self.zone_manager = zone_manager.ZoneManager()
19 if not scheduler_driver:
20
21=== added file 'nova/scheduler/multi.py'
22--- nova/scheduler/multi.py 1970-01-01 00:00:00 +0000
23+++ nova/scheduler/multi.py 2011-08-11 23:50:24 +0000
24@@ -0,0 +1,73 @@
25+# vim: tabstop=4 shiftwidth=4 softtabstop=4
26+
27+# Copyright (c) 2010 Openstack, LLC.
28+# Copyright 2010 United States Government as represented by the
29+# Administrator of the National Aeronautics and Space Administration.
30+# All Rights Reserved.
31+#
32+# Licensed under the Apache License, Version 2.0 (the "License"); you may
33+# not use this file except in compliance with the License. You may obtain
34+# a copy of the License at
35+#
36+# http://www.apache.org/licenses/LICENSE-2.0
37+#
38+# Unless required by applicable law or agreed to in writing, software
39+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
40+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
41+# License for the specific language governing permissions and limitations
42+# under the License.
43+
44+"""
45+Scheduler that allows routing some calls to one driver and others to another.
46+"""
47+
48+from nova import flags
49+from nova import utils
50+from nova.scheduler import driver
51+
52+
53+FLAGS = flags.FLAGS
54+flags.DEFINE_string('compute_scheduler_driver',
55+ 'nova.scheduler.chance.ChanceScheduler',
56+ 'Driver to use for scheduling compute calls')
57+flags.DEFINE_string('volume_scheduler_driver',
58+ 'nova.scheduler.chance.ChanceScheduler',
59+ 'Driver to use for scheduling volume calls')
60+
61+
62+# A mapping of methods to topics so we can figure out which driver to use.
63+_METHOD_MAP = {'run_instance': 'compute',
64+ 'start_instance': 'compute',
65+ 'create_volume': 'volume'}
66+
67+
68+class MultiScheduler(driver.Scheduler):
69+ """A scheduler that holds multiple sub-schedulers.
70+
71+ This exists to allow flag-driven composibility of schedulers, allowing
72+ third parties to integrate custom schedulers more easily.
73+
74+ """
75+
76+ def __init__(self):
77+ super(MultiScheduler, self).__init__()
78+ compute_driver = utils.import_object(FLAGS.compute_scheduler_driver)
79+ volume_driver = utils.import_object(FLAGS.volume_scheduler_driver)
80+
81+ self.drivers = {'compute': compute_driver,
82+ 'volume': volume_driver}
83+
84+ def __getattr__(self, key):
85+ if not key.startswith('schedule_'):
86+ raise AttributeError(key)
87+ method = key[len('schedule_'):]
88+ if method not in _METHOD_MAP:
89+ raise AttributeError(key)
90+ return getattr(self.drivers[_METHOD_MAP[method]], key)
91+
92+ def set_zone_manager(self, zone_manager):
93+ for k, v in self.drivers.iteritems():
94+ v.set_zone_manager(zone_manager)
95+
96+ def schedule(self, context, topic, *_args, **_kwargs):
97+ return self.drivers[topic].schedule(context, topic, *_args, **_kwargs)
98
99=== modified file 'nova/tests/scheduler/test_scheduler.py'
100--- nova/tests/scheduler/test_scheduler.py 2011-08-09 22:46:57 +0000
101+++ nova/tests/scheduler/test_scheduler.py 2011-08-11 23:50:24 +0000
102@@ -36,8 +36,9 @@
103 from nova import rpc
104 from nova import utils
105 from nova.scheduler import api
106+from nova.scheduler import driver
107 from nova.scheduler import manager
108-from nova.scheduler import driver
109+from nova.scheduler import multi
110 from nova.compute import power_state
111
112
113@@ -391,7 +392,7 @@
114 compute1.kill()
115 compute2.kill()
116
117- def test_wont_sechedule_if_specified_host_is_down_no_queue(self):
118+ def test_wont_schedule_if_specified_host_is_down_no_queue(self):
119 compute1 = service.Service('host1',
120 'nova-compute',
121 'compute',
122@@ -903,6 +904,25 @@
123 db.service_destroy(self.context, s_ref2['id'])
124
125
126+class MultiDriverTestCase(SimpleDriverTestCase):
127+ """Test case for multi driver."""
128+
129+ def setUp(self):
130+ super(MultiDriverTestCase, self).setUp()
131+ self.flags(connection_type='fake',
132+ stub_network=True,
133+ max_cores=4,
134+ max_gigabytes=4,
135+ network_manager='nova.network.manager.FlatManager',
136+ volume_driver='nova.volume.driver.FakeISCSIDriver',
137+ compute_scheduler_driver=('nova.scheduler.simple'
138+ '.SimpleScheduler'),
139+ volume_scheduler_driver=('nova.scheduler.simple'
140+ '.SimpleScheduler'),
141+ scheduler_driver='nova.scheduler.multi.MultiScheduler')
142+ self.scheduler = manager.SchedulerManager()
143+
144+
145 class FakeZone(object):
146 def __init__(self, id, api_url, username, password):
147 self.id = id