Pep8 fixes
This commit is contained in:
@@ -13,16 +13,19 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
"""
|
"""
|
||||||
Helpful docstring here
|
Least Cost Scheduler is a mechanism for choosing which host machines to
|
||||||
|
provision a set of resources to. The input of the least-cost-scheduler is a
|
||||||
|
set of objective-functions, called the 'cost-functions', a weight for each
|
||||||
|
cost-function, and a list of candidate hosts (gathered via FilterHosts).
|
||||||
|
|
||||||
|
The cost-function and weights are tabulated, and the host with the least cost
|
||||||
|
is then selected for provisioning.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
from nova import flags
|
from nova import flags
|
||||||
from nova import log as logging
|
from nova import log as logging
|
||||||
# TODO(sirp): this should be just `zone_aware` to match naming scheme
|
|
||||||
# TODO(sirp): perhaps all zone-aware stuff should go under a `zone_aware`
|
|
||||||
# module
|
|
||||||
from nova.scheduler import zone_aware_scheduler
|
from nova.scheduler import zone_aware_scheduler
|
||||||
from nova import utils
|
from nova import utils
|
||||||
|
|
||||||
@@ -38,6 +41,8 @@ flags.DEFINE_list('least_cost_scheduler_cost_functions',
|
|||||||
# cost_functions.py file (perhaps in a least_cost_scheduler directory)
|
# cost_functions.py file (perhaps in a least_cost_scheduler directory)
|
||||||
flags.DEFINE_integer('noop_cost_fn_weight', 1,
|
flags.DEFINE_integer('noop_cost_fn_weight', 1,
|
||||||
'How much weight to give the noop cost function')
|
'How much weight to give the noop cost function')
|
||||||
|
|
||||||
|
|
||||||
def noop_cost_fn(host):
|
def noop_cost_fn(host):
|
||||||
"""Return a pre-weight cost of 1 for each host"""
|
"""Return a pre-weight cost of 1 for each host"""
|
||||||
return 1
|
return 1
|
||||||
@@ -45,6 +50,8 @@ def noop_cost_fn(host):
|
|||||||
|
|
||||||
flags.DEFINE_integer('fill_first_cost_fn_weight', 1,
|
flags.DEFINE_integer('fill_first_cost_fn_weight', 1,
|
||||||
'How much weight to give the fill-first cost function')
|
'How much weight to give the fill-first cost function')
|
||||||
|
|
||||||
|
|
||||||
def fill_first_cost_fn(host):
|
def fill_first_cost_fn(host):
|
||||||
"""Prefer hosts that have less ram available, filter_hosts will exclude
|
"""Prefer hosts that have less ram available, filter_hosts will exclude
|
||||||
hosts that don't have enough ram"""
|
hosts that don't have enough ram"""
|
||||||
@@ -82,16 +89,21 @@ class LeastCostScheduler(zone_aware_scheduler.ZoneAwareScheduler):
|
|||||||
def weigh_hosts(self, num, request_spec, hosts):
|
def weigh_hosts(self, num, request_spec, hosts):
|
||||||
"""Returns a list of dictionaries of form:
|
"""Returns a list of dictionaries of form:
|
||||||
[ {weight: weight, hostname: hostname} ]"""
|
[ {weight: weight, hostname: hostname} ]"""
|
||||||
|
|
||||||
# FIXME(sirp): weigh_hosts should handle more than just instances
|
# FIXME(sirp): weigh_hosts should handle more than just instances
|
||||||
hostnames = [hostname for hostname, _ in hosts]
|
hostnames = [hostname for hostname, caps in hosts]
|
||||||
|
|
||||||
cost_fns = self.get_cost_fns()
|
cost_fns = self.get_cost_fns()
|
||||||
costs = weighted_sum(domain=hosts, weighted_fns=cost_fns)
|
costs = weighted_sum(domain=hosts, weighted_fns=cost_fns)
|
||||||
|
|
||||||
weighted = []
|
weighted = []
|
||||||
|
weight_log = []
|
||||||
for cost, hostname in zip(costs, hostnames):
|
for cost, hostname in zip(costs, hostnames):
|
||||||
|
weight_log.append("%s: %s" % (hostname, "%.2f" % cost))
|
||||||
weight_dict = dict(weight=cost, hostname=hostname)
|
weight_dict = dict(weight=cost, hostname=hostname)
|
||||||
weighted.append(weight_dict)
|
weighted.append(weight_dict)
|
||||||
|
|
||||||
|
LOG.debug(_("Weighted Costs => %s") % weight_log)
|
||||||
return weighted
|
return weighted
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -117,11 +117,11 @@ class ZoneAwareScheduler(driver.Scheduler):
|
|||||||
# Filter local hosts based on requirements ...
|
# Filter local hosts based on requirements ...
|
||||||
host_list = self.filter_hosts(num_instances, request_spec)
|
host_list = self.filter_hosts(num_instances, request_spec)
|
||||||
|
|
||||||
# then weigh the selected hosts.
|
|
||||||
# weighted = [{weight=weight, name=hostname}, ...]
|
|
||||||
|
|
||||||
# TODO(sirp): weigh_hosts should also be a function of 'topic' or
|
# TODO(sirp): weigh_hosts should also be a function of 'topic' or
|
||||||
# resources, so that we can apply different objective functions to it
|
# resources, so that we can apply different objective functions to it
|
||||||
|
|
||||||
|
# then weigh the selected hosts.
|
||||||
|
# weighted = [{weight=weight, name=hostname}, ...]
|
||||||
weighted = self.weigh_hosts(num_instances, request_spec, host_list)
|
weighted = self.weigh_hosts(num_instances, request_spec, host_list)
|
||||||
|
|
||||||
# Next, tack on the best weights from the child zones ...
|
# Next, tack on the best weights from the child zones ...
|
||||||
@@ -145,8 +145,9 @@ class ZoneAwareScheduler(driver.Scheduler):
|
|||||||
"""Derived classes must override this method and return
|
"""Derived classes must override this method and return
|
||||||
a list of hosts in [(hostname, capability_dict)] format."""
|
a list of hosts in [(hostname, capability_dict)] format."""
|
||||||
# NOTE(sirp): The default logic is the equivalent to AllHostsFilter
|
# NOTE(sirp): The default logic is the equivalent to AllHostsFilter
|
||||||
|
service_states = self.zone_manager.service_states
|
||||||
return [(host, services)
|
return [(host, services)
|
||||||
for host, services in self.zone_manager.service_states.iteritems()]
|
for host, services in service_states.iteritems()]
|
||||||
|
|
||||||
def weigh_hosts(self, num, request_spec, hosts):
|
def weigh_hosts(self, num, request_spec, hosts):
|
||||||
"""Derived classes may override this to provide more sophisticated
|
"""Derived classes may override this to provide more sophisticated
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class FakeHost(object):
|
|||||||
self.free_ram = free_ram
|
self.free_ram = free_ram
|
||||||
self.io = io
|
self.io = io
|
||||||
|
|
||||||
|
|
||||||
class WeightedSumTestCase(test.TestCase):
|
class WeightedSumTestCase(test.TestCase):
|
||||||
def test_empty_domain(self):
|
def test_empty_domain(self):
|
||||||
domain = []
|
domain = []
|
||||||
@@ -50,7 +51,8 @@ class WeightedSumTestCase(test.TestCase):
|
|||||||
(2, lambda h: h.io), # Avoid high I/O
|
(2, lambda h: h.io), # Avoid high I/O
|
||||||
]
|
]
|
||||||
|
|
||||||
costs = least_cost.weighted_sum(domain=hosts, weighted_fns=weighted_fns)
|
costs = least_cost.weighted_sum(
|
||||||
|
domain=hosts, weighted_fns=weighted_fns)
|
||||||
|
|
||||||
# Each 256 MB unit of free-ram contributes 0.5 points by way of:
|
# Each 256 MB unit of free-ram contributes 0.5 points by way of:
|
||||||
# cost = weight * (score/max_score) = 1 * (256/512) = 0.5
|
# cost = weight * (score/max_score) = 1 * (256/512) = 0.5
|
||||||
@@ -65,6 +67,7 @@ class WeightedSumTestCase(test.TestCase):
|
|||||||
class FakeZoneManager:
|
class FakeZoneManager:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class LeastCostSchedulerTestCase(test.TestCase):
|
class LeastCostSchedulerTestCase(test.TestCase):
|
||||||
def _host_caps(self, multiplier):
|
def _host_caps(self, multiplier):
|
||||||
# Returns host capabilities in the following way:
|
# Returns host capabilities in the following way:
|
||||||
@@ -116,7 +119,6 @@ class LeastCostSchedulerTestCase(test.TestCase):
|
|||||||
#FLAGS.default_host_filter_driver = self.old_flag
|
#FLAGS.default_host_filter_driver = self.old_flag
|
||||||
super(LeastCostSchedulerTestCase, self).tearDown()
|
super(LeastCostSchedulerTestCase, self).tearDown()
|
||||||
|
|
||||||
|
|
||||||
def assertWeights(self, expected, num, request_spec, hosts):
|
def assertWeights(self, expected, num, request_spec, hosts):
|
||||||
weighted = self.sched.weigh_hosts(num, request_spec, hosts)
|
weighted = self.sched.weigh_hosts(num, request_spec, hosts)
|
||||||
self.assertDictListMatch(weighted, expected, approx_equal=True)
|
self.assertDictListMatch(weighted, expected, approx_equal=True)
|
||||||
@@ -139,7 +141,8 @@ class LeastCostSchedulerTestCase(test.TestCase):
|
|||||||
request_spec = {}
|
request_spec = {}
|
||||||
hosts = self.sched.filter_hosts(num, request_spec)
|
hosts = self.sched.filter_hosts(num, request_spec)
|
||||||
|
|
||||||
expected = [ dict(weight=1, hostname=hostname) for hostname, caps in hosts]
|
expected = [dict(weight=1, hostname=hostname)
|
||||||
|
for hostname, caps in hosts]
|
||||||
self.assertWeights(expected, num, request_spec, hosts)
|
self.assertWeights(expected, num, request_spec, hosts)
|
||||||
|
|
||||||
def test_cost_fn_weights(self):
|
def test_cost_fn_weights(self):
|
||||||
@@ -152,7 +155,8 @@ class LeastCostSchedulerTestCase(test.TestCase):
|
|||||||
request_spec = {}
|
request_spec = {}
|
||||||
hosts = self.sched.filter_hosts(num, request_spec)
|
hosts = self.sched.filter_hosts(num, request_spec)
|
||||||
|
|
||||||
expected = [ dict(weight=2, hostname=hostname) for hostname, caps in hosts]
|
expected = [dict(weight=2, hostname=hostname)
|
||||||
|
for hostname, caps in hosts]
|
||||||
self.assertWeights(expected, num, request_spec, hosts)
|
self.assertWeights(expected, num, request_spec, hosts)
|
||||||
|
|
||||||
def test_fill_first_cost_fn(self):
|
def test_fill_first_cost_fn(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user