Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[scheduler] Consolidate host_info/passes steps in filter & weigher #365

Open
wants to merge 1 commit into
base: stable/rocky-m3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 27 additions & 10 deletions nova/scheduler/filters/affinity_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,22 @@ 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
# With no different_host key
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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to return a set always? If you do, then I'd do it explicitly, or else risk returning None or even an empty string:

Suggested change
return different_host
return set()


if isinstance(different_host, str):
return set([different_host])

return set(different_host)


class SameHostFilter(filters.BaseHostFilter):
Expand All @@ -53,15 +60,22 @@ 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
# With no same_host key
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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

Suggested change
return same_host
return set()


if isinstance(same_host, str):
return set([same_host])

return set(same_host)


class SimpleCIDRAffinityFilter(filters.BaseHostFilter):
Expand Down Expand Up @@ -93,24 +107,25 @@ 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
# compute node where the instance is. That case, AntiAffinityFilter
# 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']
Expand All @@ -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)


Expand Down
9 changes: 2 additions & 7 deletions nova/scheduler/weights/affinity.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down