1
# Copyright (c) 2011-2012 OpenStack, LLC.
4
# Licensed under the Apache License, Version 2.0 (the "License"); you may
5
# not use this file except in compliance with the License. You may obtain
6
# a copy of the License at
8
# http://www.apache.org/licenses/LICENSE-2.0
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
# License for the specific language governing permissions and limitations
16
Least Cost is an algorithm for choosing which host machines to
17
provision a set of resources to. The input is a WeightedHost object which
18
is decided upon by a set of objective-functions, called the 'cost-functions'.
19
The WeightedHost contains a combined weight for each cost-function.
21
The cost-function and weights are tabulated, and the host with the least cost
22
is then selected for provisioning.
24
NOTE(comstud): This is deprecated. One should use the RAMWeigher and/or
25
create other weight modules.
28
from nova import exception
29
from nova.openstack.common import cfg
30
from nova.openstack.common import importutils
31
from nova.openstack.common import log as logging
34
LOG = logging.getLogger(__name__)
37
cfg.ListOpt('least_cost_functions',
39
help='Which cost functions the LeastCostScheduler should use'),
40
cfg.FloatOpt('noop_cost_fn_weight',
42
help='How much weight to give the noop cost function'),
43
cfg.FloatOpt('compute_fill_first_cost_fn_weight',
45
help='How much weight to give the fill-first cost function. '
46
'A negative value will reverse behavior: '
51
CONF.register_opts(least_cost_opts)
54
def noop_cost_fn(host_state, weight_properties):
55
"""Return a pre-weight cost of 1 for each host"""
59
def compute_fill_first_cost_fn(host_state, weight_properties):
60
"""Higher weights win, so we should return a lower weight
61
when there's more free ram available.
63
Note: the weight modifier for this function in default configuration
64
is -1.0. With -1.0 this function runs in reverse, so systems
65
with the most free memory will be preferred.
67
return -host_state.free_ram_mb
70
def _get_cost_functions():
71
"""Returns a list of tuples containing weights and cost functions to
72
use for weighing hosts
74
cost_fns_conf = CONF.least_cost_functions
75
if cost_fns_conf is None:
76
# The old default. This will get fixed up below.
77
fn_str = 'nova.scheduler.least_cost.compute_fill_first_cost_fn'
78
cost_fns_conf = [fn_str]
80
for cost_fn_str in cost_fns_conf:
81
short_name = cost_fn_str.split('.')[-1]
82
if not (short_name.startswith('compute_') or
83
short_name.startswith('noop')):
85
# Fix up any old paths to the new paths
86
if cost_fn_str.startswith('nova.scheduler.least_cost.'):
87
cost_fn_str = ('nova.scheduler.weights.least_cost' +
90
# NOTE: import_class is somewhat misnamed since
91
# the weighing function can be any non-class callable
93
cost_fn = importutils.import_class(cost_fn_str)
95
raise exception.SchedulerCostFunctionNotFound(
96
cost_fn_str=cost_fn_str)
99
flag_name = "%s_weight" % cost_fn.__name__
100
weight = getattr(CONF, flag_name)
101
except AttributeError:
102
raise exception.SchedulerWeightFlagNotFound(
104
# Set the original default.
105
if (flag_name == 'compute_fill_first_cost_fn_weight' and
108
cost_fns.append((weight, cost_fn))
112
def get_least_cost_weighers():
113
cost_functions = _get_cost_functions()
115
# Unfortunately we need to import this late so we don't have an
117
from nova.scheduler import weights
119
class _LeastCostWeigher(weights.BaseHostWeigher):
120
def weigh_objects(self, weighted_hosts, weight_properties):
121
for host in weighted_hosts:
122
host.weight = sum(weight * fn(host.obj, weight_properties)
123
for weight, fn in cost_functions)
125
return [_LeastCostWeigher]