From 6b6a76da377b3444e66ca07235d3138934d20f7c Mon Sep 17 00:00:00 2001 From: Fabian Wiesel Date: Wed, 5 Oct 2022 14:09:05 +0200 Subject: [PATCH] [scheduler] Consolidate host_info/passes steps in filter & weigher Both host_info_requiring_instance_ids as well as host_passes/_weigh_object had duplicated code for extracting the instance-ids needed By consolidating them we reduce the code duplication. Change-Id: Icfc1d3e554ff0834dec35d52772996284dc0a5da --- nova/scheduler/filters/affinity_filter.py | 37 +++++++++++++++++------ nova/scheduler/weights/affinity.py | 9 ++---- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/nova/scheduler/filters/affinity_filter.py b/nova/scheduler/filters/affinity_filter.py index f30cc7a810a..31b69fea24e 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 @@ -40,7 +40,14 @@ def host_passes(self, host_state, spec_obj): return True def host_info_requiring_instance_ids(self, spec_obj): - return set(spec_obj.get_scheduler_hint('different_host')) + different_host = spec_obj.get_scheduler_hint('different_host') + if not different_host: + return different_host + + if isinstance(different_host, str): + return set([different_host]) + + return set(different_host) class SameHostFilter(filters.BaseHostFilter): @@ -53,7 +60,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 @@ -61,7 +68,14 @@ def host_passes(self, host_state, spec_obj): return True def host_info_requiring_instance_ids(self, spec_obj): - return set(spec_obj.get_scheduler_hint('same_host')) + same_host = spec_obj.get_scheduler_hint('same_host') + if not same_host: + return same_host + + if isinstance(same_host, str): + return set([same_host]) + + return set(same_host) class SimpleCIDRAffinityFilter(filters.BaseHostFilter): @@ -93,10 +107,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 +118,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 +152,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)