Coverage for manila/scheduler/filters/share_replication.py: 100%
28 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
1# Copyright (c) 2016 Goutham Pacha Ravi
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
16from oslo_log import log
18from manila.scheduler.filters import base_host
20LOG = log.getLogger(__name__)
23class ShareReplicationFilter(base_host.BaseHostFilter):
24 """ShareReplicationFilter filters hosts based on replication support."""
26 def host_passes(self, host_state, filter_properties):
27 """Return True if 'active' replica's host can replicate with host.
29 Design of this filter:
31 - Share replication is symmetric. All backends that can
32 replicate between each other must share the same
33 'replication_domain'.
34 - For scheduling a share that can be replicated in the future,
35 this filter checks for 'replication_domain' capability.
36 - For scheduling a replica, it checks for the
37 'replication_domain' compatibility.
39 """
40 active_replica_host = filter_properties.get('request_spec', {}).get(
41 'active_replica_host')
42 existing_replica_hosts = filter_properties.get('request_spec', {}).get(
43 'all_replica_hosts', '').split(',')
44 replication_type = filter_properties.get('resource_type', {}).get(
45 'extra_specs', {}).get('replication_type')
46 active_replica_replication_domain = filter_properties.get(
47 'replication_domain')
48 host_replication_domain = host_state.replication_domain
50 if replication_type is None:
51 # NOTE(gouthamr): You're probably not creating a replicated
52 # share or a replica, then this host obviously passes.
53 return True
54 elif host_replication_domain is None:
55 msg = "Replication is not enabled on host %s."
56 LOG.debug(msg, host_state.host)
57 return False
58 elif active_replica_host is None:
59 # 'replication_type' filtering will be handled by the
60 # capabilities filter, since it is a share-type extra-spec.
61 return True
63 # Scheduler filtering by replication_domain for a replica
64 if active_replica_replication_domain != host_replication_domain:
65 msg = ("The replication domain of Host %(host)s is "
66 "'%(host_domain)s' and it does not match the replication "
67 "domain of the 'active' replica's host: "
68 "%(active_replica_host)s, which is '%(arh_domain)s'. ")
69 kwargs = {
70 "host": host_state.host,
71 "host_domain": host_replication_domain,
72 "active_replica_host": active_replica_host,
73 "arh_domain": active_replica_replication_domain,
74 }
75 LOG.debug(msg, kwargs)
76 return False
78 # Check host string for already created replicas
79 if host_state.host in existing_replica_hosts:
80 msg = ("Skipping host %s since it already hosts a replica for "
81 "this share.")
82 LOG.debug(msg, host_state.host)
83 return False
85 return True