summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorChris Behrens <cbehrens@codestud.com>2010-08-06 17:40:10 -0500
committerChris Behrens <cbehrens@codestud.com>2010-08-06 17:40:10 -0500
commit6c4e257b6df94b8c8e0745e8c3d0701293ae588e (patch)
tree1ea95a0d1911f5927f2fceb685a2200e94a2cbc9 /nova
parent869f33c9bf4a70e2a4ca4d1034114890d458f983 (diff)
Moved Scheduler classes into scheduler.py. Created a way to specify scheduler class that the SchedulerService uses...
Diffstat (limited to 'nova')
-rw-r--r--nova/scheduler/scheduler.py82
-rw-r--r--nova/scheduler/service.py52
2 files changed, 96 insertions, 38 deletions
diff --git a/nova/scheduler/scheduler.py b/nova/scheduler/scheduler.py
new file mode 100644
index 000000000..0da7b95cf
--- /dev/null
+++ b/nova/scheduler/scheduler.py
@@ -0,0 +1,82 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010 United States Government as represented by the
+# Administrator of the National Aeronautics and Space Administration.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""
+Scheduler Classes
+"""
+
+import logging
+import random
+import sys
+import time
+
+from nova import exception
+from nova import flags
+from nova.datastore import Redis
+
+FLAGS = flags.FLAGS
+flags.DEFINE_integer('node_down_time',
+ 60,
+ 'seconds without heartbeat that determines a compute node to be down')
+
+
+class Scheduler(object):
+ """
+ The base class that all Scheduler clases should inherit from
+ """
+
+ @property
+ def compute_nodes(self):
+ return [identifier.split(':')[0] for identifier in Redis.instance().smembers("daemons") if (identifier.split(':')[1] == "nova-compute")]
+
+ def compute_node_is_up(self, node):
+ time_str = Redis.instance().hget('%s:%s:%s' % ('daemon', node, 'nova-compute'), 'updated_at')
+ # Would be a lot easier if we stored heartbeat time in epoch :)
+ return(time_str and
+ (time.time() - (int(time.mktime(time.strptime(time_str.replace('Z', 'UTC'), '%Y-%m-%dT%H:%M:%S%Z'))) - time.timezone) < FLAGS.node_down_time))
+
+ def compute_nodes_up(self):
+ return [node for node in self.compute_nodes if self.compute_node_is_up(node)]
+
+ def pick_node(self, instance_id, **_kwargs):
+ """You DEFINITELY want to define this in your subclass"""
+ raise NotImplementedError("Your subclass should define pick_node")
+
+class RandomScheduler(Scheduler):
+ """
+ Implements Scheduler as a random node selector
+ """
+
+ def __init__(self):
+ super(RandomScheduler, self).__init__()
+
+ def pick_node(self, instance_id, **_kwargs):
+ nodes = self.compute_nodes_up()
+ return nodes[int(random.random() * len(nodes))]
+
+class BestFitScheduler(Scheduler):
+ """
+ Implements Scheduler as a best-fit node selector
+ """
+
+ def __init__(self):
+ super(BestFitScheduler, self).__init__()
+
+ def pick_node(self, instance_id, **_kwargs):
+ raise NotImplementedError("BestFitScheduler is not done yet")
+
diff --git a/nova/scheduler/service.py b/nova/scheduler/service.py
index 3a226322f..3a86cefbe 100644
--- a/nova/scheduler/service.py
+++ b/nova/scheduler/service.py
@@ -21,32 +21,34 @@ Scheduler Service
"""
import logging
-import random
-import sys
-import time
from twisted.internet import defer
-from twisted.internet import task
from nova import exception
from nova import flags
-from nova import process
from nova import rpc
from nova import service
-from nova import utils
from nova.compute import model
-from nova.datastore import Redis
+from nova.scheduler import scheduler
FLAGS = flags.FLAGS
-flags.DEFINE_integer('node_down_time', 60,
- 'seconds without heartbeat that determines a compute node to be down')
-
+flags.DEFINE_string('scheduler_type',
+ 'random',
+ 'the scheduler to use')
+
+scheduler_classes = {
+ 'random': scheduler.RandomScheduler,
+ 'bestfit': scheduler.BestFitScheduler
+ }
+
class SchedulerService(service.Service):
"""
Manages the running instances.
"""
def __init__(self):
super(SchedulerService, self).__init__()
- self.instdir = model.InstanceDirectory()
+ if (FLAGS.scheduler_type not in scheduler_classes):
+ raise exception.Error("Scheduler '%s' does not exist" % FLAGS.scheduler_type)
+ self._scheduler_class = scheduler_classes[FLAGS.scheduler_type]
def noop(self):
""" simple test of an AMQP message call """
@@ -68,21 +70,8 @@ class SchedulerService(service.Service):
logging.exception("model server went away")
yield
- @property
- def compute_nodes(self):
- return [identifier.split(':')[0] for identifier in Redis.instance().smembers("daemons") if (identifier.split(':')[1] == "nova-compute")]
-
- def compute_node_is_up(self, node):
- time_str = Redis.instance().hget('%s:%s:%s' % ('daemon', node, 'nova-compute'), 'updated_at')
- return(time_str and
- (time.time() - (int(time.mktime(time.strptime(time_str.replace('Z', 'UTC'), '%Y-%m-%dT%H:%M:%S%Z'))) - time.timezone) < FLAGS.node_down_time))
-
- def compute_nodes_up(self):
- return [node for node in self.compute_nodes if self.compute_node_is_up(node)]
-
def pick_node(self, instance_id, **_kwargs):
- """You DEFINITELY want to define this in your subclass"""
- raise NotImplementedError("Your subclass should define pick_node")
+ return self._scheduler_class().pick_node(instance_id, **_kwargs)
@exception.wrap_exception
def run_instance(self, instance_id, **_kwargs):
@@ -94,16 +83,3 @@ class SchedulerService(service.Service):
logging.debug("Casting to node %s for instance %s" %
(node, instance_id))
-class RandomService(SchedulerService):
- """
- Implements SchedulerService as a random node selector
- """
-
- def __init__(self):
- super(RandomService, self).__init__()
-
- def pick_node(self, instance_id, **_kwargs):
- nodes = self.compute_nodes_up()
- return nodes[int(random.random() * len(nodes))]
-
-