Merge "Delete the TypeAffinityFilter"

This commit is contained in:
Zuul 2017-12-21 04:51:11 +00:00 committed by Gerrit Code Review
commit 2281532d0e
7 changed files with 12 additions and 112 deletions

View File

@ -258,7 +258,7 @@ This filter passes hosts if no ``instance_type`` key is set or the
is a string that may contain either a single ``instance_type`` name or a
comma-separated list of ``instance_type`` names, such as ``m1.nano`` or
``m1.nano,m1.small``. For information about how to use this filter, see
:ref:`host-aggregates`. See also :ref:`TypeAffinityFilter`.
:ref:`host-aggregates`.
AllHostsFilter
--------------
@ -753,15 +753,6 @@ With the API, use the ``os:scheduler_hints`` key:
}
}
.. _TypeAffinityFilter:
TypeAffinityFilter
------------------
Dynamically limits hosts to one instance type. An instance can only be launched
on a host, if no instance with different instances types are running on it, or
if the host has no running instances at all.
Cell filters
~~~~~~~~~~~~

View File

@ -154,17 +154,6 @@ There are many standard filter classes which may be used
a set of instances.
* |RetryFilter| - filters hosts that have been attempted for scheduling.
Only passes hosts that have not been previously attempted.
* |TypeAffinityFilter| - Only passes hosts that are not already running an
instance of the requested type.
.. warning:: TypeAffinityFilter is deprecated for removal in the
17.0.0 Queens release. There is no replacement planned for this
filter. It is fundamentally flawed in that it relies on the
``flavors.id`` primary key and if a flavor "changed", i.e. deleted
and re-created with new values, it will result in this filter
thinking it is a different flavor, thus breaking the usefulness of
this filter.
* |AggregateTypeAffinityFilter| - limits instance_type by aggregate.
This filter passes hosts if no instance_type key is set or
the instance_type aggregate metadata value contains the name of the
@ -485,7 +474,6 @@ in :mod:`nova.tests.scheduler`.
.. |DifferentHostFilter| replace:: :class:`DifferentHostFilter <nova.scheduler.filters.affinity_filter.DifferentHostFilter>`
.. |SameHostFilter| replace:: :class:`SameHostFilter <nova.scheduler.filters.affinity_filter.SameHostFilter>`
.. |RetryFilter| replace:: :class:`RetryFilter <nova.scheduler.filters.retry_filter.RetryFilter>`
.. |TypeAffinityFilter| replace:: :class:`TypeAffinityFilter <nova.scheduler.filters.type_filter.TypeAffinityFilter>`
.. |AggregateTypeAffinityFilter| replace:: :class:`AggregateTypeAffinityFilter <nova.scheduler.filters.type_filter.AggregateTypeAffinityFilter>`
.. |ServerGroupAntiAffinityFilter| replace:: :class:`ServerGroupAntiAffinityFilter <nova.scheduler.filters.affinity_filter.ServerGroupAntiAffinityFilter>`
.. |ServerGroupAffinityFilter| replace:: :class:`ServerGroupAffinityFilter <nova.scheduler.filters.affinity_filter.ServerGroupAffinityFilter>`

View File

@ -14,47 +14,9 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_log import log as logging
from nova.scheduler import filters
from nova.scheduler.filters import utils
LOG = logging.getLogger(__name__)
class TypeAffinityFilter(filters.BaseHostFilter):
"""DEPRECATED: TypeAffinityFilter doesn't allow more than one VM type
per host.
Note: this works best with ram_weight_multiplier
(spread) set to 1 (default).
"""
RUN_ON_REBUILD = False
def __init__(self):
super(TypeAffinityFilter, self).__init__()
LOG.warning('TypeAffinityFilter is deprecated for removal in the '
'17.0.0 Queens release. There is no replacement planned '
'for this filter. It is fundamentally flawed in that it '
'relies on the flavors.id primary key and if a flavor '
'\"changed\" (deleted and re-created with new values) '
'it will result in this filter thinking it is a '
'different flavor, thus breaking the usefulness of this '
'filter.')
def host_passes(self, host_state, spec_obj):
"""Dynamically limits hosts to one instance type
Return False if host has any instance types other than the requested
type. Return True if all instance types match or if host is empty.
"""
instance_type = spec_obj.flavor
instance_type_id = instance_type.id
other_types_on_host = utils.other_types_on_host(host_state,
instance_type_id)
return not other_types_on_host
class AggregateTypeAffinityFilter(filters.BaseHostFilter):
"""AggregateTypeAffinityFilter limits instance_type by aggregate

View File

@ -83,16 +83,3 @@ def instance_uuids_overlap(host_state, uuids):
# host_state.instances is a dict whose keys are the instance uuids
host_uuids = set(host_state.instances.keys())
return bool(host_uuids.intersection(set_uuids))
def other_types_on_host(host_state, instance_type_id):
"""Tests for overlap between a host_state's instances and an
instance_type_id.
Returns True if there are any instances in the host_state whose
instance_type_id is different than the supplied instance_type_id value.
"""
host_instances = host_state.instances.values()
host_types = set([inst.instance_type_id for inst in host_instances])
inst_set = set([instance_type_id])
return bool(host_types - inst_set)

View File

@ -12,46 +12,14 @@
import mock
import six
from nova import objects
from nova.scheduler.filters import type_filter
from nova import test
from nova.tests.unit.scheduler import fakes
from nova.tests import uuidsentinel as uuids
class TestTypeFilter(test.NoDBTestCase):
def test_type_filter(self):
with mock.patch.object(type_filter.LOG, 'warning') as mock_warning:
self.filt_cls = type_filter.TypeAffinityFilter()
# make sure we logged a deprecation warning
self.assertEqual(1, mock_warning.call_count)
self.assertIn('TypeAffinityFilter is deprecated for removal',
six.text_type(mock_warning.call_args_list[0][0]))
host = fakes.FakeHostState('fake_host', 'fake_node', {})
host.instances = {}
target_id = 1
spec_obj = objects.RequestSpec(
context=mock.MagicMock(),
flavor=objects.Flavor(id=target_id))
# True since no instances on host
self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
# Add an instance with the same instance_type_id
inst1 = objects.Instance(uuid=uuids.instance_1,
instance_type_id=target_id)
host.instances = {inst1.uuid: inst1}
# True since only same instance_type_id on host
self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
# Add an instance with a different instance_type_id
diff_type = target_id + 1
inst2 = objects.Instance(uuid=uuids.instance_2,
instance_type_id=diff_type)
host.instances.update({inst2.uuid: inst2})
# False since host now has an instance of a different type
self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
@mock.patch('nova.scheduler.filters.utils.aggregate_values_from_key')
def test_aggregate_type_filter_no_metadata(self, agg_mock):
self.filt_cls = type_filter.AggregateTypeAffinityFilter()

View File

@ -106,10 +106,3 @@ class TestUtils(test.NoDBTestCase):
self.assertTrue(utils.instance_uuids_overlap(host_state,
[uuids.instance_1]))
self.assertFalse(utils.instance_uuids_overlap(host_state, ['zz']))
def test_other_types_on_host(self):
inst1 = objects.Instance(uuid=uuids.instance, instance_type_id=1)
host_state = fakes.FakeHostState('host1', 'node1', {})
host_state.instances = {inst1.uuid: inst1}
self.assertFalse(utils.other_types_on_host(host_state, 1))
self.assertTrue(utils.other_types_on_host(host_state, 2))

View File

@ -0,0 +1,11 @@
---
upgrade:
- |
The ``TypeAffinityFilter``, which was deprecated in the 16.0.0 Pike
release, has been removed. The filter was flawed in that it relied on the
flavor ``id`` primary key which cannot be relied upon since you cannot
"edit" a flavor to change its disk, vcpu, etc values. Therefore to change
a given flavor, it must be deleted and re-created, which means a new ``id``
value, thus potentially breaking the usefulness of the filter. Also, the
flavor migration from the ``nova`` database to the ``nova_api`` database
would also have resulted in different ``id`` values.