filter: add per-aggregate filter to configure disk_allocation_ratio
Adds a filter AggregateDiskFilter which provides the ability to read from aggregates metadata the "disk_allocation_ratio". DocImpact Implements: blueprint per-aggregate-disk-allocation-ratio Change-Id: I79d59fcdfb09e67ed6f12113615c673624b24a19
This commit is contained in:
parent
7fb2a039dd
commit
56a9512f14
|
@ -94,6 +94,11 @@ There are some standard filter classes to use (:mod:`nova.scheduler.filters`):
|
|||
``disk_allocation_ration`` setting. It's virtual disk to physical disk
|
||||
allocation ratio and it's 1.0 by default. The total allow allocated disk size will
|
||||
be physical disk multiplied this ratio.
|
||||
* |AggregateDiskFilter| - filters hosts by disk allocation with per-aggregate
|
||||
``disk_allocation_ratio`` setting. If no per-aggregate value is found, it will
|
||||
fall back to the global default ``disk_allocation_ratio``. If more than one value
|
||||
is found for a host (meaning the host is in two or more different aggregates with
|
||||
different ratio settings), the minimum value will be used.
|
||||
* |NumInstancesFilter| - filters hosts by number of running instances on it.
|
||||
hosts with too many instances will be filtered.
|
||||
``max_instances_per_host`` setting. Maximum number of instances allowed to run on
|
||||
|
@ -360,6 +365,7 @@ in :mod:``nova.tests.scheduler``.
|
|||
.. |RamFilter| replace:: :class:`RamFilter <nova.scheduler.filters.ram_filter.RamFilter>`
|
||||
.. |AggregateRamFilter| replace:: :class:`AggregateRamFilter <nova.scheduler.filters.ram_filter.AggregateRamFilter>`
|
||||
.. |DiskFilter| replace:: :class:`DiskFilter <nova.scheduler.filters.disk_filter.DiskFilter>`
|
||||
.. |AggregateDiskFilter| replace:: :class:`AggregateDiskFilter <nova.scheduler.filters.disk_filter.AggregateDiskFilter>`
|
||||
.. |NumInstancesFilter| replace:: :class:`NumInstancesFilter <nova.scheduler.filters.num_instances_filter.NumInstancesFilter>`
|
||||
.. |IoOpsFilter| replace:: :class:`IoOpsFilter <nova.scheduler.filters.io_ops_filter.IoOpsFilter>`
|
||||
.. |AggregateIoOpsFilter| replace:: :class:`AggregateIoOpsFilter <nova.scheduler.filters.io_ops_filter.AggregateIoOpsFilter>`
|
||||
|
|
|
@ -15,8 +15,10 @@
|
|||
|
||||
from oslo.config import cfg
|
||||
|
||||
from nova.i18n import _LW
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.scheduler import filters
|
||||
from nova.scheduler.filters import utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -30,6 +32,9 @@ CONF.register_opt(disk_allocation_ratio_opt)
|
|||
class DiskFilter(filters.BaseHostFilter):
|
||||
"""Disk Filter with over subscription flag."""
|
||||
|
||||
def _get_disk_allocation_ratio(self, host_state, filter_properties):
|
||||
return CONF.disk_allocation_ratio
|
||||
|
||||
def host_passes(self, host_state, filter_properties):
|
||||
"""Filter based on disk usage."""
|
||||
instance_type = filter_properties.get('instance_type')
|
||||
|
@ -40,7 +45,10 @@ class DiskFilter(filters.BaseHostFilter):
|
|||
free_disk_mb = host_state.free_disk_mb
|
||||
total_usable_disk_mb = host_state.total_usable_disk_gb * 1024
|
||||
|
||||
disk_mb_limit = total_usable_disk_mb * CONF.disk_allocation_ratio
|
||||
disk_allocation_ratio = self._get_disk_allocation_ratio(
|
||||
host_state, filter_properties)
|
||||
|
||||
disk_mb_limit = total_usable_disk_mb * disk_allocation_ratio
|
||||
used_disk_mb = total_usable_disk_mb - free_disk_mb
|
||||
usable_disk_mb = disk_mb_limit - used_disk_mb
|
||||
|
||||
|
@ -55,3 +63,28 @@ class DiskFilter(filters.BaseHostFilter):
|
|||
disk_gb_limit = disk_mb_limit / 1024
|
||||
host_state.limits['disk_gb'] = disk_gb_limit
|
||||
return True
|
||||
|
||||
|
||||
class AggregateDiskFilter(DiskFilter):
|
||||
"""AggregateDiskFilter with per-aggregate disk allocation ratio flag.
|
||||
|
||||
Fall back to global disk_allocation_ratio if no per-aggregate setting
|
||||
found.
|
||||
"""
|
||||
|
||||
def _get_disk_allocation_ratio(self, host_state, filter_properties):
|
||||
# TODO(uni): DB query in filter is a performance hit, especially for
|
||||
# system with lots of hosts. Will need a general solution here to fix
|
||||
# all filters with aggregate DB call things.
|
||||
aggregate_vals = utils.aggregate_values_from_db(
|
||||
filter_properties['context'],
|
||||
host_state.host,
|
||||
'disk_allocation_ratio')
|
||||
try:
|
||||
ratio = utils.validate_num_values(
|
||||
aggregate_vals, CONF.disk_allocation_ratio, cast_to=float)
|
||||
except ValueError as e:
|
||||
LOG.warn(_LW("Could not decode disk_allocation_ratio: '%s'"), e)
|
||||
ratio = CONF.disk_allocation_ratio
|
||||
|
||||
return ratio
|
||||
|
|
|
@ -1927,3 +1927,46 @@ class HostFiltersTestCase(test.NoDBTestCase):
|
|||
metadata={'max_io_ops_per_host': 'XXX'})
|
||||
filter_properties = {'context': self.context}
|
||||
self.assertTrue(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
def test_aggregate_disk_filter_value_error(self):
|
||||
self._stub_service_is_up(True)
|
||||
filt_cls = self.class_map['AggregateDiskFilter']()
|
||||
self.flags(disk_allocation_ratio=1.0)
|
||||
filter_properties = {
|
||||
'context': self.context,
|
||||
'instance_type': {'root_gb': 1,
|
||||
'ephemeral_gb': 1,
|
||||
'swap': 1024}}
|
||||
service = {'disabled': False}
|
||||
host = fakes.FakeHostState('host1', 'node1',
|
||||
{'free_disk_mb': 3 * 1024,
|
||||
'total_usable_disk_gb': 1,
|
||||
'service': service})
|
||||
self._create_aggregate_with_host(name='fake_aggregate',
|
||||
hosts=['host1'],
|
||||
metadata={'disk_allocation_ratio': 'XXX'})
|
||||
self.assertTrue(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
def test_aggregate_disk_filter_default_value(self):
|
||||
self._stub_service_is_up(True)
|
||||
filt_cls = self.class_map['AggregateDiskFilter']()
|
||||
self.flags(disk_allocation_ratio=1.0)
|
||||
filter_properties = {
|
||||
'context': self.context,
|
||||
'instance_type': {'root_gb': 2,
|
||||
'ephemeral_gb': 1,
|
||||
'swap': 1024}}
|
||||
service = {'disabled': False}
|
||||
host = fakes.FakeHostState('host1', 'node1',
|
||||
{'free_disk_mb': 3 * 1024,
|
||||
'total_usable_disk_gb': 1,
|
||||
'service': service})
|
||||
# Uses global conf.
|
||||
self.assertFalse(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
# Uses an aggregate with ratio
|
||||
self._create_aggregate_with_host(
|
||||
name='fake_aggregate',
|
||||
hosts=['host1'],
|
||||
metadata={'disk_allocation_ratio': '2'})
|
||||
self.assertTrue(filt_cls.host_passes(host, filter_properties))
|
||||
|
|
Loading…
Reference in New Issue