Add IgnoreAttemptedHostsFilter to oslo

IgnoreAttemptedHostsFilter is RetryFilter that is using in nova and
cinder, so we can put it to oslo and then back port it to both nova
and cinder.

Change-Id: Ia355810b106fee14a55f48081301a310979befac
Implements part of bp oslo-more-filters
This commit is contained in:
Jay Lau 2013-12-04 11:22:49 -05:00
parent db29de01d3
commit 70004c6bb1
4 changed files with 76 additions and 0 deletions

View File

@ -0,0 +1,50 @@
# Copyright (c) 2011 OpenStack Foundation.
# 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.
from openstack.common.gettextutils import _
from openstack.common import log as logging
from openstack.common.scheduler import filters
LOG = logging.getLogger(__name__)
class IgnoreAttemptedHostsFilter(filters.BaseHostFilter):
"""Filter out previously attempted hosts
A host passes this filter if it has not already been attempted for
scheduling. The scheduler needs to add previously attempted hosts
to the 'attempted' key of filter_properties in order for this to work
correctly.
"""
def host_passes(self, host_state, filter_properties):
"""Skip nodes that have already been attempted."""
attempted = filter_properties.get('attempted', None)
if not attempted:
# Re-scheduling is disabled
LOG.debug(_("Re-scheduling is disabled"))
return True
hosts = attempted.get('hosts', [])
host = host_state.host
passes = host not in hosts
pass_msg = "passes" if passes else "fails"
LOG.debug(_("Host %(host)s %(pass_msg)s. Previously tried hosts: "
"%(hosts)s") % {'host': host,
'pass_msg': pass_msg,
'hosts': hosts})
return passes

View File

@ -37,6 +37,7 @@ openstack.common.scheduler.filters =
AvailabilityZoneFilter = openstack.common.scheduler.filters.availability_zone_filter:AvailabilityZoneFilter
CapabilitiesFilter = openstack.common.scheduler.filters.capabilities_filter:CapabilitiesFilter
JsonFilter = openstack.common.scheduler.filters.json_filter:JsonFilter
IgnoreAttemptedHostsFilter = openstack.common.scheduler.filters.ignore_attempted_hosts_filter:IgnoreAttemptedHostsFilter
openstack.common.tests.fakes.weights =
FakeWeigher1 = tests.unit.fakes:FakeWeigher1

View File

@ -47,5 +47,6 @@ class FakeHostManager(object):
class FakeHostState(object):
def __init__(self, host, attribute_dict):
self.host = host
for (key, val) in six.iteritems(attribute_dict):
setattr(self, key, val)

View File

@ -270,6 +270,7 @@ class HostFiltersTestCase(test.BaseTestCase):
self.assertTrue('JsonFilter' in self.class_map)
self.assertTrue('CapabilitiesFilter' in self.class_map)
self.assertTrue('AvailabilityZoneFilter' in self.class_map)
self.assertTrue('IgnoreAttemptedHostsFilter' in self.class_map)
def _do_test_type_filter_extra_specs(self, ecaps, especs, passes):
filt_cls = self.class_map['CapabilitiesFilter']()
@ -676,3 +677,26 @@ class HostFiltersTestCase(test.BaseTestCase):
host = fakes.FakeHostState('host1',
{'service': service})
self.assertTrue(filt_cls.host_passes(host, request))
def test_ignore_attempted_hosts_filter_disabled(self):
# Test case where re-scheduling is disabled.
filt_cls = self.class_map['IgnoreAttemptedHostsFilter']()
host = fakes.FakeHostState('host1', {})
filter_properties = {}
self.assertTrue(filt_cls.host_passes(host, filter_properties))
def test_ignore_attempted_hosts_filter_pass(self):
# Node not previously tried.
filt_cls = self.class_map['IgnoreAttemptedHostsFilter']()
host = fakes.FakeHostState('host1', {})
attempted = dict(num_attempts=2, hosts=['host2'])
filter_properties = dict(attempted=attempted)
self.assertTrue(filt_cls.host_passes(host, filter_properties))
def test_ignore_attempted_hosts_filter_fail(self):
# Node was already tried.
filt_cls = self.class_map['IgnoreAttemptedHostsFilter']()
host = fakes.FakeHostState('host1', {})
attempted = dict(num_attempts=2, hosts=['host1'])
filter_properties = dict(attempted=attempted)
self.assertFalse(filt_cls.host_passes(host, filter_properties))