diff options
| author | Chris Behrens <cbehrens@codestud.com> | 2010-08-06 17:40:10 -0500 |
|---|---|---|
| committer | Chris Behrens <cbehrens@codestud.com> | 2010-08-06 17:40:10 -0500 |
| commit | 6c4e257b6df94b8c8e0745e8c3d0701293ae588e (patch) | |
| tree | 1ea95a0d1911f5927f2fceb685a2200e94a2cbc9 /nova | |
| parent | 869f33c9bf4a70e2a4ca4d1034114890d458f983 (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.py | 82 | ||||
| -rw-r--r-- | nova/scheduler/service.py | 52 |
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))] - - |
