diff --git a/nova/scheduler/filters/affinity_filter.py b/nova/scheduler/filters/affinity_filter.py index f30cc7a810a..eedb9ed21ef 100644 --- a/nova/scheduler/filters/affinity_filter.py +++ b/nova/scheduler/filters/affinity_filter.py @@ -32,7 +32,7 @@ class DifferentHostFilter(filters.BaseHostFilter): RUN_ON_REBUILD = False def host_passes(self, host_state, spec_obj): - affinity_uuids = spec_obj.get_scheduler_hint('different_host') + affinity_uuids = self.host_info_requiring_instance_ids(spec_obj) if affinity_uuids: overlap = utils.instance_uuids_overlap(host_state, affinity_uuids) return not overlap @@ -53,7 +53,7 @@ class SameHostFilter(filters.BaseHostFilter): RUN_ON_REBUILD = False def host_passes(self, host_state, spec_obj): - affinity_uuids = spec_obj.get_scheduler_hint('same_host') + affinity_uuids = self.host_info_requiring_instance_ids(spec_obj) if affinity_uuids: overlap = utils.instance_uuids_overlap(host_state, affinity_uuids) return overlap @@ -93,10 +93,10 @@ class _GroupAntiAffinityFilter(filters.BaseHostFilter): RUN_ON_REBUILD = False def host_passes(self, host_state, spec_obj): - # Only invoke the filter if 'anti-affinity' is configured - instance_group = spec_obj.instance_group - policy = instance_group.policy if instance_group else None - if self.policy_name != policy: + members = self.host_info_requiring_instance_ids(spec_obj) + # Only invoke the filter if 'anti-affinity' is configured, + # and there are any instances to consider + if not members: return True # NOTE(hanrong): Move operations like resize can check the same source @@ -104,13 +104,14 @@ def host_passes(self, host_state, spec_obj): # must not return the source as a non-possible destination. if spec_obj.instance_uuid in host_state.instances.keys(): return True + # The list of instances UUIDs on the given host instances = set(host_state.instances.keys()) - # The list of instances UUIDs which are members of this group - members = set(spec_obj.instance_group.members) # The set of instances on the host that are also members of this group servers_on_host = instances.intersection(members) + instance_group = spec_obj.instance_group + rules = instance_group.rules if rules and 'max_server_per_host' in rules: max_server_per_host = rules['max_server_per_host'] @@ -137,9 +138,11 @@ def host_passes(self, host_state, spec_obj): def host_info_requiring_instance_ids(self, spec_obj): instance_group = spec_obj.instance_group policy = instance_group.policy if instance_group else None + if self.policy_name != policy: return set() + # The list of instances UUIDs which are members of this group return set(spec_obj.instance_group.members) diff --git a/nova/scheduler/weights/affinity.py b/nova/scheduler/weights/affinity.py index c79739ca188..06841cc5f5d 100644 --- a/nova/scheduler/weights/affinity.py +++ b/nova/scheduler/weights/affinity.py @@ -37,16 +37,11 @@ class _SoftAffinityWeigherBase(weights.BaseHostWeigher): def _weigh_object(self, host_state, request_spec): """Higher weights win.""" - if not request_spec.instance_group: - return 0 - - policy = request_spec.instance_group.policy - - if self.policy_name != policy: + members = self.host_info_requiring_instance_ids(request_spec) + if not members: return 0 instances = set(host_state.instances.keys()) - members = set(request_spec.instance_group.members) member_on_host = instances.intersection(members) return len(member_on_host)