diff --git a/cinder/exception.py b/cinder/exception.py index e1b61c41cb1..3cbb5016671 100644 --- a/cinder/exception.py +++ b/cinder/exception.py @@ -574,8 +574,8 @@ class PasteAppNotFound(NotFound): message = _("Could not load paste app '%(name)s' from %(path)s") -class NoValidHost(CinderException): - message = _("No valid host was found. %(reason)s") +class NoValidBackend(CinderException): + message = _("No valid backend was found. %(reason)s") class NoMoreTargets(CinderException): diff --git a/cinder/scheduler/driver.py b/cinder/scheduler/driver.py index 57d759e7185..7eaeb0a7d6d 100644 --- a/cinder/scheduler/driver.py +++ b/cinder/scheduler/driver.py @@ -115,15 +115,21 @@ class Scheduler(object): host, capabilities) - def host_passes_filters(self, context, host, request_spec, + def host_passes_filters(self, context, backend, request_spec, filter_properties): - """Check if the specified host passes the filters.""" - raise NotImplementedError(_("Must implement host_passes_filters")) + """Check if the specified backend passes the filters.""" + raise NotImplementedError(_("Must implement backend_passes_filters")) def find_retype_host(self, context, request_spec, filter_properties=None, migration_policy='never'): - """Find a host that can accept the volume with its new type.""" - raise NotImplementedError(_("Must implement find_retype_host")) + """Find a backend that can accept the volume with its new type.""" + raise NotImplementedError(_("Must implement find_retype_backend")) + + # NOTE(geguileo): For backward compatibility with out of tree Schedulers + # we don't change host_passes_filters or find_retype_host method names but + # create an "alias" for them with the right name instead. + backend_passes_filters = host_passes_filters + find_retype_backend = find_retype_host def schedule(self, context, topic, method, *_args, **_kwargs): """Must override schedule method for scheduler to work.""" diff --git a/cinder/scheduler/filter_scheduler.py b/cinder/scheduler/filter_scheduler.py index 5ead5919a8f..d1161d8f804 100644 --- a/cinder/scheduler/filter_scheduler.py +++ b/cinder/scheduler/filter_scheduler.py @@ -66,15 +66,16 @@ class FilterScheduler(driver.Scheduler): request_spec_list, filter_properties_list): - weighed_host = self._schedule_group( + weighed_backend = self._schedule_group( context, request_spec_list, filter_properties_list) - if not weighed_host: - raise exception.NoValidHost(reason=_("No weighed hosts available")) + if not weighed_backend: + raise exception.NoValidBackend(reason=_("No weighed backends " + "available")) - backend = weighed_host.obj + backend = weighed_backend.obj updated_group = driver.group_update_db(context, group, backend.host, backend.cluster_name) @@ -85,17 +86,18 @@ class FilterScheduler(driver.Scheduler): request_spec_list, group_filter_properties, filter_properties_list): - weighed_host = self._schedule_generic_group( + weighed_backend = self._schedule_generic_group( context, group_spec, request_spec_list, group_filter_properties, filter_properties_list) - if not weighed_host: - raise exception.NoValidHost(reason=_("No weighed hosts available")) + if not weighed_backend: + raise exception.NoValidBackend(reason=_("No weighed backends " + "available")) - backend = weighed_host.obj + backend = weighed_backend.obj updated_group = driver.generic_group_update_db(context, group, backend.host, @@ -104,13 +106,13 @@ class FilterScheduler(driver.Scheduler): self.volume_rpcapi.create_group(context, updated_group) def schedule_create_volume(self, context, request_spec, filter_properties): - weighed_host = self._schedule(context, request_spec, - filter_properties) + backend = self._schedule(context, request_spec, filter_properties) - if not weighed_host: - raise exception.NoValidHost(reason=_("No weighed hosts available")) + if not backend: + raise exception.NoValidBackend(reason=_("No weighed backends " + "available")) - backend = weighed_host.obj + backend = backend.obj volume_id = request_spec['volume_id'] updated_volume = driver.volume_update_db(context, volume_id, @@ -126,25 +128,25 @@ class FilterScheduler(driver.Scheduler): filter_properties, allow_reschedule=True) - def host_passes_filters(self, context, host, request_spec, - filter_properties): - """Check if the specified host passes the filters.""" - weighed_hosts = self._get_weighted_candidates(context, request_spec, - filter_properties) - for weighed_host in weighed_hosts: - host_state = weighed_host.obj - if host_state.backend_id == host: - return host_state + def backend_passes_filters(self, context, backend, request_spec, + filter_properties): + """Check if the specified backend passes the filters.""" + weighed_backends = self._get_weighted_candidates(context, request_spec, + filter_properties) + for weighed_backend in weighed_backends: + backend_state = weighed_backend.obj + if backend_state.backend_id == backend: + return backend_state volume_id = request_spec.get('volume_id', '??volume_id missing??') - raise exception.NoValidHost(reason=_('Cannot place volume %(id)s on ' - '%(host)s') % - {'id': volume_id, - 'host': host}) + raise exception.NoValidBackend(reason=_('Cannot place volume %(id)s ' + 'on %(backend)s') % + {'id': volume_id, + 'backend': backend}) - def find_retype_host(self, context, request_spec, filter_properties=None, - migration_policy='never'): - """Find a host that can accept the volume with its new type.""" + def find_retype_backend(self, context, request_spec, + filter_properties=None, migration_policy='never'): + """Find a backend that can accept the volume with its new type.""" filter_properties = filter_properties or {} backend = (request_spec['volume_properties'].get('cluster_name') or request_spec['volume_properties']['host']) @@ -156,10 +158,10 @@ class FilterScheduler(driver.Scheduler): weighed_backends = self._get_weighted_candidates(context, request_spec, filter_properties) if not weighed_backends: - raise exception.NoValidHost(reason=_('No valid hosts for volume ' - '%(id)s with type %(type)s') % - {'id': request_spec['volume_id'], - 'type': request_spec['volume_type']}) + raise exception.NoValidBackend( + reason=_('No valid backends for volume %(id)s with type ' + '%(type)s') % {'id': request_spec['volume_id'], + 'type': request_spec['volume_type']}) for weighed_backend in weighed_backends: backend_state = weighed_backend.obj @@ -183,31 +185,30 @@ class FilterScheduler(driver.Scheduler): return backend_state if migration_policy == 'never': - raise exception.NoValidHost(reason=_('Current host not valid for ' - 'volume %(id)s with type ' - '%(type)s, migration not ' - 'allowed') % - {'id': request_spec['volume_id'], - 'type': request_spec['volume_type']}) + raise exception.NoValidBackend( + reason=_('Current backend not valid for volume %(id)s with ' + 'type %(type)s, migration not allowed') % + {'id': request_spec['volume_id'], + 'type': request_spec['volume_type']}) - top_host = self._choose_top_host(weighed_backends, request_spec) - return top_host.obj + top_backend = self._choose_top_backend(weighed_backends, request_spec) + return top_backend.obj def get_pools(self, context, filters): # TODO(zhiteng) Add filters support return self.host_manager.get_pools(context) def _post_select_populate_filter_properties(self, filter_properties, - host_state): + backend_state): """Populate filter properties with additional information. - Add additional information to the filter properties after a host has + Add additional information to the filter properties after a backend has been selected by the scheduling process. """ # Add a retry entry for the selected volume backend: - self._add_retry_host(filter_properties, host_state.backend_id) + self._add_retry_backend(filter_properties, backend_state.backend_id) - def _add_retry_host(self, filter_properties, host): + def _add_retry_backend(self, filter_properties, backend): """Add a retry entry for the selected volume backend. In the event that the request gets re-scheduled, this entry will signal @@ -216,8 +217,11 @@ class FilterScheduler(driver.Scheduler): retry = filter_properties.get('retry', None) if not retry: return - hosts = retry['hosts'] - hosts.append(host) + # TODO(geguileo): In P - change to only use backends + for key in ('hosts', 'backends'): + backends = retry.get(key) + if backends is not None: + backends.append(backend) def _max_attempts(self): max_attempts = CONF.scheduler_max_attempts @@ -233,21 +237,22 @@ class FilterScheduler(driver.Scheduler): if not exc: return # no exception info from a previous attempt, skip - hosts = retry.get('hosts', None) - if not hosts: + # TODO(geguileo): In P - change to hosts = retry.get('backends') + backends = retry.get('backends', retry.get('hosts')) + if not backends: return # no previously attempted hosts, skip - last_host = hosts[-1] + last_backend = backends[-1] LOG.error(_LE("Error scheduling %(volume_id)s from last vol-service: " - "%(last_host)s : %(exc)s"), + "%(last_backend)s : %(exc)s"), {'volume_id': volume_id, - 'last_host': last_host, + 'last_backend': last_backend, 'exc': exc}) def _populate_retry(self, filter_properties, properties): """Populate filter properties with history of retries for request. - If maximum retries is exceeded, raise NoValidHost. + If maximum retries is exceeded, raise NoValidBackend. """ max_attempts = self.max_attempts retry = filter_properties.pop('retry', {}) @@ -262,7 +267,8 @@ class FilterScheduler(driver.Scheduler): else: retry = { 'num_attempts': 1, - 'hosts': [] # list of volume service hosts tried + 'backends': [], # list of volume service backends tried + 'hosts': [] # TODO(geguileo): Remove in P and leave backends } filter_properties['retry'] = retry @@ -270,7 +276,7 @@ class FilterScheduler(driver.Scheduler): self._log_volume_error(volume_id, retry) if retry['num_attempts'] > max_attempts: - raise exception.NoValidHost( + raise exception.NoValidBackend( reason=_("Exceeded max scheduling attempts %(max_attempts)d " "for volume %(volume_id)s") % {'max_attempts': max_attempts, @@ -278,7 +284,7 @@ class FilterScheduler(driver.Scheduler): def _get_weighted_candidates(self, context, request_spec, filter_properties=None): - """Return a list of hosts that meet required specs. + """Return a list of backends that meet required specs. Returned list is ordered by their fitness. """ @@ -320,26 +326,26 @@ class FilterScheduler(driver.Scheduler): resource_type['extra_specs'].update( multiattach=' True') - # Find our local list of acceptable hosts by filtering and + # Find our local list of acceptable backends by filtering and # weighing our options. we virtually consume resources on # it so subsequent selections can adjust accordingly. # Note: remember, we are using an iterator here. So only # traverse this list once. - hosts = self.host_manager.get_all_host_states(elevated) + backends = self.host_manager.get_all_backend_states(elevated) # Filter local hosts based on requirements ... - hosts = self.host_manager.get_filtered_hosts(hosts, - filter_properties) - if not hosts: + backends = self.host_manager.get_filtered_backends(backends, + filter_properties) + if not backends: return [] - LOG.debug("Filtered %s", hosts) - # weighted_host = WeightedHost() ... the best - # host for the job. - weighed_hosts = self.host_manager.get_weighed_hosts(hosts, - filter_properties) - return weighed_hosts + LOG.debug("Filtered %s", backends) + # weighted_backends = WeightedHost() ... the best + # backend for the job. + weighed_backends = self.host_manager.get_weighed_backends( + backends, filter_properties) + return weighed_backends def _get_weighted_candidates_group(self, context, request_spec_list, filter_properties_list=None): @@ -350,7 +356,7 @@ class FilterScheduler(driver.Scheduler): """ elevated = context.elevated() - weighed_hosts = [] + weighed_backends = [] index = 0 for request_spec in request_spec_list: volume_properties = request_spec['volume_properties'] @@ -388,67 +394,67 @@ class FilterScheduler(driver.Scheduler): self.populate_filter_properties(request_spec, filter_properties) - # Find our local list of acceptable hosts by filtering and + # Find our local list of acceptable backends by filtering and # weighing our options. we virtually consume resources on # it so subsequent selections can adjust accordingly. # Note: remember, we are using an iterator here. So only # traverse this list once. - all_hosts = self.host_manager.get_all_host_states(elevated) - if not all_hosts: + all_backends = self.host_manager.get_all_backend_states(elevated) + if not all_backends: return [] - # Filter local hosts based on requirements ... - hosts = self.host_manager.get_filtered_hosts(all_hosts, - filter_properties) + # Filter local backends based on requirements ... + backends = self.host_manager.get_filtered_backends( + all_backends, filter_properties) - if not hosts: + if not backends: return [] - LOG.debug("Filtered %s", hosts) + LOG.debug("Filtered %s", backends) # weighted_host = WeightedHost() ... the best # host for the job. - temp_weighed_hosts = self.host_manager.get_weighed_hosts( - hosts, + temp_weighed_backends = self.host_manager.get_weighed_backends( + backends, filter_properties) - if not temp_weighed_hosts: + if not temp_weighed_backends: return [] if index == 0: - weighed_hosts = temp_weighed_hosts + weighed_backends = temp_weighed_backends else: - new_weighed_hosts = [] - for host1 in weighed_hosts: - for host2 in temp_weighed_hosts: + new_weighed_backends = [] + for backend1 in weighed_backends: + for backend2 in temp_weighed_backends: # Should schedule creation of CG on backend level, # not pool level. - if (utils.extract_host(host1.obj.backend_id) == - utils.extract_host(host2.obj.backend_id)): - new_weighed_hosts.append(host1) - weighed_hosts = new_weighed_hosts - if not weighed_hosts: + if (utils.extract_host(backend1.obj.backend_id) == + utils.extract_host(backend2.obj.backend_id)): + new_weighed_backends.append(backend1) + weighed_backends = new_weighed_backends + if not weighed_backends: return [] index += 1 - return weighed_hosts + return weighed_backends def _get_weighted_candidates_generic_group( self, context, group_spec, request_spec_list, group_filter_properties=None, filter_properties_list=None): - """Finds hosts that supports the group. + """Finds backends that supports the group. - Returns a list of hosts that meet the required specs, + Returns a list of backends that meet the required specs, ordered by their fitness. """ elevated = context.elevated() - hosts_by_group_type = self._get_weighted_candidates_by_group_type( + backends_by_group_type = self._get_weighted_candidates_by_group_type( context, group_spec, group_filter_properties) - weighed_hosts = [] - hosts_by_vol_type = [] + weighed_backends = [] + backends_by_vol_type = [] index = 0 for request_spec in request_spec_list: volume_properties = request_spec['volume_properties'] @@ -486,72 +492,72 @@ class FilterScheduler(driver.Scheduler): self.populate_filter_properties(request_spec, filter_properties) - # Find our local list of acceptable hosts by filtering and + # Find our local list of acceptable backends by filtering and # weighing our options. we virtually consume resources on # it so subsequent selections can adjust accordingly. # Note: remember, we are using an iterator here. So only # traverse this list once. - all_hosts = self.host_manager.get_all_host_states(elevated) - if not all_hosts: + all_backends = self.host_manager.get_all_backend_states(elevated) + if not all_backends: return [] - # Filter local hosts based on requirements ... - hosts = self.host_manager.get_filtered_hosts(all_hosts, - filter_properties) + # Filter local backends based on requirements ... + backends = self.host_manager.get_filtered_backends( + all_backends, filter_properties) - if not hosts: + if not backends: return [] - LOG.debug("Filtered %s", hosts) + LOG.debug("Filtered %s", backends) - # weighted_host = WeightedHost() ... the best - # host for the job. - temp_weighed_hosts = self.host_manager.get_weighed_hosts( - hosts, + # weighted_backend = WeightedHost() ... the best + # backend for the job. + temp_weighed_backends = self.host_manager.get_weighed_backends( + backends, filter_properties) - if not temp_weighed_hosts: + if not temp_weighed_backends: return [] if index == 0: - hosts_by_vol_type = temp_weighed_hosts + backends_by_vol_type = temp_weighed_backends else: - hosts_by_vol_type = self._find_valid_hosts( - hosts_by_vol_type, temp_weighed_hosts) - if not hosts_by_vol_type: + backends_by_vol_type = self._find_valid_backends( + backends_by_vol_type, temp_weighed_backends) + if not backends_by_vol_type: return [] index += 1 - # Find hosts selected by both the group type and volume types. - weighed_hosts = self._find_valid_hosts(hosts_by_vol_type, - hosts_by_group_type) + # Find backends selected by both the group type and volume types. + weighed_backends = self._find_valid_backends(backends_by_vol_type, + backends_by_group_type) - return weighed_hosts + return weighed_backends - def _find_valid_hosts(self, host_list1, host_list2): - new_hosts = [] - for host1 in host_list1: - for host2 in host_list2: + def _find_valid_backends(self, backend_list1, backend_list2): + new_backends = [] + for backend1 in backend_list1: + for backend2 in backend_list2: # Should schedule creation of group on backend level, # not pool level. - if (utils.extract_host(host1.obj.backend_id) == - utils.extract_host(host2.obj.backend_id)): - new_hosts.append(host1) - if not new_hosts: + if (utils.extract_host(backend1.obj.backend_id) == + utils.extract_host(backend2.obj.backend_id)): + new_backends.append(backend1) + if not new_backends: return [] - return new_hosts + return new_backends def _get_weighted_candidates_by_group_type( self, context, group_spec, group_filter_properties=None): - """Finds hosts that supports the group type. + """Finds backends that supports the group type. - Returns a list of hosts that meet the required specs, + Returns a list of backends that meet the required specs, ordered by their fitness. """ elevated = context.elevated() - weighed_hosts = [] + weighed_backends = [] volume_properties = group_spec['volume_properties'] # Since Cinder is using mixed filters from Oslo and it's own, which # takes 'resource_XX' and 'volume_XX' as input respectively, @@ -577,97 +583,97 @@ class FilterScheduler(driver.Scheduler): self.populate_filter_properties(group_spec, group_filter_properties) - # Find our local list of acceptable hosts by filtering and + # Find our local list of acceptable backends by filtering and # weighing our options. we virtually consume resources on # it so subsequent selections can adjust accordingly. # Note: remember, we are using an iterator here. So only # traverse this list once. - all_hosts = self.host_manager.get_all_host_states(elevated) - if not all_hosts: + all_backends = self.host_manager.get_all_backend_states(elevated) + if not all_backends: return [] - # Filter local hosts based on requirements ... - hosts = self.host_manager.get_filtered_hosts(all_hosts, - group_filter_properties) + # Filter local backends based on requirements ... + backends = self.host_manager.get_filtered_backends( + all_backends, group_filter_properties) - if not hosts: + if not backends: return [] - LOG.debug("Filtered %s", hosts) + LOG.debug("Filtered %s", backends) - # weighted_host = WeightedHost() ... the best - # host for the job. - weighed_hosts = self.host_manager.get_weighed_hosts( - hosts, + # weighted_backends = WeightedHost() ... the best backend for the job. + weighed_backends = self.host_manager.get_weighed_backends( + backends, group_filter_properties) - if not weighed_hosts: + if not weighed_backends: return [] - return weighed_hosts + return weighed_backends def _schedule(self, context, request_spec, filter_properties=None): - weighed_hosts = self._get_weighted_candidates(context, request_spec, - filter_properties) - # When we get the weighed_hosts, we clear those hosts whose backend - # is not same as consistencygroup's backend. + weighed_backends = self._get_weighted_candidates(context, request_spec, + filter_properties) + # When we get the weighed_backends, we clear those backends that don't + # match the consistencygroup's backend. if request_spec.get('CG_backend'): group_backend = request_spec.get('CG_backend') else: group_backend = request_spec.get('group_backend') - if weighed_hosts and group_backend: + if weighed_backends and group_backend: # Get host name including host@backend#pool info from - # weighed_hosts. - for host in weighed_hosts[::-1]: - backend = utils.extract_host(host.obj.backend_id) - if backend != group_backend: - weighed_hosts.remove(host) - if not weighed_hosts: - LOG.warning(_LW('No weighed hosts found for volume ' + # weighed_backends. + for backend in weighed_backends[::-1]: + backend_id = utils.extract_host(backend.obj.backend_id) + if backend_id != group_backend: + weighed_backends.remove(backend) + if not weighed_backends: + LOG.warning(_LW('No weighed backend found for volume ' 'with properties: %s'), filter_properties['request_spec'].get('volume_type')) return None - return self._choose_top_host(weighed_hosts, request_spec) + return self._choose_top_backend(weighed_backends, request_spec) def _schedule_group(self, context, request_spec_list, filter_properties_list=None): - weighed_hosts = self._get_weighted_candidates_group( + weighed_backends = self._get_weighted_candidates_group( context, request_spec_list, filter_properties_list) - if not weighed_hosts: + if not weighed_backends: return None - return self._choose_top_host_group(weighed_hosts, request_spec_list) + return self._choose_top_backend_group(weighed_backends, + request_spec_list) def _schedule_generic_group(self, context, group_spec, request_spec_list, group_filter_properties=None, filter_properties_list=None): - weighed_hosts = self._get_weighted_candidates_generic_group( + weighed_backends = self._get_weighted_candidates_generic_group( context, group_spec, request_spec_list, group_filter_properties, filter_properties_list) - if not weighed_hosts: + if not weighed_backends: return None - return self._choose_top_host_generic_group(weighed_hosts) + return self._choose_top_backend_generic_group(weighed_backends) - def _choose_top_host(self, weighed_hosts, request_spec): - top_host = weighed_hosts[0] - host_state = top_host.obj - LOG.debug("Choosing %s", host_state.backend_id) + def _choose_top_backend(self, weighed_backends, request_spec): + top_backend = weighed_backends[0] + backend_state = top_backend.obj + LOG.debug("Choosing %s", backend_state.backend_id) volume_properties = request_spec['volume_properties'] - host_state.consume_from_volume(volume_properties) - return top_host + backend_state.consume_from_volume(volume_properties) + return top_backend - def _choose_top_host_group(self, weighed_hosts, request_spec_list): - top_host = weighed_hosts[0] - host_state = top_host.obj - LOG.debug("Choosing %s", host_state.backend_id) - return top_host + def _choose_top_backend_group(self, weighed_backends, request_spec_list): + top_backend = weighed_backends[0] + backend_state = top_backend.obj + LOG.debug("Choosing %s", backend_state.backend_id) + return top_backend - def _choose_top_host_generic_group(self, weighed_hosts): - top_host = weighed_hosts[0] - host_state = top_host.obj - LOG.debug("Choosing %s", host_state.backend_id) - return top_host + def _choose_top_backend_generic_group(self, weighed_backends): + top_backend = weighed_backends[0] + backend_state = top_backend.obj + LOG.debug("Choosing %s", backend_state.backend_id) + return top_backend diff --git a/cinder/scheduler/filters/__init__.py b/cinder/scheduler/filters/__init__.py index f29852420f6..a4228f8b65e 100644 --- a/cinder/scheduler/filters/__init__.py +++ b/cinder/scheduler/filters/__init__.py @@ -20,13 +20,15 @@ Scheduler host filters from cinder.scheduler import base_filter -class BaseHostFilter(base_filter.BaseFilter): +class BaseBackendFilter(base_filter.BaseFilter): """Base class for host filters.""" def _filter_one(self, obj, filter_properties): """Return True if the object passes the filter, otherwise False.""" - return self.host_passes(obj, filter_properties) + # For backward compatibility with out of tree filters + passes_method = getattr(self, 'host_passes', self.backend_passes) + return passes_method(obj, filter_properties) - def host_passes(self, host_state, filter_properties): + def backend_passes(self, host_state, filter_properties): """Return True if the HostState passes the filter, otherwise False. Override this in a subclass. @@ -34,6 +36,12 @@ class BaseHostFilter(base_filter.BaseFilter): raise NotImplementedError() -class HostFilterHandler(base_filter.BaseFilterHandler): +class BackendFilterHandler(base_filter.BaseFilterHandler): def __init__(self, namespace): - super(HostFilterHandler, self).__init__(BaseHostFilter, namespace) + super(BackendFilterHandler, self).__init__(BaseHostFilter, namespace) + + +# NOTE(geguileo): For backward compatibility with external filters that +# inherit from these classes +BaseHostFilter = BaseBackendFilter +HostFilterHandler = BackendFilterHandler diff --git a/cinder/scheduler/filters/affinity_filter.py b/cinder/scheduler/filters/affinity_filter.py index 560167b88fd..bcc56ed74a0 100644 --- a/cinder/scheduler/filters/affinity_filter.py +++ b/cinder/scheduler/filters/affinity_filter.py @@ -20,7 +20,7 @@ from cinder.scheduler import filters from cinder.volume import api as volume -class AffinityFilter(filters.BaseHostFilter): +class AffinityFilter(filters.BaseBackendFilter): def __init__(self): self.volume_api = volume.API() @@ -36,7 +36,7 @@ class AffinityFilter(filters.BaseHostFilter): class DifferentBackendFilter(AffinityFilter): """Schedule volume on a different back-end from a set of volumes.""" - def host_passes(self, host_state, filter_properties): + def backend_passes(self, backend_state, filter_properties): context = filter_properties['context'] scheduler_hints = filter_properties.get('scheduler_hints') or {} @@ -62,7 +62,7 @@ class DifferentBackendFilter(AffinityFilter): if affinity_uuids: return not self._get_volumes(context, affinity_uuids, - host_state) + backend_state) # With no different_host key return True @@ -70,7 +70,7 @@ class DifferentBackendFilter(AffinityFilter): class SameBackendFilter(AffinityFilter): """Schedule volume on the same back-end as another volume.""" - def host_passes(self, host_state, filter_properties): + def backend_passes(self, backend_state, filter_properties): context = filter_properties['context'] scheduler_hints = filter_properties.get('scheduler_hints') or {} @@ -95,7 +95,7 @@ class SameBackendFilter(AffinityFilter): return False if affinity_uuids: - return self._get_volumes(context, affinity_uuids, host_state) + return self._get_volumes(context, affinity_uuids, backend_state) # With no same_host key return True diff --git a/cinder/scheduler/filters/availability_zone_filter.py b/cinder/scheduler/filters/availability_zone_filter.py index 0ff245d6f52..57b0a5495c2 100644 --- a/cinder/scheduler/filters/availability_zone_filter.py +++ b/cinder/scheduler/filters/availability_zone_filter.py @@ -16,17 +16,18 @@ from cinder.scheduler import filters -class AvailabilityZoneFilter(filters.BaseHostFilter): - """Filters Hosts by availability zone.""" +class AvailabilityZoneFilter(filters.BaseBackendFilter): + """Filters Backends by availability zone.""" # Availability zones do not change within a request run_filter_once_per_request = True - def host_passes(self, host_state, filter_properties): + def backend_passes(self, backend_state, filter_properties): spec = filter_properties.get('request_spec', {}) props = spec.get('resource_properties', {}) availability_zone = props.get('availability_zone') if availability_zone: - return availability_zone == host_state.service['availability_zone'] + return (availability_zone == + backend_state.service['availability_zone']) return True diff --git a/cinder/scheduler/filters/capabilities_filter.py b/cinder/scheduler/filters/capabilities_filter.py index 5d64b150c8a..bcf877b11a5 100644 --- a/cinder/scheduler/filters/capabilities_filter.py +++ b/cinder/scheduler/filters/capabilities_filter.py @@ -21,8 +21,8 @@ from cinder.scheduler.filters import extra_specs_ops LOG = logging.getLogger(__name__) -class CapabilitiesFilter(filters.BaseHostFilter): - """HostFilter to work with resource (instance & volume) type records.""" +class CapabilitiesFilter(filters.BaseBackendFilter): + """BackendFilter to work with resource (instance & volume) type records.""" def _satisfies_extra_specs(self, capabilities, resource_type): """Check if capabilities satisfy resource type requirements. @@ -55,7 +55,7 @@ class CapabilitiesFilter(filters.BaseHostFilter): try: cap = cap[scope[index]] except (TypeError, KeyError): - LOG.debug("Host doesn't provide capability '%(cap)s' " % + LOG.debug("Backend doesn't provide capability '%(cap)s' " % {'cap': scope[index]}) return False @@ -75,15 +75,15 @@ class CapabilitiesFilter(filters.BaseHostFilter): return False return True - def host_passes(self, host_state, filter_properties): - """Return a list of hosts that can create resource_type.""" + def backend_passes(self, backend_state, filter_properties): + """Return a list of backends that can create resource_type.""" # Note(zhiteng) Currently only Cinder and Nova are using # this filter, so the resource type is either instance or # volume. resource_type = filter_properties.get('resource_type') - if not self._satisfies_extra_specs(host_state.capabilities, + if not self._satisfies_extra_specs(backend_state.capabilities, resource_type): - LOG.debug("%(host_state)s fails resource_type extra_specs " - "requirements", {'host_state': host_state}) + LOG.debug("%(backend_state)s fails resource_type extra_specs " + "requirements", {'backend_state': backend_state}) return False return True diff --git a/cinder/scheduler/filters/capacity_filter.py b/cinder/scheduler/filters/capacity_filter.py index 1959d36fbb5..59359be4e4c 100644 --- a/cinder/scheduler/filters/capacity_filter.py +++ b/cinder/scheduler/filters/capacity_filter.py @@ -28,22 +28,22 @@ from cinder.scheduler import filters LOG = logging.getLogger(__name__) -class CapacityFilter(filters.BaseHostFilter): - """CapacityFilter filters based on volume host's capacity utilization.""" +class CapacityFilter(filters.BaseBackendFilter): + """Capacity filters based on volume backend's capacity utilization.""" - def host_passes(self, host_state, filter_properties): + def backend_passes(self, backend_state, filter_properties): """Return True if host has sufficient capacity.""" # If the volume already exists on this host, don't fail it for # insufficient capacity (e.g., if we are retyping) - if host_state.backend_id == filter_properties.get('vol_exists_on'): + if backend_state.backend_id == filter_properties.get('vol_exists_on'): return True spec = filter_properties.get('request_spec') if spec: volid = spec.get('volume_id') - grouping = 'cluster' if host_state.cluster_name else 'host' + grouping = 'cluster' if backend_state.cluster_name else 'host' if filter_properties.get('new_size'): # If new_size is passed, we are allocating space to extend a volume requested_size = (int(filter_properties.get('new_size')) - @@ -51,25 +51,25 @@ class CapacityFilter(filters.BaseHostFilter): LOG.debug('Checking if %(grouping)s %(grouping_name)s can extend ' 'the volume %(id)s in %(size)s GB', {'grouping': grouping, - 'grouping_name': host_state.backend_id, 'id': volid, + 'grouping_name': backend_state.backend_id, 'id': volid, 'size': requested_size}) else: requested_size = filter_properties.get('size') LOG.debug('Checking if %(grouping)s %(grouping_name)s can create ' 'a %(size)s GB volume (%(id)s)', {'grouping': grouping, - 'grouping_name': host_state.backend_id, 'id': volid, + 'grouping_name': backend_state.backend_id, 'id': volid, 'size': requested_size}) - if host_state.free_capacity_gb is None: + if backend_state.free_capacity_gb is None: # Fail Safe LOG.error(_LE("Free capacity not set: " "volume node info collection broken.")) return False - free_space = host_state.free_capacity_gb - total_space = host_state.total_capacity_gb - reserved = float(host_state.reserved_percentage) / 100 + free_space = backend_state.free_capacity_gb + total_space = backend_state.total_capacity_gb + reserved = float(backend_state.reserved_percentage) / 100 if free_space in ['infinite', 'unknown']: # NOTE(zhiteng) for those back-ends cannot report actual # available capacity, we assume it is able to serve the @@ -93,7 +93,7 @@ class CapacityFilter(filters.BaseHostFilter): "%(grouping_name)s."), {"total": total, "grouping": grouping, - "grouping_name": host_state.backend_id}) + "grouping_name": backend_state.backend_id}) return False # Calculate how much free space is left after taking into account # the reserved space. @@ -114,16 +114,16 @@ class CapacityFilter(filters.BaseHostFilter): # thin_provisioning_support is True. Check if the ratio of # provisioned capacity over total capacity has exceeded over # subscription ratio. - if (thin and host_state.thin_provisioning_support and - host_state.max_over_subscription_ratio >= 1): - provisioned_ratio = ((host_state.provisioned_capacity_gb + + if (thin and backend_state.thin_provisioning_support and + backend_state.max_over_subscription_ratio >= 1): + provisioned_ratio = ((backend_state.provisioned_capacity_gb + requested_size) / total) - if provisioned_ratio > host_state.max_over_subscription_ratio: + if provisioned_ratio > backend_state.max_over_subscription_ratio: msg_args = { "provisioned_ratio": provisioned_ratio, - "oversub_ratio": host_state.max_over_subscription_ratio, + "oversub_ratio": backend_state.max_over_subscription_ratio, "grouping": grouping, - "grouping_name": host_state.backend_id, + "grouping_name": backend_state.backend_id, } LOG.warning(_LW( "Insufficient free space for thin provisioning. " @@ -140,20 +140,20 @@ class CapacityFilter(filters.BaseHostFilter): # the currently available free capacity (taking into account # of reserved space) which we can over-subscribe. adjusted_free_virtual = ( - free * host_state.max_over_subscription_ratio) + free * backend_state.max_over_subscription_ratio) return adjusted_free_virtual >= requested_size - elif thin and host_state.thin_provisioning_support: + elif thin and backend_state.thin_provisioning_support: LOG.warning(_LW("Filtering out %(grouping)s %(grouping_name)s " "with an invalid maximum over subscription ratio " "of %(oversub_ratio).2f. The ratio should be a " "minimum of 1.0."), {"oversub_ratio": - host_state.max_over_subscription_ratio, + backend_state.max_over_subscription_ratio, "grouping": grouping, - "grouping_name": host_state.backend_id}) + "grouping_name": backend_state.backend_id}) return False - msg_args = {"grouping_name": host_state.backend_id, + msg_args = {"grouping_name": backend_state.backend_id, "grouping": grouping, "requested": requested_size, "available": free} diff --git a/cinder/scheduler/filters/driver_filter.py b/cinder/scheduler/filters/driver_filter.py index 329b3c7ed75..dcfcbaecd24 100644 --- a/cinder/scheduler/filters/driver_filter.py +++ b/cinder/scheduler/filters/driver_filter.py @@ -24,33 +24,34 @@ from cinder.scheduler import filters LOG = logging.getLogger(__name__) -class DriverFilter(filters.BaseHostFilter): - """DriverFilter filters hosts based on a 'filter function' and metrics. +class DriverFilter(filters.BaseBackendFilter): + """DriverFilter filters backend based on a 'filter function' and metrics. - DriverFilter filters based on volume host's provided 'filter function' + DriverFilter filters based on volume backend's provided 'filter function' and metrics. """ - def host_passes(self, host_state, filter_properties): - """Determines whether a host has a passing filter_function or not.""" - stats = self._generate_stats(host_state, filter_properties) + def backend_passes(self, backend_state, filter_properties): + """Determines if a backend has a passing filter_function or not.""" + stats = self._generate_stats(backend_state, filter_properties) - LOG.debug("Checking backend '%s'", stats['host_stats']['backend_id']) + LOG.debug("Checking backend '%s'", + stats['backend_stats']['backend_id']) result = self._check_filter_function(stats) LOG.debug("Result: %s", result) LOG.debug("Done checking backend '%s'", - stats['host_stats']['backend_id']) + stats['backend_stats']['backend_id']) return result def _check_filter_function(self, stats): - """Checks if a volume passes a host's filter function. + """Checks if a volume passes a backend's filter function. Returns a tuple in the format (filter_passing, filter_invalid). Both values are booleans. """ if stats['filter_function'] is None: - LOG.debug("Filter function not set :: passing host") + LOG.debug("Filter function not set :: passing backend") return True try: @@ -60,7 +61,7 @@ class DriverFilter(filters.BaseHostFilter): # Warn the admin for now that there is an error in the # filter function. LOG.warning(_LW("Error in filtering function " - "'%(function)s' : '%(error)s' :: failing host"), + "'%(function)s' : '%(error)s' :: failing backend"), {'function': stats['filter_function'], 'error': ex, }) return False @@ -69,8 +70,8 @@ class DriverFilter(filters.BaseHostFilter): def _run_evaluator(self, func, stats): """Evaluates a given function using the provided available stats.""" - host_stats = stats['host_stats'] - host_caps = stats['host_caps'] + backend_stats = stats['backend_stats'] + backend_caps = stats['backend_caps'] extra_specs = stats['extra_specs'] qos_specs = stats['qos_specs'] volume_stats = stats['volume_stats'] @@ -78,39 +79,39 @@ class DriverFilter(filters.BaseHostFilter): result = evaluator.evaluate( func, extra=extra_specs, - stats=host_stats, - capabilities=host_caps, + stats=backend_stats, + capabilities=backend_caps, volume=volume_stats, qos=qos_specs) return result - def _generate_stats(self, host_state, filter_properties): - """Generates statistics from host and volume data.""" + def _generate_stats(self, backend_state, filter_properties): + """Generates statistics from backend and volume data.""" - host_stats = { - 'host': host_state.host, - 'cluster_name': host_state.cluster_name, - 'backend_id': host_state.backend_id, - 'volume_backend_name': host_state.volume_backend_name, - 'vendor_name': host_state.vendor_name, - 'driver_version': host_state.driver_version, - 'storage_protocol': host_state.storage_protocol, - 'QoS_support': host_state.QoS_support, - 'total_capacity_gb': host_state.total_capacity_gb, - 'allocated_capacity_gb': host_state.allocated_capacity_gb, - 'free_capacity_gb': host_state.free_capacity_gb, - 'reserved_percentage': host_state.reserved_percentage, - 'updated': host_state.updated, + backend_stats = { + 'host': backend_state.host, + 'cluster_name': backend_state.cluster_name, + 'backend_id': backend_state.backend_id, + 'volume_backend_name': backend_state.volume_backend_name, + 'vendor_name': backend_state.vendor_name, + 'driver_version': backend_state.driver_version, + 'storage_protocol': backend_state.storage_protocol, + 'QoS_support': backend_state.QoS_support, + 'total_capacity_gb': backend_state.total_capacity_gb, + 'allocated_capacity_gb': backend_state.allocated_capacity_gb, + 'free_capacity_gb': backend_state.free_capacity_gb, + 'reserved_percentage': backend_state.reserved_percentage, + 'updated': backend_state.updated, } - host_caps = host_state.capabilities + backend_caps = backend_state.capabilities filter_function = None - if ('filter_function' in host_caps and - host_caps['filter_function'] is not None): - filter_function = six.text_type(host_caps['filter_function']) + if ('filter_function' in backend_caps and + backend_caps['filter_function'] is not None): + filter_function = six.text_type(backend_caps['filter_function']) qos_specs = filter_properties.get('qos_specs', {}) @@ -121,8 +122,8 @@ class DriverFilter(filters.BaseHostFilter): volume_stats = request_spec.get('volume_properties', {}) stats = { - 'host_stats': host_stats, - 'host_caps': host_caps, + 'backend_stats': backend_stats, + 'backend_caps': backend_caps, 'extra_specs': extra_specs, 'qos_specs': qos_specs, 'volume_stats': volume_stats, diff --git a/cinder/scheduler/filters/ignore_attempted_hosts_filter.py b/cinder/scheduler/filters/ignore_attempted_hosts_filter.py index f37241652f7..fc86dee118d 100644 --- a/cinder/scheduler/filters/ignore_attempted_hosts_filter.py +++ b/cinder/scheduler/filters/ignore_attempted_hosts_filter.py @@ -20,7 +20,7 @@ from cinder.scheduler import filters LOG = logging.getLogger(__name__) -class IgnoreAttemptedHostsFilter(filters.BaseHostFilter): +class IgnoreAttemptedHostsFilter(filters.BaseBackendFilter): """Filter out previously attempted hosts A host passes this filter if it has not already been attempted for @@ -30,13 +30,13 @@ class IgnoreAttemptedHostsFilter(filters.BaseHostFilter): { 'retry': { - 'hosts': ['host1', 'host2'], + 'backends': ['backend1', 'backend2'], 'num_attempts': 3, } } """ - def host_passes(self, host_state, filter_properties): + def backend_passes(self, backend_state, filter_properties): """Skip nodes that have already been attempted.""" attempted = filter_properties.get('retry') if not attempted: @@ -44,14 +44,15 @@ class IgnoreAttemptedHostsFilter(filters.BaseHostFilter): LOG.debug("Re-scheduling is disabled.") return True - hosts = attempted.get('hosts', []) - host = host_state.backend_id + # TODO(geguileo): In P - Just use backends + backends = attempted.get('backends', attempted.get('hosts', [])) + backend = backend_state.backend_id - passes = host not in hosts + passes = backend not in backends 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}) + LOG.debug("Backend %(backend)s %(pass_msg)s. Previously tried " + "backends: %(backends)s" % {'backend': backend, + 'pass_msg': pass_msg, + 'backends': backends}) return passes diff --git a/cinder/scheduler/filters/instance_locality_filter.py b/cinder/scheduler/filters/instance_locality_filter.py index e2d562f34e9..303bf974f46 100644 --- a/cinder/scheduler/filters/instance_locality_filter.py +++ b/cinder/scheduler/filters/instance_locality_filter.py @@ -30,7 +30,7 @@ INSTANCE_HOST_PROP = 'OS-EXT-SRV-ATTR:host' REQUESTS_TIMEOUT = 5 -class InstanceLocalityFilter(filters.BaseHostFilter): +class InstanceLocalityFilter(filters.BaseBackendFilter): """Schedule volume on the same host as a given instance. This filter enables selection of a storage back-end located on the host @@ -51,7 +51,7 @@ class InstanceLocalityFilter(filters.BaseHostFilter): def __init__(self): # Cache Nova API answers directly into the Filter object. - # Since a BaseHostFilter instance lives only during the volume's + # Since a BaseBackendFilter instance lives only during the volume's # scheduling, the cache is re-created for every new volume creation. self._cache = {} super(InstanceLocalityFilter, self).__init__() @@ -69,9 +69,9 @@ class InstanceLocalityFilter(filters.BaseHostFilter): return self._nova_ext_srv_attr - def host_passes(self, backend_state, filter_properties): + def backend_passes(self, backend_state, filter_properties): context = filter_properties['context'] - host = volume_utils.extract_host(backend_state.backend_id, 'host') + backend = volume_utils.extract_host(backend_state.backend_id, 'host') scheduler_hints = filter_properties.get('scheduler_hints') or {} instance_uuid = scheduler_hints.get(HINT_KEYWORD, None) @@ -93,7 +93,7 @@ class InstanceLocalityFilter(filters.BaseHostFilter): # First, lookup for already-known information in local cache if instance_uuid in self._cache: - return self._cache[instance_uuid] == host + return self._cache[instance_uuid] == backend if not self._nova_has_extended_server_attributes(context): LOG.warning(_LW('Hint "%s" dropped because ' @@ -116,5 +116,5 @@ class InstanceLocalityFilter(filters.BaseHostFilter): self._cache[instance_uuid] = getattr(server, INSTANCE_HOST_PROP) - # Match if given instance is hosted on host - return self._cache[instance_uuid] == host + # Match if given instance is hosted on backend + return self._cache[instance_uuid] == backend diff --git a/cinder/scheduler/filters/json_filter.py b/cinder/scheduler/filters/json_filter.py index dbbca066dd7..ee763a9d1da 100644 --- a/cinder/scheduler/filters/json_filter.py +++ b/cinder/scheduler/filters/json_filter.py @@ -21,8 +21,8 @@ import six from cinder.scheduler import filters -class JsonFilter(filters.BaseHostFilter): - """Host Filter to allow simple JSON-based grammar for selecting hosts.""" +class JsonFilter(filters.BaseBackendFilter): + """Backend filter for simple JSON-based grammar for selecting backends.""" def _op_compare(self, args, op): """Compare first item of args with the rest using specified operator. @@ -87,12 +87,12 @@ class JsonFilter(filters.BaseHostFilter): 'and': _and, } - def _parse_string(self, string, host_state): + def _parse_string(self, string, backend_state): """Parse capability lookup strings. Strings prefixed with $ are capability lookups in the form '$variable' where 'variable' is an attribute in the - HostState class. If $variable is a dictionary, you may + BackendState class. If $variable is a dictionary, you may use: $variable.dictkey """ if not string: @@ -101,7 +101,7 @@ class JsonFilter(filters.BaseHostFilter): return string path = string[1:].split(".") - obj = getattr(host_state, path[0], None) + obj = getattr(backend_state, path[0], None) if obj is None: return None for item in path[1:]: @@ -110,7 +110,7 @@ class JsonFilter(filters.BaseHostFilter): return None return obj - def _process_filter(self, query, host_state): + def _process_filter(self, query, backend_state): """Recursively parse the query structure.""" if not query: return True @@ -119,16 +119,16 @@ class JsonFilter(filters.BaseHostFilter): cooked_args = [] for arg in query[1:]: if isinstance(arg, list): - arg = self._process_filter(arg, host_state) + arg = self._process_filter(arg, backend_state) elif isinstance(arg, six.string_types): - arg = self._parse_string(arg, host_state) + arg = self._parse_string(arg, backend_state) if arg is not None: cooked_args.append(arg) result = method(self, cooked_args) return result - def host_passes(self, host_state, filter_properties): - """Return a list of hosts that can fulfill query requirements.""" + def backend_passes(self, backend_state, filter_properties): + """Return a list of backends that can fulfill query requirements.""" # TODO(zhiteng) Add description for filter_properties structure # and scheduler_hints. try: @@ -141,9 +141,9 @@ class JsonFilter(filters.BaseHostFilter): # NOTE(comstud): Not checking capabilities or service for # enabled/disabled so that a provided json filter can decide - result = self._process_filter(jsonutils.loads(query), host_state) + result = self._process_filter(jsonutils.loads(query), backend_state) if isinstance(result, list): - # If any succeeded, include the host + # If any succeeded, include the backend result = any(result) if result: # Filter it out. diff --git a/cinder/scheduler/flows/create_volume.py b/cinder/scheduler/flows/create_volume.py index 6fb35111c71..ae255bbf144 100644 --- a/cinder/scheduler/flows/create_volume.py +++ b/cinder/scheduler/flows/create_volume.py @@ -124,11 +124,11 @@ class ScheduleCreateVolumeTask(flow_utils.CinderTask): except Exception as e: # An error happened, notify on the scheduler queue and log that # this happened and set the volume to errored out and reraise the - # error *if* exception caught isn't NoValidHost. Otherwise *do not* - # reraise (since what's the point?) + # error *if* exception caught isn't NoValidBackend. Otherwise *do + # not* reraise (since what's the point?) with excutils.save_and_reraise_exception( - reraise=not isinstance(e, exception.NoValidHost)): - if isinstance(e, exception.NoValidHost): + reraise=not isinstance(e, exception.NoValidBackend)): + if isinstance(e, exception.NoValidBackend): self.message_api.create( context, defined_messages.UNABLE_TO_ALLOCATE, diff --git a/cinder/scheduler/host_manager.py b/cinder/scheduler/host_manager.py index 345c8c836f1..d85aceba632 100644 --- a/cinder/scheduler/host_manager.py +++ b/cinder/scheduler/host_manager.py @@ -14,7 +14,7 @@ # under the License. """ -Manage hosts in the current zone. +Manage backends in the current zone. """ import collections @@ -34,6 +34,11 @@ from cinder.scheduler import filters from cinder.volume import utils as vol_utils +# FIXME: This file should be renamed to backend_manager, we should also rename +# HostManager class, and scheduler_host_manager option, and also the weight +# classes, and add code to maintain backward compatibility. + + host_manager_opts = [ cfg.ListOpt('scheduler_default_filters', default=[ @@ -83,7 +88,7 @@ class ReadOnlyDict(collections.Mapping): return '%s(%r)' % (self.__class__.__name__, self.data) -class HostState(object): +class BackendState(object): """Mutable and immutable information tracked for a volume backend.""" def __init__(self, host, cluster_name, capabilities=None, service=None): @@ -303,12 +308,11 @@ class HostState(object): # come up with better representation of HostState. grouping = 'cluster' if self.cluster_name else 'host' grouping_name = self.backend_id - return ("%s '%s': free_capacity_gb: %s, pools: %s" % (grouping, grouping_name, self.free_capacity_gb, self.pools)) -class PoolState(HostState): +class PoolState(BackendState): def __init__(self, host, cluster_name, capabilities, pool_name): new_host = vol_utils.append_host(host, pool_name) new_cluster = vol_utils.append_host(cluster_name, pool_name) @@ -356,7 +360,7 @@ class PoolState(HostState): class HostManager(object): """Base HostManager class.""" - host_state_cls = HostState + backend_state_cls = BackendState REQUIRED_KEYS = frozenset([ 'pool_name', @@ -371,20 +375,20 @@ class HostManager(object): def __init__(self): self.service_states = {} # { : {: {cap k : v}}} - self.host_state_map = {} - self.filter_handler = filters.HostFilterHandler('cinder.scheduler.' - 'filters') + self.backend_state_map = {} + self.filter_handler = filters.BackendFilterHandler('cinder.scheduler.' + 'filters') self.filter_classes = self.filter_handler.get_all_classes() self.weight_handler = importutils.import_object( CONF.scheduler_weight_handler, 'cinder.scheduler.weights') self.weight_classes = self.weight_handler.get_all_classes() - self._no_capabilities_hosts = set() # Hosts having no capabilities - self._update_host_state_map(cinder_context.get_admin_context()) + self._no_capabilities_hosts = set() # Services without capabilities + self._update_backend_state_map(cinder_context.get_admin_context()) self.service_states_last_update = {} - def _choose_host_filters(self, filter_cls_names): + def _choose_backend_filters(self, filter_cls_names): """Return a list of available filter names. This function checks input filter names against a predefined set @@ -411,7 +415,7 @@ class HostManager(object): filter_name=", ".join(bad_filters)) return good_filters - def _choose_host_weighers(self, weight_cls_names): + def _choose_backend_weighers(self, weight_cls_names): """Return a list of available weigher names. This function checks input weigher names against a predefined set @@ -439,20 +443,20 @@ class HostManager(object): weigher_name=", ".join(bad_weighers)) return good_weighers - def get_filtered_hosts(self, hosts, filter_properties, - filter_class_names=None): - """Filter hosts and return only ones passing all filters.""" - filter_classes = self._choose_host_filters(filter_class_names) + def get_filtered_backends(self, backends, filter_properties, + filter_class_names=None): + """Filter backends and return only ones passing all filters.""" + filter_classes = self._choose_backend_filters(filter_class_names) return self.filter_handler.get_filtered_objects(filter_classes, - hosts, + backends, filter_properties) - def get_weighed_hosts(self, hosts, weight_properties, - weigher_class_names=None): - """Weigh the hosts.""" - weigher_classes = self._choose_host_weighers(weigher_class_names) + def get_weighed_backends(self, backends, weight_properties, + weigher_class_names=None): + """Weigh the backends.""" + weigher_classes = self._choose_backend_weighers(weigher_class_names) return self.weight_handler.get_weighed_objects(weigher_classes, - hosts, + backends, weight_properties) def update_service_capabilities(self, service_name, host, capabilities, @@ -532,7 +536,7 @@ class HostManager(object): def has_all_capabilities(self): return len(self._no_capabilities_hosts) == 0 - def _update_host_state_map(self, context): + def _update_backend_state_map(self, context): # Get resource usage across the available volume nodes: topic = constants.VOLUME_TOPIC @@ -555,14 +559,14 @@ class HostManager(object): # Since the service could have been added or remove from a cluster backend_key = service.service_topic_queue - backend_state = self.host_state_map.get(backend_key, None) + backend_state = self.backend_state_map.get(backend_key, None) if not backend_state: - backend_state = self.host_state_cls( + backend_state = self.backend_state_cls( host, service.cluster_name, capabilities=capabilities, service=dict(service)) - self.host_state_map[backend_key] = backend_state + self.backend_state_map[backend_key] = backend_state # We may be receiving capability reports out of order from # different volume services in a cluster, so we drop older updates @@ -577,8 +581,8 @@ class HostManager(object): self._no_capabilities_hosts = no_capabilities_hosts - # remove non-active keys from host_state_map - inactive_backend_keys = set(self.host_state_map) - active_backends + # remove non-active keys from backend_state_map + inactive_backend_keys = set(self.backend_state_map) - active_backends for backend_key in inactive_backend_keys: # NOTE(geguileo): We don't want to log the removal of a host from # the map when we are removing it because it has been added to a @@ -586,27 +590,28 @@ class HostManager(object): if backend_key not in active_hosts: LOG.info(_LI("Removing non-active backend: %(backend)s from " "scheduler cache."), {'backend': backend_key}) - del self.host_state_map[backend_key] + del self.backend_state_map[backend_key] - def get_all_host_states(self, context): - """Returns a dict of all the hosts the HostManager knows about. + def get_all_backend_states(self, context): + """Returns a dict of all the backends the HostManager knows about. - Each of the consumable resources in HostState are + Each of the consumable resources in BackendState are populated with capabilities scheduler received from RPC. For example: - {'192.168.1.100': HostState(), ...} + {'192.168.1.100': BackendState(), ...} """ - self._update_host_state_map(context) + self._update_backend_state_map(context) - # build a pool_state map and return that map instead of host_state_map + # build a pool_state map and return that map instead of + # backend_state_map all_pools = {} - for host, state in self.host_state_map.items(): + for backend_key, state in self.backend_state_map.items(): for key in state.pools: pool = state.pools[key] - # use host.pool_name to make sure key is unique - pool_key = '.'.join([host, pool.pool_name]) + # use backend_key.pool_name to make sure key is unique + pool_key = '.'.join([backend_key, pool.pool_name]) all_pools[pool_key] = pool return all_pools.values() @@ -614,14 +619,14 @@ class HostManager(object): def get_pools(self, context): """Returns a dict of all pools on all hosts HostManager knows about.""" - self._update_host_state_map(context) + self._update_backend_state_map(context) all_pools = [] - for host, state in self.host_state_map.items(): + for backend_key, state in self.backend_state_map.items(): for key in state.pools: pool = state.pools[key] - # use host.pool_name to make sure key is unique - pool_key = vol_utils.append_host(host, pool.pool_name) + # use backend_key.pool_name to make sure key is unique + pool_key = vol_utils.append_host(backend_key, pool.pool_name) new_pool = dict(name=pool_key) new_pool.update(dict(capabilities=pool.capabilities)) all_pools.append(new_pool) diff --git a/cinder/scheduler/manager.py b/cinder/scheduler/manager.py index 9b69582d098..c10799813d4 100644 --- a/cinder/scheduler/manager.py +++ b/cinder/scheduler/manager.py @@ -124,8 +124,8 @@ class SchedulerManager(manager.CleanableManager, manager.Manager): context, group, request_spec_list, filter_properties_list) - except exception.NoValidHost: - LOG.error(_LE("Could not find a host for consistency group " + except exception.NoValidBackend: + LOG.error(_LE("Could not find a backend for consistency group " "%(group_id)s."), {'group_id': group.id}) group.status = 'error' @@ -149,8 +149,8 @@ class SchedulerManager(manager.CleanableManager, manager.Manager): request_spec_list, group_filter_properties, filter_properties_list) - except exception.NoValidHost: - LOG.error(_LE("Could not find a host for group " + except exception.NoValidBackend: + LOG.error(_LE("Could not find a backend for group " "%(group_id)s."), {'group_id': group.id}) group.status = 'error' @@ -198,7 +198,7 @@ class SchedulerManager(manager.CleanableManager, manager.Manager): def migrate_volume(self, context, volume, backend, force_copy, request_spec, filter_properties): - """Ensure that the host exists and can accept the volume.""" + """Ensure that the backend exists and can accept the volume.""" self._wait_for_scheduler() def _migrate_volume_set_error(self, context, ex, request_spec): @@ -214,10 +214,10 @@ class SchedulerManager(manager.CleanableManager, manager.Manager): context, ex, request_spec) try: - tgt_backend = self.driver.host_passes_filters(context, backend, - request_spec, - filter_properties) - except exception.NoValidHost as ex: + tgt_backend = self.driver.backend_passes_filters(context, backend, + request_spec, + filter_properties) + except exception.NoValidBackend as ex: _migrate_volume_set_error(self, context, ex, request_spec) except Exception as ex: with excutils.save_and_reraise_exception(): @@ -269,19 +269,20 @@ class SchedulerManager(manager.CleanableManager, manager.Manager): migration_policy = 'never' try: - tgt_host = self.driver.find_retype_host(context, request_spec, - filter_properties, - migration_policy) + tgt_backend = self.driver.find_retype_backend(context, + request_spec, + filter_properties, + migration_policy) except Exception as ex: # Not having a valid host is an expected exception, so we don't # reraise on it. - reraise = not isinstance(ex, exception.NoValidHost) + reraise = not isinstance(ex, exception.NoValidBackend) with excutils.save_and_reraise_exception(reraise=reraise): _retype_volume_set_error(self, context, ex, request_spec, volume, reservations) else: volume_rpcapi.VolumeAPI().retype(context, volume, - new_type['id'], tgt_host, + new_type['id'], tgt_backend, migration_policy, reservations, old_reservations) @@ -298,11 +299,11 @@ class SchedulerManager(manager.CleanableManager, manager.Manager): context, ex, request_spec) try: - self.driver.host_passes_filters(context, - volume.service_topic_queue, - request_spec, - filter_properties) - except exception.NoValidHost as ex: + self.driver.backend_passes_filters(context, + volume.service_topic_queue, + request_spec, + filter_properties) + except exception.NoValidBackend as ex: _manage_existing_set_error(self, context, ex, request_spec) except Exception as ex: with excutils.save_and_reraise_exception(): @@ -333,12 +334,12 @@ class SchedulerManager(manager.CleanableManager, manager.Manager): filter_properties['new_size'] = new_size try: - self.driver.host_passes_filters(context, - volume.service_topic_queue, - request_spec, filter_properties) + self.driver.backend_passes_filters(context, + volume.service_topic_queue, + request_spec, filter_properties) volume_rpcapi.VolumeAPI().extend_volume(context, volume, new_size, reservations) - except exception.NoValidHost as ex: + except exception.NoValidBackend as ex: QUOTAS.rollback(context, reservations, project_id=volume.project_id) _extend_volume_set_error(self, context, ex, request_spec) diff --git a/cinder/test.py b/cinder/test.py index 221834a5a1a..11551eb9cfc 100644 --- a/cinder/test.py +++ b/cinder/test.py @@ -413,11 +413,13 @@ class ModelsObjectComparatorMixin(object): def _assertEqualListsOfObjects(self, objs1, objs2, ignored_keys=None, msg=None): obj_to_dict = lambda o: self._dict_from_object(o, ignored_keys) - sort_key = lambda d: [d[k] for k in sorted(d)] - conv_and_sort = lambda obj: sorted(map(obj_to_dict, obj), key=sort_key) - - self.assertListEqual(conv_and_sort(objs1), conv_and_sort(objs2), - msg=msg) + objs1 = map(obj_to_dict, objs1) + objs2 = list(map(obj_to_dict, objs2)) + # We don't care about the order of the lists, as long as they are in + for obj1 in objs1: + self.assertIn(obj1, objs2) + objs2.remove(obj1) + self.assertEqual([], objs2) def _assertEqualListsOfPrimitivesAsSets(self, primitives1, primitives2): self.assertEqual(len(primitives1), len(primitives2)) diff --git a/cinder/tests/unit/api/contrib/test_admin_actions.py b/cinder/tests/unit/api/contrib/test_admin_actions.py index 47e678806da..54b515b1c86 100644 --- a/cinder/tests/unit/api/contrib/test_admin_actions.py +++ b/cinder/tests/unit/api/contrib/test_admin_actions.py @@ -62,6 +62,7 @@ class BaseAdminTest(test.TestCase): def _create_volume(self, context, updates=None): db_volume = {'status': 'available', 'host': 'test', + 'binary': 'cinder-volume', 'availability_zone': 'fake_zone', 'attach_status': fields.VolumeAttachStatus.DETACHED} if updates: @@ -502,10 +503,12 @@ class AdminActionsTest(BaseAdminTest): db.service_create(self.ctx, {'host': 'test', 'topic': constants.VOLUME_TOPIC, + 'binary': 'cinder-volume', 'created_at': timeutils.utcnow()}) db.service_create(self.ctx, {'host': 'test2', 'topic': constants.VOLUME_TOPIC, + 'binary': 'cinder-volume', 'created_at': timeutils.utcnow()}) db.service_create(self.ctx, {'host': 'clustered_host', diff --git a/cinder/tests/unit/objects/test_cluster.py b/cinder/tests/unit/objects/test_cluster.py index d9799a3a27f..6a63fca48b2 100644 --- a/cinder/tests/unit/objects/test_cluster.py +++ b/cinder/tests/unit/objects/test_cluster.py @@ -36,6 +36,7 @@ def _get_filters_sentinel(): 'race_preventer': mock.sentinel.race_preventer, 'last_heartbeat': mock.sentinel.last_heartbeat, 'num_hosts': mock.sentinel.num_hosts, + 'name_match_level': mock.sentinel.name_match_level, 'num_down_hosts': mock.sentinel.num_down_hosts} diff --git a/cinder/tests/unit/scheduler/fakes.py b/cinder/tests/unit/scheduler/fakes.py index 6e5539c9e43..2a237ae5536 100644 --- a/cinder/tests/unit/scheduler/fakes.py +++ b/cinder/tests/unit/scheduler/fakes.py @@ -90,9 +90,9 @@ class FakeHostManager(host_manager.HostManager): } -class FakeHostState(host_manager.HostState): +class FakeBackendState(host_manager.BackendState): def __init__(self, host, attribute_dict): - super(FakeHostState, self).__init__(host, None) + super(FakeBackendState, self).__init__(host, None) for (key, val) in attribute_dict.items(): setattr(self, key, val) diff --git a/cinder/tests/unit/scheduler/test_allocated_capacity_weigher.py b/cinder/tests/unit/scheduler/test_allocated_capacity_weigher.py index cf92154ee50..a8b44081773 100644 --- a/cinder/tests/unit/scheduler/test_allocated_capacity_weigher.py +++ b/cinder/tests/unit/scheduler/test_allocated_capacity_weigher.py @@ -42,11 +42,11 @@ class AllocatedCapacityWeigherTestCase(test.TestCase): weight_properties)[0] @mock.patch('cinder.db.sqlalchemy.api.service_get_all') - def _get_all_hosts(self, _mock_service_get_all, disabled=False): + def _get_all_backends(self, _mock_service_get_all, disabled=False): ctxt = context.get_admin_context() fakes.mock_host_manager_db_calls(_mock_service_get_all, disabled=disabled) - host_states = self.host_manager.get_all_host_states(ctxt) + host_states = self.host_manager.get_all_backend_states(ctxt) _mock_service_get_all.assert_called_once_with( ctxt, None, # backend_match_level @@ -54,7 +54,7 @@ class AllocatedCapacityWeigherTestCase(test.TestCase): return host_states def test_default_of_spreading_first(self): - hostinfo_list = self._get_all_hosts() + hostinfo_list = self._get_all_backends() # host1: allocated_capacity_gb=0, weight=0 Norm=0.0 # host2: allocated_capacity_gb=1748, weight=-1748 @@ -70,7 +70,7 @@ class AllocatedCapacityWeigherTestCase(test.TestCase): def test_capacity_weight_multiplier1(self): self.flags(allocated_capacity_weight_multiplier=1.0) - hostinfo_list = self._get_all_hosts() + hostinfo_list = self._get_all_backends() # host1: allocated_capacity_gb=0, weight=0 Norm=0.0 # host2: allocated_capacity_gb=1748, weight=1748 @@ -86,7 +86,7 @@ class AllocatedCapacityWeigherTestCase(test.TestCase): def test_capacity_weight_multiplier2(self): self.flags(allocated_capacity_weight_multiplier=-2.0) - hostinfo_list = self._get_all_hosts() + hostinfo_list = self._get_all_backends() # host1: allocated_capacity_gb=0, weight=0 Norm=0.0 # host2: allocated_capacity_gb=1748, weight=-3496 diff --git a/cinder/tests/unit/scheduler/test_base_filter.py b/cinder/tests/unit/scheduler/test_base_filter.py index a0ecdfaf83e..54fd3f78403 100644 --- a/cinder/tests/unit/scheduler/test_base_filter.py +++ b/cinder/tests/unit/scheduler/test_base_filter.py @@ -178,8 +178,8 @@ class TestBaseFilterHandler(test.TestCase): def test_get_filtered_objects_info_and_debug_log_none_returned(self): all_filters = [FilterA, FilterA, FilterB] - fake_hosts = [host_manager.HostState('fake_host%s' % x, None) - for x in range(1, 4)] + fake_backends = [host_manager.BackendState('fake_be%s' % x, None) + for x in range(1, 4)] filt_props = {"request_spec": {'volume_id': fake.VOLUME_ID, 'volume_properties': {'project_id': fake.PROJECT_ID, @@ -187,7 +187,7 @@ class TestBaseFilterHandler(test.TestCase): 'host': 'host4'}}} with mock.patch.object(base_filter, 'LOG') as mock_log: result = self.handler.get_filtered_objects( - all_filters, fake_hosts, filt_props) + all_filters, fake_backends, filt_props) self.assertFalse(result) msg = "with volume ID '%s'" % fake.VOLUME_ID # FilterA should leave Host1 and Host2; FilterB should leave None. @@ -197,8 +197,8 @@ class TestBaseFilterHandler(test.TestCase): self.assertIn(msg, cargs) self.assertIn(exp_output, cargs) - exp_output = ("[('FilterA', ['fake_host2', 'fake_host3']), " - "('FilterA', ['fake_host3']), " + exp_output = ("[('FilterA', ['fake_be2', 'fake_be3']), " + "('FilterA', ['fake_be3']), " + "('FilterB', None)]") cargs = mock_log.debug.call_args[0][0] self.assertIn(msg, cargs) diff --git a/cinder/tests/unit/scheduler/test_capacity_weigher.py b/cinder/tests/unit/scheduler/test_capacity_weigher.py index 77fb2ba2ea7..3bdc0d7d945 100644 --- a/cinder/tests/unit/scheduler/test_capacity_weigher.py +++ b/cinder/tests/unit/scheduler/test_capacity_weigher.py @@ -45,16 +45,16 @@ class CapacityWeigherTestCase(test.TestCase): weight_properties) @mock.patch('cinder.db.sqlalchemy.api.service_get_all') - def _get_all_hosts(self, _mock_service_get_all, disabled=False): + def _get_all_backends(self, _mock_service_get_all, disabled=False): ctxt = context.get_admin_context() fakes.mock_host_manager_db_calls(_mock_service_get_all, disabled=disabled) - host_states = self.host_manager.get_all_host_states(ctxt) + backend_states = self.host_manager.get_all_backend_states(ctxt) _mock_service_get_all.assert_called_once_with( ctxt, None, # backend_match_level topic=constants.VOLUME_TOPIC, disabled=disabled) - return host_states + return backend_states # If thin and thin_provisioning_support are True, # use the following formula: @@ -78,7 +78,7 @@ class CapacityWeigherTestCase(test.TestCase): ) @ddt.unpack def test_default_of_spreading_first(self, volume_type, winner): - hostinfo_list = self._get_all_hosts() + backend_info_list = self._get_all_backends() # Results for the 1st test # {'provisioning:type': 'thin'}: @@ -106,7 +106,7 @@ class CapacityWeigherTestCase(test.TestCase): 'volume_type': volume_type, } weighed_host = self._get_weighed_hosts( - hostinfo_list, + backend_info_list, weight_properties=weight_properties)[0] self.assertEqual(1.0, weighed_host.weight) self.assertEqual(winner, utils.extract_host(weighed_host.obj.host)) @@ -126,7 +126,7 @@ class CapacityWeigherTestCase(test.TestCase): @ddt.unpack def test_capacity_weight_multiplier1(self, volume_type, winner): self.flags(capacity_weight_multiplier=-1.0) - hostinfo_list = self._get_all_hosts() + backend_info_list = self._get_all_backends() # Results for the 1st test # {'provisioning:type': 'thin'}: @@ -154,7 +154,7 @@ class CapacityWeigherTestCase(test.TestCase): 'volume_type': volume_type, } weighed_host = self._get_weighed_hosts( - hostinfo_list, + backend_info_list, weight_properties=weight_properties)[0] self.assertEqual(0.0, weighed_host.weight) self.assertEqual(winner, utils.extract_host(weighed_host.obj.host)) @@ -174,7 +174,7 @@ class CapacityWeigherTestCase(test.TestCase): @ddt.unpack def test_capacity_weight_multiplier2(self, volume_type, winner): self.flags(capacity_weight_multiplier=2.0) - hostinfo_list = self._get_all_hosts() + backend_info_list = self._get_all_backends() # Results for the 1st test # {'provisioning:type': 'thin'}: @@ -202,7 +202,7 @@ class CapacityWeigherTestCase(test.TestCase): 'volume_type': volume_type, } weighed_host = self._get_weighed_hosts( - hostinfo_list, + backend_info_list, weight_properties=weight_properties)[0] self.assertEqual(1.0 * 2, weighed_host.weight) self.assertEqual(winner, utils.extract_host(weighed_host.obj.host)) @@ -210,7 +210,7 @@ class CapacityWeigherTestCase(test.TestCase): def test_capacity_weight_no_unknown_or_infinite(self): self.flags(capacity_weight_multiplier=-1.0) del self.host_manager.service_states['host5'] - hostinfo_list = self._get_all_hosts() + backend_info_list = self._get_all_backends() # host1: thin_provisioning_support = False # free_capacity_gb=1024, @@ -229,7 +229,7 @@ class CapacityWeigherTestCase(test.TestCase): # Norm=0.0 # so, host4 should win: - weighed_hosts = self._get_weighed_hosts(hostinfo_list) + weighed_hosts = self._get_weighed_hosts(backend_info_list) best_host = weighed_hosts[0] self.assertEqual(0.0, best_host.weight) self.assertEqual('host4', utils.extract_host(best_host.obj.host)) @@ -250,7 +250,7 @@ class CapacityWeigherTestCase(test.TestCase): 'thick_provisioning_support': False, 'reserved_percentage': 5, 'timestamp': datetime.utcnow()} - hostinfo_list = self._get_all_hosts() + backend_info_list = self._get_all_backends() # host1: thin_provisioning_support = False # free_capacity_gb=1024, @@ -271,7 +271,7 @@ class CapacityWeigherTestCase(test.TestCase): # Norm=-1.0 # so, host4 should win: - weighed_hosts = self._get_weighed_hosts(hostinfo_list) + weighed_hosts = self._get_weighed_hosts(backend_info_list) best_host = weighed_hosts[0] self.assertEqual(0.0, best_host.weight) self.assertEqual('host4', utils.extract_host(best_host.obj.host)) @@ -292,7 +292,7 @@ class CapacityWeigherTestCase(test.TestCase): 'thick_provisioning_support': False, 'reserved_percentage': 5, 'timestamp': datetime.utcnow()} - hostinfo_list = self._get_all_hosts() + backend_info_list = self._get_all_backends() # host1: thin_provisioning_support = False # free_capacity_gb=1024, @@ -313,7 +313,7 @@ class CapacityWeigherTestCase(test.TestCase): # Norm=-1.0 # so, host4 should win: - weighed_hosts = self._get_weighed_hosts(hostinfo_list) + weighed_hosts = self._get_weighed_hosts(backend_info_list) best_host = weighed_hosts[0] self.assertEqual(0.0, best_host.weight) self.assertEqual('host4', utils.extract_host(best_host.obj.host)) @@ -334,7 +334,7 @@ class CapacityWeigherTestCase(test.TestCase): 'thick_provisioning_support': False, 'reserved_percentage': 5, 'timestamp': datetime.utcnow()} - hostinfo_list = self._get_all_hosts() + backend_info_list = self._get_all_backends() # host1: thin_provisioning_support = False # free_capacity_gb=1024, @@ -355,7 +355,7 @@ class CapacityWeigherTestCase(test.TestCase): # Norm=-1.0 # so, host4 should win: - weighed_hosts = self._get_weighed_hosts(hostinfo_list) + weighed_hosts = self._get_weighed_hosts(backend_info_list) best_host = weighed_hosts[0] self.assertEqual(0.0, best_host.weight) self.assertEqual('host4', utils.extract_host(best_host.obj.host)) @@ -376,7 +376,7 @@ class CapacityWeigherTestCase(test.TestCase): 'thick_provisioning_support': False, 'reserved_percentage': 5, 'timestamp': datetime.utcnow()} - hostinfo_list = self._get_all_hosts() + backend_info_list = self._get_all_backends() # host1: thin_provisioning_support = False # free_capacity_gb=1024, @@ -397,7 +397,7 @@ class CapacityWeigherTestCase(test.TestCase): # Norm=-1.0 # so, host4 should win: - weighed_hosts = self._get_weighed_hosts(hostinfo_list) + weighed_hosts = self._get_weighed_hosts(backend_info_list) best_host = weighed_hosts[0] self.assertEqual(0.0, best_host.weight) self.assertEqual('host4', utils.extract_host(best_host.obj.host)) diff --git a/cinder/tests/unit/scheduler/test_chance_weigher.py b/cinder/tests/unit/scheduler/test_chance_weigher.py index 651707af17f..e99c42d130f 100644 --- a/cinder/tests/unit/scheduler/test_chance_weigher.py +++ b/cinder/tests/unit/scheduler/test_chance_weigher.py @@ -50,7 +50,7 @@ class ChanceWeigherTestCase(test.TestCase): # ensure HostManager can load the ChanceWeigher # via the entry points mechanism hm = host_manager.HostManager() - weighers = hm._choose_host_weighers('ChanceWeigher') + weighers = hm._choose_backend_weighers('ChanceWeigher') self.assertEqual(1, len(weighers)) self.assertEqual(weighers[0], chance.ChanceWeigher) @@ -58,7 +58,8 @@ class ChanceWeigherTestCase(test.TestCase): # ensure we don't lose any hosts when weighing with # the ChanceWeigher hm = host_manager.HostManager() - fake_hosts = [host_manager.HostState('fake_host%s' % x, None) - for x in range(1, 5)] - weighed_hosts = hm.get_weighed_hosts(fake_hosts, {}, 'ChanceWeigher') - self.assertEqual(4, len(weighed_hosts)) + fake_backends = [host_manager.BackendState('fake_be%s' % x, None) + for x in range(1, 5)] + weighed_backends = hm.get_weighed_backends(fake_backends, {}, + 'ChanceWeigher') + self.assertEqual(4, len(weighed_backends)) diff --git a/cinder/tests/unit/scheduler/test_filter_scheduler.py b/cinder/tests/unit/scheduler/test_filter_scheduler.py index f45dad7c7c7..57c73542d46 100644 --- a/cinder/tests/unit/scheduler/test_filter_scheduler.py +++ b/cinder/tests/unit/scheduler/test_filter_scheduler.py @@ -35,7 +35,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): driver_cls = filter_scheduler.FilterScheduler def test_create_group_no_hosts(self): - # Ensure empty hosts result in NoValidHosts exception. + # Ensure empty hosts result in NoValidBackend exception. sched = fakes.FakeFilterScheduler() fake_context = context.RequestContext('user', 'project') @@ -51,7 +51,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): group_spec = {'group_type': {'name': 'GrpType'}, 'volume_properties': {'project_id': 1, 'size': 0}} - self.assertRaises(exception.NoValidHost, + self.assertRaises(exception.NoValidBackend, sched.schedule_create_group, fake_context, 'faki-id1', group_spec, request_spec_list, {}, []) @@ -87,7 +87,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): self.assertTrue(_mock_service_get_all.called) def test_create_consistencygroup_no_hosts(self): - # Ensure empty hosts result in NoValidHosts exception. + # Ensure empty hosts result in NoValidBackend exception. sched = fakes.FakeFilterScheduler() fake_context = context.RequestContext('user', 'project') @@ -100,7 +100,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): 'volume_type': {'name': 'Type2', 'extra_specs': {}}} request_spec_list = [request_spec, request_spec2] - self.assertRaises(exception.NoValidHost, + self.assertRaises(exception.NoValidBackend, sched.schedule_create_consistencygroup, fake_context, 'faki-id1', request_spec_list, {}) @@ -161,7 +161,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): self.assertTrue(_mock_service_get_all.called) def test_create_volume_no_hosts(self): - # Ensure empty hosts/child_zones result in NoValidHosts exception. + # Ensure empty hosts/child_zones result in NoValidBackend exception. sched = fakes.FakeFilterScheduler() fake_context = context.RequestContext('user', 'project') @@ -170,8 +170,9 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): 'volume_type': {'name': 'LVM_iSCSI'}, 'volume_id': fake.VOLUME_ID} request_spec = objects.RequestSpec.from_primitives(request_spec) - self.assertRaises(exception.NoValidHost, sched.schedule_create_volume, - fake_context, request_spec, {}) + self.assertRaises(exception.NoValidBackend, + sched.schedule_create_volume, fake_context, + request_spec, {}) def test_create_volume_no_hosts_invalid_req(self): sched = fakes.FakeFilterScheduler() @@ -183,7 +184,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): 'size': 1}, 'volume_type': {'name': 'LVM_iSCSI'}} request_spec = objects.RequestSpec.from_primitives(request_spec) - self.assertRaises(exception.NoValidHost, + self.assertRaises(exception.NoValidBackend, sched.schedule_create_volume, fake_context, request_spec, @@ -199,15 +200,15 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): 'size': 1}, 'volume_id': fake.VOLUME_ID} request_spec = objects.RequestSpec.from_primitives(request_spec) - self.assertRaises(exception.NoValidHost, + self.assertRaises(exception.NoValidBackend, sched.schedule_create_volume, fake_context, request_spec, {}) @mock.patch('cinder.scheduler.host_manager.HostManager.' - 'get_all_host_states') - def test_create_volume_non_admin(self, _mock_get_all_host_states): + 'get_all_backend_states') + def test_create_volume_non_admin(self, _mock_get_all_backend_states): # Test creating a volume locally using create_volume, passing # a non-admin context. DB actions should work. self.was_admin = False @@ -219,7 +220,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): return {} sched = fakes.FakeFilterScheduler() - _mock_get_all_host_states.side_effect = fake_get + _mock_get_all_backend_states.side_effect = fake_get fake_context = context.RequestContext('user', 'project') @@ -228,8 +229,9 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): 'volume_type': {'name': 'LVM_iSCSI'}, 'volume_id': fake.VOLUME_ID} request_spec = objects.RequestSpec.from_primitives(request_spec) - self.assertRaises(exception.NoValidHost, sched.schedule_create_volume, - fake_context, request_spec, {}) + self.assertRaises(exception.NoValidBackend, + sched.schedule_create_volume, fake_context, + request_spec, {}) self.assertTrue(self.was_admin) @mock.patch('cinder.db.service_get_all') @@ -393,38 +395,38 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): retry = dict(num_attempts=2) filter_properties = dict(retry=retry) - self.assertRaises(exception.NoValidHost, sched._schedule, self.context, - request_spec, filter_properties=filter_properties) + self.assertRaises(exception.NoValidBackend, sched._schedule, + self.context, request_spec, + filter_properties=filter_properties) - def test_add_retry_host(self): - retry = dict(num_attempts=1, hosts=[]) + def test_add_retry_backend(self): + retry = dict(num_attempts=1, backends=[]) filter_properties = dict(retry=retry) - host = "fakehost" + backend = "fakehost" sched = fakes.FakeFilterScheduler() - sched._add_retry_host(filter_properties, host) + sched._add_retry_backend(filter_properties, backend) - hosts = filter_properties['retry']['hosts'] - self.assertEqual(1, len(hosts)) - self.assertEqual(host, hosts[0]) + backends = filter_properties['retry']['backends'] + self.assertListEqual([backend], backends) def test_post_select_populate(self): # Test addition of certain filter props after a node is selected. - retry = {'hosts': [], 'num_attempts': 1} + retry = {'backends': [], 'num_attempts': 1} filter_properties = {'retry': retry} sched = fakes.FakeFilterScheduler() - host_state = host_manager.HostState('host', None) - host_state.total_capacity_gb = 1024 + backend_state = host_manager.BackendState('host', None) + backend_state.total_capacity_gb = 1024 sched._post_select_populate_filter_properties(filter_properties, - host_state) + backend_state) self.assertEqual('host', - filter_properties['retry']['hosts'][0]) + filter_properties['retry']['backends'][0]) - self.assertEqual(1024, host_state.total_capacity_gb) + self.assertEqual(1024, backend_state.total_capacity_gb) - def _host_passes_filters_setup(self, mock_obj): + def _backend_passes_filters_setup(self, mock_obj): sched = fakes.FakeFilterScheduler() sched.host_manager = fakes.FakeHostManager() fake_context = context.RequestContext('user', 'project', @@ -435,48 +437,48 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): return (sched, fake_context) @mock.patch('cinder.db.service_get_all') - def test_host_passes_filters_happy_day(self, _mock_service_get_topic): - """Do a successful pass through of with host_passes_filters().""" - sched, ctx = self._host_passes_filters_setup( + def test_backend_passes_filters_happy_day(self, _mock_service_get_topic): + """Do a successful pass through of with backend_passes_filters().""" + sched, ctx = self._backend_passes_filters_setup( _mock_service_get_topic) request_spec = {'volume_id': fake.VOLUME_ID, 'volume_type': {'name': 'LVM_iSCSI'}, 'volume_properties': {'project_id': 1, 'size': 1}} request_spec = objects.RequestSpec.from_primitives(request_spec) - ret_host = sched.host_passes_filters(ctx, 'host1#lvm1', - request_spec, {}) + ret_host = sched.backend_passes_filters(ctx, 'host1#lvm1', + request_spec, {}) self.assertEqual('host1', utils.extract_host(ret_host.host)) self.assertTrue(_mock_service_get_topic.called) @mock.patch('cinder.db.service_get_all') - def test_host_passes_filters_default_pool_happy_day( + def test_backend_passes_filters_default_pool_happy_day( self, _mock_service_get_topic): - """Do a successful pass through of with host_passes_filters().""" - sched, ctx = self._host_passes_filters_setup( + """Do a successful pass through of with backend_passes_filters().""" + sched, ctx = self._backend_passes_filters_setup( _mock_service_get_topic) request_spec = {'volume_id': fake.VOLUME_ID, 'volume_type': {'name': 'LVM_iSCSI'}, 'volume_properties': {'project_id': 1, 'size': 1}} request_spec = objects.RequestSpec.from_primitives(request_spec) - ret_host = sched.host_passes_filters(ctx, 'host5#_pool0', - request_spec, {}) + ret_host = sched.backend_passes_filters(ctx, 'host5#_pool0', + request_spec, {}) self.assertEqual('host5', utils.extract_host(ret_host.host)) self.assertTrue(_mock_service_get_topic.called) @mock.patch('cinder.db.service_get_all') - def test_host_passes_filters_no_capacity(self, _mock_service_get_topic): + def test_backend_passes_filters_no_capacity(self, _mock_service_get_topic): """Fail the host due to insufficient capacity.""" - sched, ctx = self._host_passes_filters_setup( + sched, ctx = self._backend_passes_filters_setup( _mock_service_get_topic) request_spec = {'volume_id': fake.VOLUME_ID, 'volume_type': {'name': 'LVM_iSCSI'}, 'volume_properties': {'project_id': 1, 'size': 1024}} request_spec = objects.RequestSpec.from_primitives(request_spec) - self.assertRaises(exception.NoValidHost, - sched.host_passes_filters, + self.assertRaises(exception.NoValidBackend, + sched.backend_passes_filters, ctx, 'host1#lvm1', request_spec, {}) self.assertTrue(_mock_service_get_topic.called) @@ -486,7 +488,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): # policy=never. host4 doesn't have enough space to hold an additional # 200GB, but it is already the host of this volume and should not be # counted twice. - sched, ctx = self._host_passes_filters_setup( + sched, ctx = self._backend_passes_filters_setup( _mock_service_get_topic) extra_specs = {'volume_backend_name': 'lvm4'} request_spec = {'volume_id': fake.VOLUME_ID, @@ -496,9 +498,9 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): 'size': 200, 'host': 'host4#lvm4'}} request_spec = objects.RequestSpec.from_primitives(request_spec) - host_state = sched.find_retype_host(ctx, request_spec, - filter_properties={}, - migration_policy='never') + host_state = sched.find_retype_backend(ctx, request_spec, + filter_properties={}, + migration_policy='never') self.assertEqual('host4', utils.extract_host(host_state.host)) @mock.patch('cinder.db.service_get_all') @@ -508,7 +510,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): # policy=never. host4 doesn't have enough space to hold an additional # 200GB, but it is already the host of this volume and should not be # counted twice. - sched, ctx = self._host_passes_filters_setup( + sched, ctx = self._backend_passes_filters_setup( _mock_service_get_topic) extra_specs = {'volume_backend_name': 'lvm3'} request_spec = {'volume_id': fake.VOLUME_ID, @@ -518,16 +520,16 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): 'size': 200, 'host': 'host3#lvm3'}} request_spec = objects.RequestSpec.from_primitives(request_spec) - host_state = sched.find_retype_host(ctx, request_spec, - filter_properties={}, - migration_policy='never') + host_state = sched.find_retype_backend(ctx, request_spec, + filter_properties={}, + migration_policy='never') self.assertEqual('host3#lvm3', host_state.host) @mock.patch('cinder.db.service_get_all') def test_retype_policy_never_migrate_fail(self, _mock_service_get_topic): # Retype should fail if current host doesn't pass filters and # policy=never. - sched, ctx = self._host_passes_filters_setup( + sched, ctx = self._backend_passes_filters_setup( _mock_service_get_topic) extra_specs = {'volume_backend_name': 'lvm1'} request_spec = {'volume_id': fake.VOLUME_ID, @@ -537,15 +539,15 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): 'size': 200, 'host': 'host4'}} request_spec = objects.RequestSpec.from_primitives(request_spec) - self.assertRaises(exception.NoValidHost, sched.find_retype_host, ctx, - request_spec, filter_properties={}, + self.assertRaises(exception.NoValidBackend, sched.find_retype_backend, + ctx, request_spec, filter_properties={}, migration_policy='never') @mock.patch('cinder.db.service_get_all') def test_retype_policy_demand_migrate_pass(self, _mock_service_get_topic): # Retype should pass if current host fails filters but another host # is suitable when policy=on-demand. - sched, ctx = self._host_passes_filters_setup( + sched, ctx = self._backend_passes_filters_setup( _mock_service_get_topic) extra_specs = {'volume_backend_name': 'lvm1'} request_spec = {'volume_id': fake.VOLUME_ID, @@ -555,16 +557,16 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): 'size': 200, 'host': 'host4'}} request_spec = objects.RequestSpec.from_primitives(request_spec) - host_state = sched.find_retype_host(ctx, request_spec, - filter_properties={}, - migration_policy='on-demand') + host_state = sched.find_retype_backend(ctx, request_spec, + filter_properties={}, + migration_policy='on-demand') self.assertEqual('host1', utils.extract_host(host_state.host)) @mock.patch('cinder.db.service_get_all') def test_retype_policy_demand_migrate_fail(self, _mock_service_get_topic): # Retype should fail if current host doesn't pass filters and # no other suitable candidates exist even if policy=on-demand. - sched, ctx = self._host_passes_filters_setup( + sched, ctx = self._backend_passes_filters_setup( _mock_service_get_topic) extra_specs = {'volume_backend_name': 'lvm1'} request_spec = {'volume_id': fake.VOLUME_ID, @@ -574,6 +576,6 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): 'size': 2048, 'host': 'host4'}} request_spec = objects.RequestSpec.from_primitives(request_spec) - self.assertRaises(exception.NoValidHost, sched.find_retype_host, ctx, - request_spec, filter_properties={}, + self.assertRaises(exception.NoValidBackend, sched.find_retype_backend, + ctx, request_spec, filter_properties={}, migration_policy='on-demand') diff --git a/cinder/tests/unit/scheduler/test_goodness_weigher.py b/cinder/tests/unit/scheduler/test_goodness_weigher.py index d9c74678d16..80f14118f85 100644 --- a/cinder/tests/unit/scheduler/test_goodness_weigher.py +++ b/cinder/tests/unit/scheduler/test_goodness_weigher.py @@ -23,7 +23,7 @@ from cinder.tests.unit.scheduler import fakes class GoodnessWeigherTestCase(test.TestCase): def test_goodness_weigher_with_no_goodness_function(self): weigher = goodness.GoodnessWeigher() - host_state = fakes.FakeHostState('host1', { + host_state = fakes.FakeBackendState('host1', { 'host': 'host.example.com', 'capabilities': { 'foo': '50' @@ -36,19 +36,19 @@ class GoodnessWeigherTestCase(test.TestCase): def test_goodness_weigher_passing_host(self): weigher = goodness.GoodnessWeigher() - host_state = fakes.FakeHostState('host1', { + host_state = fakes.FakeBackendState('host1', { 'host': 'host.example.com', 'capabilities': { 'goodness_function': '100' } }) - host_state_2 = fakes.FakeHostState('host2', { + host_state_2 = fakes.FakeBackendState('host2', { 'host': 'host2.example.com', 'capabilities': { 'goodness_function': '0' } }) - host_state_3 = fakes.FakeHostState('host3', { + host_state_3 = fakes.FakeBackendState('host3', { 'host': 'host3.example.com', 'capabilities': { 'goodness_function': '100 / 2' @@ -65,7 +65,7 @@ class GoodnessWeigherTestCase(test.TestCase): def test_goodness_weigher_capabilities_substitution(self): weigher = goodness.GoodnessWeigher() - host_state = fakes.FakeHostState('host1', { + host_state = fakes.FakeBackendState('host1', { 'host': 'host.example.com', 'capabilities': { 'foo': 50, @@ -79,7 +79,7 @@ class GoodnessWeigherTestCase(test.TestCase): def test_goodness_weigher_extra_specs_substitution(self): weigher = goodness.GoodnessWeigher() - host_state = fakes.FakeHostState('host1', { + host_state = fakes.FakeBackendState('host1', { 'host': 'host.example.com', 'capabilities': { 'goodness_function': '10 + extra.foo' @@ -98,7 +98,7 @@ class GoodnessWeigherTestCase(test.TestCase): def test_goodness_weigher_volume_substitution(self): weigher = goodness.GoodnessWeigher() - host_state = fakes.FakeHostState('host1', { + host_state = fakes.FakeBackendState('host1', { 'host': 'host.example.com', 'capabilities': { 'goodness_function': '10 + volume.foo' @@ -117,7 +117,7 @@ class GoodnessWeigherTestCase(test.TestCase): def test_goodness_weigher_qos_substitution(self): weigher = goodness.GoodnessWeigher() - host_state = fakes.FakeHostState('host1', { + host_state = fakes.FakeBackendState('host1', { 'host': 'host.example.com', 'capabilities': { 'goodness_function': '10 + qos.foo' @@ -134,7 +134,7 @@ class GoodnessWeigherTestCase(test.TestCase): def test_goodness_weigher_stats_substitution(self): weigher = goodness.GoodnessWeigher() - host_state = fakes.FakeHostState('host1', { + host_state = fakes.FakeBackendState('host1', { 'host': 'host.example.com', 'capabilities': { 'goodness_function': 'stats.free_capacity_gb > 20' @@ -148,7 +148,7 @@ class GoodnessWeigherTestCase(test.TestCase): def test_goodness_weigher_invalid_substitution(self): weigher = goodness.GoodnessWeigher() - host_state = fakes.FakeHostState('host1', { + host_state = fakes.FakeBackendState('host1', { 'host': 'host.example.com', 'capabilities': { 'goodness_function': '10 + stats.my_val' @@ -162,13 +162,13 @@ class GoodnessWeigherTestCase(test.TestCase): def test_goodness_weigher_host_rating_out_of_bounds(self): weigher = goodness.GoodnessWeigher() - host_state = fakes.FakeHostState('host1', { + host_state = fakes.FakeBackendState('host1', { 'host': 'host.example.com', 'capabilities': { 'goodness_function': '-10' } }) - host_state_2 = fakes.FakeHostState('host2', { + host_state_2 = fakes.FakeBackendState('host2', { 'host': 'host2.example.com', 'capabilities': { 'goodness_function': '200' @@ -183,7 +183,7 @@ class GoodnessWeigherTestCase(test.TestCase): def test_goodness_weigher_invalid_goodness_function(self): weigher = goodness.GoodnessWeigher() - host_state = fakes.FakeHostState('host1', { + host_state = fakes.FakeBackendState('host1', { 'host': 'host.example.com', 'capabilities': { 'goodness_function': '50 / 0' diff --git a/cinder/tests/unit/scheduler/test_host_filters.py b/cinder/tests/unit/scheduler/test_host_filters.py index f2294a12391..45ef503d783 100644 --- a/cinder/tests/unit/scheduler/test_host_filters.py +++ b/cinder/tests/unit/scheduler/test_host_filters.py @@ -32,15 +32,16 @@ from cinder.tests.unit.scheduler import fakes from cinder.tests.unit import utils -class HostFiltersTestCase(test.TestCase): - """Test case for host filters.""" +class BackendFiltersTestCase(test.TestCase): + """Test case for backend filters.""" def setUp(self): - super(HostFiltersTestCase, self).setUp() + super(BackendFiltersTestCase, self).setUp() self.context = context.RequestContext(fake.USER_ID, fake.PROJECT_ID) # This has a side effect of testing 'get_filter_classes' # when specifying a method (in this case, our standard filters) - filter_handler = filters.HostFilterHandler('cinder.scheduler.filters') + filter_handler = filters.BackendFilterHandler( + 'cinder.scheduler.filters') classes = filter_handler.get_all_classes() self.class_map = {} for cls in classes: @@ -50,7 +51,7 @@ class HostFiltersTestCase(test.TestCase): @ddt.ddt @mock.patch('cinder.objects.service.Service.is_up', new_callable=mock.PropertyMock) -class CapacityFilterTestCase(HostFiltersTestCase): +class CapacityFilterTestCase(BackendFiltersTestCase): def setUp(self): super(CapacityFilterTestCase, self).setUp() self.json_query = jsonutils.dumps( @@ -64,25 +65,25 @@ class CapacityFilterTestCase(HostFiltersTestCase): filter_properties = {'size': 100, 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 500, - 'free_capacity_gb': 200, - 'updated_at': None, - 'service': service}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 500, + 'free_capacity_gb': 200, + 'updated_at': None, + 'service': service}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) - def test_filter_current_host_passes(self, _mock_serv_is_up): + def test_filter_current_backend_passes(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True filt_cls = self.class_map['CapacityFilter']() filter_properties = {'size': 100, 'vol_exists_on': 'host1', 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 100, - 'free_capacity_gb': 10, - 'updated_at': None, - 'service': service}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 100, + 'free_capacity_gb': 10, + 'updated_at': None, + 'service': service}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_filter_fails(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -90,13 +91,13 @@ class CapacityFilterTestCase(HostFiltersTestCase): filter_properties = {'size': 100, 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 200, - 'free_capacity_gb': 120, - 'reserved_percentage': 20, - 'updated_at': None, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 200, + 'free_capacity_gb': 120, + 'reserved_percentage': 20, + 'updated_at': None, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_filter_fails_free_capacity_None(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -104,11 +105,11 @@ class CapacityFilterTestCase(HostFiltersTestCase): filter_properties = {'size': 100, 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'free_capacity_gb': None, - 'updated_at': None, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_capacity_gb': None, + 'updated_at': None, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_filter_passes_infinite(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -116,11 +117,11 @@ class CapacityFilterTestCase(HostFiltersTestCase): filter_properties = {'size': 100, 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'free_capacity_gb': 'infinite', - 'updated_at': None, - 'service': service}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_capacity_gb': 'infinite', + 'updated_at': None, + 'service': service}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_filter_extend_request(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -128,12 +129,12 @@ class CapacityFilterTestCase(HostFiltersTestCase): filter_properties = {'new_size': 100, 'size': 50, 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'free_capacity_gb': 200, - 'updated_at': None, - 'total_capacity_gb': 500, - 'service': service}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_capacity_gb': 200, + 'updated_at': None, + 'total_capacity_gb': 500, + 'service': service}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_filter_extend_request_negative(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -141,12 +142,12 @@ class CapacityFilterTestCase(HostFiltersTestCase): filter_properties = {'size': 50, 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'free_capacity_gb': 49, - 'updated_at': None, - 'total_capacity_gb': 500, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_capacity_gb': 49, + 'updated_at': None, + 'total_capacity_gb': 500, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_filter_passes_unknown(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -154,11 +155,11 @@ class CapacityFilterTestCase(HostFiltersTestCase): filter_properties = {'size': 100, 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'free_capacity_gb': 'unknown', - 'updated_at': None, - 'service': service}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_capacity_gb': 'unknown', + 'updated_at': None, + 'service': service}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_filter_passes_total_infinite(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -166,13 +167,13 @@ class CapacityFilterTestCase(HostFiltersTestCase): filter_properties = {'size': 100, 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'free_capacity_gb': 'infinite', - 'total_capacity_gb': 'infinite', - 'reserved_percentage': 0, - 'updated_at': None, - 'service': service}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_capacity_gb': 'infinite', + 'total_capacity_gb': 'infinite', + 'reserved_percentage': 0, + 'updated_at': None, + 'service': service}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_filter_passes_total_unknown(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -180,13 +181,13 @@ class CapacityFilterTestCase(HostFiltersTestCase): filter_properties = {'size': 100, 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'free_capacity_gb': 'unknown', - 'total_capacity_gb': 'unknown', - 'reserved_percentage': 0, - 'updated_at': None, - 'service': service}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_capacity_gb': 'unknown', + 'total_capacity_gb': 'unknown', + 'reserved_percentage': 0, + 'updated_at': None, + 'service': service}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_filter_fails_total_infinite(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -194,12 +195,12 @@ class CapacityFilterTestCase(HostFiltersTestCase): filter_properties = {'size': 100, 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 'infinite', - 'reserved_percentage': 5, - 'updated_at': None, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 'infinite', + 'reserved_percentage': 5, + 'updated_at': None, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_filter_fails_total_unknown(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -207,12 +208,12 @@ class CapacityFilterTestCase(HostFiltersTestCase): filter_properties = {'size': 100, 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 'unknown', - 'reserved_percentage': 5, - 'updated_at': None, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 'unknown', + 'reserved_percentage': 5, + 'updated_at': None, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_filter_fails_total_zero(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -220,12 +221,12 @@ class CapacityFilterTestCase(HostFiltersTestCase): filter_properties = {'size': 100, 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 0, - 'reserved_percentage': 5, - 'updated_at': None, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 0, + 'reserved_percentage': 5, + 'updated_at': None, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_filter_thin_true_passes(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -237,17 +238,17 @@ class CapacityFilterTestCase(HostFiltersTestCase): ' False', 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 500, - 'free_capacity_gb': 200, - 'provisioned_capacity_gb': 500, - 'max_over_subscription_ratio': 2.0, - 'reserved_percentage': 5, - 'thin_provisioning_support': True, - 'thick_provisioning_support': False, - 'updated_at': None, - 'service': service}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 500, + 'free_capacity_gb': 200, + 'provisioned_capacity_gb': 500, + 'max_over_subscription_ratio': 2.0, + 'reserved_percentage': 5, + 'thin_provisioning_support': True, + 'thick_provisioning_support': False, + 'updated_at': None, + 'service': service}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_filter_thin_true_passes2(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -259,17 +260,17 @@ class CapacityFilterTestCase(HostFiltersTestCase): ' False', 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 500, - 'free_capacity_gb': 200, - 'provisioned_capacity_gb': 7000, - 'max_over_subscription_ratio': 20, - 'reserved_percentage': 5, - 'thin_provisioning_support': True, - 'thick_provisioning_support': False, - 'updated_at': None, - 'service': service}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 500, + 'free_capacity_gb': 200, + 'provisioned_capacity_gb': 7000, + 'max_over_subscription_ratio': 20, + 'reserved_percentage': 5, + 'thin_provisioning_support': True, + 'thick_provisioning_support': False, + 'updated_at': None, + 'service': service}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_filter_thin_false_passes(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -283,17 +284,17 @@ class CapacityFilterTestCase(HostFiltersTestCase): service = {'disabled': False} # If "thin_provisioning_support" is False, # "max_over_subscription_ratio" will be ignored. - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 500, - 'free_capacity_gb': 200, - 'provisioned_capacity_gb': 300, - 'max_over_subscription_ratio': 1.0, - 'reserved_percentage': 5, - 'thin_provisioning_support': False, - 'thick_provisioning_support': True, - 'updated_at': None, - 'service': service}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 500, + 'free_capacity_gb': 200, + 'provisioned_capacity_gb': 300, + 'max_over_subscription_ratio': 1.0, + 'reserved_percentage': 5, + 'thin_provisioning_support': False, + 'thick_provisioning_support': True, + 'updated_at': None, + 'service': service}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_filter_over_subscription_less_than_1(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -305,17 +306,17 @@ class CapacityFilterTestCase(HostFiltersTestCase): ' False', 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 500, - 'free_capacity_gb': 100, - 'provisioned_capacity_gb': 400, - 'max_over_subscription_ratio': 0.8, - 'reserved_percentage': 0, - 'thin_provisioning_support': True, - 'thick_provisioning_support': False, - 'updated_at': None, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 500, + 'free_capacity_gb': 100, + 'provisioned_capacity_gb': 400, + 'max_over_subscription_ratio': 0.8, + 'reserved_percentage': 0, + 'thin_provisioning_support': True, + 'thick_provisioning_support': False, + 'updated_at': None, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_filter_over_subscription_equal_to_1(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -327,17 +328,17 @@ class CapacityFilterTestCase(HostFiltersTestCase): ' False', 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 500, - 'free_capacity_gb': 200, - 'provisioned_capacity_gb': 400, - 'max_over_subscription_ratio': 1.0, - 'reserved_percentage': 0, - 'thin_provisioning_support': True, - 'thick_provisioning_support': False, - 'updated_at': None, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 500, + 'free_capacity_gb': 200, + 'provisioned_capacity_gb': 400, + 'max_over_subscription_ratio': 1.0, + 'reserved_percentage': 0, + 'thin_provisioning_support': True, + 'thick_provisioning_support': False, + 'updated_at': None, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_filter_over_subscription_fails(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -349,17 +350,17 @@ class CapacityFilterTestCase(HostFiltersTestCase): ' False', 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 500, - 'free_capacity_gb': 200, - 'provisioned_capacity_gb': 700, - 'max_over_subscription_ratio': 1.5, - 'reserved_percentage': 5, - 'thin_provisioning_support': True, - 'thick_provisioning_support': False, - 'updated_at': None, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 500, + 'free_capacity_gb': 200, + 'provisioned_capacity_gb': 700, + 'max_over_subscription_ratio': 1.5, + 'reserved_percentage': 5, + 'thin_provisioning_support': True, + 'thick_provisioning_support': False, + 'updated_at': None, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_filter_over_subscription_fails2(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -371,17 +372,17 @@ class CapacityFilterTestCase(HostFiltersTestCase): ' False', 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 500, - 'free_capacity_gb': 30, - 'provisioned_capacity_gb': 9000, - 'max_over_subscription_ratio': 20, - 'reserved_percentage': 0, - 'thin_provisioning_support': True, - 'thick_provisioning_support': False, - 'updated_at': None, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 500, + 'free_capacity_gb': 30, + 'provisioned_capacity_gb': 9000, + 'max_over_subscription_ratio': 20, + 'reserved_percentage': 0, + 'thin_provisioning_support': True, + 'thick_provisioning_support': False, + 'updated_at': None, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_filter_reserved_thin_true_fails(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -393,17 +394,17 @@ class CapacityFilterTestCase(HostFiltersTestCase): ' False', 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 500, - 'free_capacity_gb': 100, - 'provisioned_capacity_gb': 1000, - 'max_over_subscription_ratio': 2.0, - 'reserved_percentage': 5, - 'thin_provisioning_support': True, - 'thick_provisioning_support': False, - 'updated_at': None, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 500, + 'free_capacity_gb': 100, + 'provisioned_capacity_gb': 1000, + 'max_over_subscription_ratio': 2.0, + 'reserved_percentage': 5, + 'thin_provisioning_support': True, + 'thick_provisioning_support': False, + 'updated_at': None, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_filter_reserved_thin_false_fails(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -417,17 +418,17 @@ class CapacityFilterTestCase(HostFiltersTestCase): service = {'disabled': False} # If "thin_provisioning_support" is False, # "max_over_subscription_ratio" will be ignored. - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 500, - 'free_capacity_gb': 100, - 'provisioned_capacity_gb': 400, - 'max_over_subscription_ratio': 1.0, - 'reserved_percentage': 5, - 'thin_provisioning_support': False, - 'thick_provisioning_support': True, - 'updated_at': None, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 500, + 'free_capacity_gb': 100, + 'provisioned_capacity_gb': 400, + 'max_over_subscription_ratio': 1.0, + 'reserved_percentage': 5, + 'thin_provisioning_support': False, + 'thick_provisioning_support': True, + 'updated_at': None, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_filter_reserved_thin_thick_true_fails(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -439,17 +440,17 @@ class CapacityFilterTestCase(HostFiltersTestCase): ' True', 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 500, - 'free_capacity_gb': 0, - 'provisioned_capacity_gb': 800, - 'max_over_subscription_ratio': 2.0, - 'reserved_percentage': 5, - 'thin_provisioning_support': True, - 'thick_provisioning_support': True, - 'updated_at': None, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 500, + 'free_capacity_gb': 0, + 'provisioned_capacity_gb': 800, + 'max_over_subscription_ratio': 2.0, + 'reserved_percentage': 5, + 'thin_provisioning_support': True, + 'thick_provisioning_support': True, + 'updated_at': None, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_filter_reserved_thin_thick_true_passes(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -461,17 +462,17 @@ class CapacityFilterTestCase(HostFiltersTestCase): ' True', 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 500, - 'free_capacity_gb': 125, - 'provisioned_capacity_gb': 400, - 'max_over_subscription_ratio': 2.0, - 'reserved_percentage': 5, - 'thin_provisioning_support': True, - 'thick_provisioning_support': True, - 'updated_at': None, - 'service': service}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 500, + 'free_capacity_gb': 125, + 'provisioned_capacity_gb': 400, + 'max_over_subscription_ratio': 2.0, + 'reserved_percentage': 5, + 'thin_provisioning_support': True, + 'thick_provisioning_support': True, + 'updated_at': None, + 'service': service}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_filter_reserved_thin_true_passes(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -483,17 +484,17 @@ class CapacityFilterTestCase(HostFiltersTestCase): ' False', 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 500, - 'free_capacity_gb': 80, - 'provisioned_capacity_gb': 600, - 'max_over_subscription_ratio': 2.0, - 'reserved_percentage': 5, - 'thin_provisioning_support': True, - 'thick_provisioning_support': False, - 'updated_at': None, - 'service': service}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 500, + 'free_capacity_gb': 80, + 'provisioned_capacity_gb': 600, + 'max_over_subscription_ratio': 2.0, + 'reserved_percentage': 5, + 'thin_provisioning_support': True, + 'thick_provisioning_support': False, + 'updated_at': None, + 'service': service}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_filter_reserved_thin_thick_true_fails2(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -505,17 +506,17 @@ class CapacityFilterTestCase(HostFiltersTestCase): ' True', 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 500, - 'free_capacity_gb': 99, - 'provisioned_capacity_gb': 1000, - 'max_over_subscription_ratio': 2.0, - 'reserved_percentage': 5, - 'thin_provisioning_support': True, - 'thick_provisioning_support': True, - 'updated_at': None, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 500, + 'free_capacity_gb': 99, + 'provisioned_capacity_gb': 1000, + 'max_over_subscription_ratio': 2.0, + 'reserved_percentage': 5, + 'thin_provisioning_support': True, + 'thick_provisioning_support': True, + 'updated_at': None, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_filter_reserved_thin_thick_true_passes2(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True @@ -527,17 +528,17 @@ class CapacityFilterTestCase(HostFiltersTestCase): ' True', 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 500, - 'free_capacity_gb': 100, - 'provisioned_capacity_gb': 400, - 'max_over_subscription_ratio': 2.0, - 'reserved_percentage': 0, - 'thin_provisioning_support': True, - 'thick_provisioning_support': True, - 'updated_at': None, - 'service': service}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 500, + 'free_capacity_gb': 100, + 'provisioned_capacity_gb': 400, + 'max_over_subscription_ratio': 2.0, + 'reserved_percentage': 0, + 'thin_provisioning_support': True, + 'thick_provisioning_support': True, + 'updated_at': None, + 'service': service}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) @ddt.data( {'volume_type': {'extra_specs': {'provisioning:type': 'thick'}}}, @@ -554,30 +555,30 @@ class CapacityFilterTestCase(HostFiltersTestCase): 'volume_type': volume_type, 'request_spec': {'volume_id': fake.VOLUME_ID}} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'total_capacity_gb': 500, - 'free_capacity_gb': 100, - 'provisioned_capacity_gb': 400, - 'max_over_subscription_ratio': 2.0, - 'reserved_percentage': 0, - 'thin_provisioning_support': True, - 'thick_provisioning_support': True, - 'updated_at': None, - 'service': service}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'total_capacity_gb': 500, + 'free_capacity_gb': 100, + 'provisioned_capacity_gb': 400, + 'max_over_subscription_ratio': 2.0, + 'reserved_percentage': 0, + 'thin_provisioning_support': True, + 'thick_provisioning_support': True, + 'updated_at': None, + 'service': service}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) -class AffinityFilterTestCase(HostFiltersTestCase): +class AffinityFilterTestCase(BackendFiltersTestCase): @mock.patch('cinder.objects.service.Service.is_up', new_callable=mock.PropertyMock) def test_different_filter_passes(self, _mock_serv_is_up): _mock_serv_is_up.return_value = True filt_cls = self.class_map['DifferentBackendFilter']() service = {'disabled': False} - host = fakes.FakeHostState('host1:pool0', - {'free_capacity_gb': '1000', - 'updated_at': None, - 'service': service}) + host = fakes.FakeBackendState('host1:pool0', + {'free_capacity_gb': '1000', + 'updated_at': None, + 'service': service}) volume = utils.create_volume(self.context, host='host1:pool1') vol_id = volume.id @@ -585,7 +586,7 @@ class AffinityFilterTestCase(HostFiltersTestCase): 'scheduler_hints': {'different_host': [vol_id], }, 'request_spec': {'volume_id': fake.VOLUME_ID}} - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) @mock.patch('cinder.objects.service.Service.is_up', new_callable=mock.PropertyMock) @@ -594,10 +595,10 @@ class AffinityFilterTestCase(HostFiltersTestCase): _mock_serv_is_up.return_value = True filt_cls = self.class_map['DifferentBackendFilter']() service = {'disabled': False} - host = fakes.FakeHostState('host1:pool0', - {'free_capacity_gb': '1000', - 'updated_at': None, - 'service': service}) + host = fakes.FakeBackendState('host1:pool0', + {'free_capacity_gb': '1000', + 'updated_at': None, + 'service': service}) volume = utils.create_volume(self.context, host='host1') vol_id = volume.id @@ -605,11 +606,11 @@ class AffinityFilterTestCase(HostFiltersTestCase): 'scheduler_hints': {'different_host': [vol_id], }, 'request_spec': {'volume_id': fake.VOLUME_ID}} - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_different_filter_non_list_fails(self): filt_cls = self.class_map['DifferentBackendFilter']() - host = fakes.FakeHostState('host2', {}) + host = fakes.FakeBackendState('host2', {}) volume = utils.create_volume(self.context, host='host2') vol_id = volume.id @@ -617,11 +618,11 @@ class AffinityFilterTestCase(HostFiltersTestCase): 'scheduler_hints': { 'different_host': vol_id}} - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_different_filter_fails(self): filt_cls = self.class_map['DifferentBackendFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) volume = utils.create_volume(self.context, host='host1') vol_id = volume.id @@ -629,21 +630,21 @@ class AffinityFilterTestCase(HostFiltersTestCase): 'scheduler_hints': {'different_host': [vol_id], }, 'request_spec': {'volume_id': fake.VOLUME_ID}} - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_different_filter_handles_none(self): filt_cls = self.class_map['DifferentBackendFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) filter_properties = {'context': self.context.elevated(), 'scheduler_hints': None, 'request_spec': {'volume_id': fake.VOLUME_ID}} - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_different_filter_handles_deleted_instance(self): filt_cls = self.class_map['DifferentBackendFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) volume = utils.create_volume(self.context, host='host1') vol_id = volume.id db.volume_destroy(utils.get_test_admin_context(), vol_id) @@ -652,21 +653,21 @@ class AffinityFilterTestCase(HostFiltersTestCase): 'scheduler_hints': { 'different_host': [vol_id], }} - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_different_filter_fail_nonuuid_hint(self): filt_cls = self.class_map['DifferentBackendFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) filter_properties = {'context': self.context.elevated(), 'scheduler_hints': { 'different_host': "NOT-a-valid-UUID", }} - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_different_filter_handles_multiple_uuids(self): filt_cls = self.class_map['DifferentBackendFilter']() - host = fakes.FakeHostState('host1#pool0', {}) + host = fakes.FakeBackendState('host1#pool0', {}) volume1 = utils.create_volume(self.context, host='host1:pool1') vol_id1 = volume1.id volume2 = utils.create_volume(self.context, host='host1:pool3') @@ -676,11 +677,11 @@ class AffinityFilterTestCase(HostFiltersTestCase): 'scheduler_hints': { 'different_host': [vol_id1, vol_id2], }} - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_different_filter_handles_invalid_uuids(self): filt_cls = self.class_map['DifferentBackendFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) volume = utils.create_volume(self.context, host='host2') vol_id = volume.id @@ -688,11 +689,11 @@ class AffinityFilterTestCase(HostFiltersTestCase): 'scheduler_hints': { 'different_host': [vol_id, "NOT-a-valid-UUID"], }} - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_same_filter_no_list_passes(self): filt_cls = self.class_map['SameBackendFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) volume = utils.create_volume(self.context, host='host1') vol_id = volume.id @@ -700,11 +701,11 @@ class AffinityFilterTestCase(HostFiltersTestCase): 'scheduler_hints': { 'same_host': vol_id}} - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_same_filter_passes(self): filt_cls = self.class_map['SameBackendFilter']() - host = fakes.FakeHostState('host1#pool0', {}) + host = fakes.FakeBackendState('host1#pool0', {}) volume = utils.create_volume(self.context, host='host1#pool0') vol_id = volume.id @@ -712,11 +713,11 @@ class AffinityFilterTestCase(HostFiltersTestCase): 'scheduler_hints': { 'same_host': [vol_id], }} - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_same_filter_legacy_vol_fails(self): filt_cls = self.class_map['SameBackendFilter']() - host = fakes.FakeHostState('host1#pool0', {}) + host = fakes.FakeBackendState('host1#pool0', {}) volume = utils.create_volume(self.context, host='host1') vol_id = volume.id @@ -724,11 +725,11 @@ class AffinityFilterTestCase(HostFiltersTestCase): 'scheduler_hints': { 'same_host': [vol_id], }} - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_same_filter_fails(self): filt_cls = self.class_map['SameBackendFilter']() - host = fakes.FakeHostState('host1#pool0', {}) + host = fakes.FakeBackendState('host1#pool0', {}) volume = utils.create_volume(self.context, host='host1#pool1') vol_id = volume.id @@ -736,11 +737,11 @@ class AffinityFilterTestCase(HostFiltersTestCase): 'scheduler_hints': { 'same_host': [vol_id], }} - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_same_filter_vol_list_pass(self): filt_cls = self.class_map['SameBackendFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) volume1 = utils.create_volume(self.context, host='host1') vol_id1 = volume1.id volume2 = utils.create_volume(self.context, host='host2') @@ -750,20 +751,20 @@ class AffinityFilterTestCase(HostFiltersTestCase): 'scheduler_hints': { 'same_host': [vol_id1, vol_id2], }} - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_same_filter_handles_none(self): filt_cls = self.class_map['SameBackendFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) filter_properties = {'context': self.context.elevated(), 'scheduler_hints': None} - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_same_filter_handles_deleted_instance(self): filt_cls = self.class_map['SameBackendFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) volume = utils.create_volume(self.context, host='host2') vol_id = volume.id db.volume_destroy(utils.get_test_admin_context(), vol_id) @@ -772,23 +773,23 @@ class AffinityFilterTestCase(HostFiltersTestCase): 'scheduler_hints': { 'same_host': [vol_id], }} - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_same_filter_fail_nonuuid_hint(self): filt_cls = self.class_map['SameBackendFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) filter_properties = {'context': self.context.elevated(), 'scheduler_hints': { 'same_host': "NOT-a-valid-UUID", }} - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) -class DriverFilterTestCase(HostFiltersTestCase): +class DriverFilterTestCase(BackendFiltersTestCase): def test_passing_function(self): filt_cls = self.class_map['DriverFilter']() - host1 = fakes.FakeHostState( + host1 = fakes.FakeBackendState( 'host1', { 'capabilities': { 'filter_function': '1 == 1', @@ -797,11 +798,11 @@ class DriverFilterTestCase(HostFiltersTestCase): filter_properties = {'volume_type': {}} - self.assertTrue(filt_cls.host_passes(host1, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host1, filter_properties)) def test_failing_function(self): filt_cls = self.class_map['DriverFilter']() - host1 = fakes.FakeHostState( + host1 = fakes.FakeBackendState( 'host1', { 'capabilities': { 'filter_function': '1 == 2', @@ -810,11 +811,11 @@ class DriverFilterTestCase(HostFiltersTestCase): filter_properties = {'volume_type': {}} - self.assertFalse(filt_cls.host_passes(host1, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host1, filter_properties)) def test_no_filter_function(self): filt_cls = self.class_map['DriverFilter']() - host1 = fakes.FakeHostState( + host1 = fakes.FakeBackendState( 'host1', { 'capabilities': { 'filter_function': None, @@ -823,22 +824,22 @@ class DriverFilterTestCase(HostFiltersTestCase): filter_properties = {'volume_type': {}} - self.assertTrue(filt_cls.host_passes(host1, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host1, filter_properties)) def test_not_implemented(self): filt_cls = self.class_map['DriverFilter']() - host1 = fakes.FakeHostState( + host1 = fakes.FakeBackendState( 'host1', { 'capabilities': {} }) filter_properties = {'volume_type': {}} - self.assertTrue(filt_cls.host_passes(host1, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host1, filter_properties)) def test_no_volume_extra_specs(self): filt_cls = self.class_map['DriverFilter']() - host1 = fakes.FakeHostState( + host1 = fakes.FakeBackendState( 'host1', { 'capabilities': { 'filter_function': '1 == 1', @@ -847,11 +848,11 @@ class DriverFilterTestCase(HostFiltersTestCase): filter_properties = {'volume_type': {}} - self.assertTrue(filt_cls.host_passes(host1, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host1, filter_properties)) def test_function_extra_spec_replacement(self): filt_cls = self.class_map['DriverFilter']() - host1 = fakes.FakeHostState( + host1 = fakes.FakeBackendState( 'host1', { 'capabilities': { 'filter_function': 'extra.var == 1', @@ -866,11 +867,11 @@ class DriverFilterTestCase(HostFiltersTestCase): } } - self.assertTrue(filt_cls.host_passes(host1, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host1, filter_properties)) def test_function_stats_replacement(self): filt_cls = self.class_map['DriverFilter']() - host1 = fakes.FakeHostState( + host1 = fakes.FakeBackendState( 'host1', { 'total_capacity_gb': 100, 'capabilities': { @@ -880,11 +881,11 @@ class DriverFilterTestCase(HostFiltersTestCase): filter_properties = {'volume_type': {}} - self.assertTrue(filt_cls.host_passes(host1, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host1, filter_properties)) def test_function_volume_replacement(self): filt_cls = self.class_map['DriverFilter']() - host1 = fakes.FakeHostState( + host1 = fakes.FakeBackendState( 'host1', { 'capabilities': { 'filter_function': 'volume.size < 5', @@ -899,11 +900,11 @@ class DriverFilterTestCase(HostFiltersTestCase): } } - self.assertTrue(filt_cls.host_passes(host1, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host1, filter_properties)) def test_function_qos_spec_replacement(self): filt_cls = self.class_map['DriverFilter']() - host1 = fakes.FakeHostState( + host1 = fakes.FakeBackendState( 'host1', { 'capabilities': { 'filter_function': 'qos.var == 1', @@ -916,11 +917,11 @@ class DriverFilterTestCase(HostFiltersTestCase): } } - self.assertTrue(filt_cls.host_passes(host1, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host1, filter_properties)) def test_function_exception_caught(self): filt_cls = self.class_map['DriverFilter']() - host1 = fakes.FakeHostState( + host1 = fakes.FakeBackendState( 'host1', { 'capabilities': { 'filter_function': '1 / 0 == 0', @@ -929,11 +930,11 @@ class DriverFilterTestCase(HostFiltersTestCase): filter_properties = {} - self.assertFalse(filt_cls.host_passes(host1, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host1, filter_properties)) def test_function_empty_qos(self): filt_cls = self.class_map['DriverFilter']() - host1 = fakes.FakeHostState( + host1 = fakes.FakeBackendState( 'host1', { 'capabilities': { 'filter_function': 'qos.maxiops == 1', @@ -944,11 +945,11 @@ class DriverFilterTestCase(HostFiltersTestCase): 'qos_specs': None } - self.assertFalse(filt_cls.host_passes(host1, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host1, filter_properties)) def test_capabilities(self): filt_cls = self.class_map['DriverFilter']() - host1 = fakes.FakeHostState( + host1 = fakes.FakeBackendState( 'host1', { 'capabilities': { 'foo': 10, @@ -958,11 +959,11 @@ class DriverFilterTestCase(HostFiltersTestCase): filter_properties = {} - self.assertTrue(filt_cls.host_passes(host1, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host1, filter_properties)) def test_wrong_capabilities(self): filt_cls = self.class_map['DriverFilter']() - host1 = fakes.FakeHostState( + host1 = fakes.FakeBackendState( 'host1', { 'capabilities': { 'bar': 10, @@ -972,10 +973,10 @@ class DriverFilterTestCase(HostFiltersTestCase): filter_properties = {} - self.assertFalse(filt_cls.host_passes(host1, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host1, filter_properties)) -class InstanceLocalityFilterTestCase(HostFiltersTestCase): +class InstanceLocalityFilterTestCase(BackendFiltersTestCase): def setUp(self): super(InstanceLocalityFilterTestCase, self).setUp() self.override_config('nova_endpoint_template', @@ -993,13 +994,13 @@ class InstanceLocalityFilterTestCase(HostFiltersTestCase): fake_extensions.return_value = ( fakes.FakeNovaClient().list_extensions.show_all()) filt_cls = self.class_map['InstanceLocalityFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) uuid = nova.novaclient().servers.create('host1') filter_properties = {'context': self.context, 'scheduler_hints': {'local_to_instance': uuid}, 'request_spec': {'volume_id': fake.VOLUME_ID}} - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) @mock.patch('novaclient.client.discover_extensions') @mock.patch('cinder.compute.nova.novaclient') @@ -1008,47 +1009,47 @@ class InstanceLocalityFilterTestCase(HostFiltersTestCase): fake_extensions.return_value = ( fakes.FakeNovaClient().list_extensions.show_all()) filt_cls = self.class_map['InstanceLocalityFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) uuid = nova.novaclient().servers.create('host2') filter_properties = {'context': self.context, 'scheduler_hints': {'local_to_instance': uuid}, 'request_spec': {'volume_id': fake.VOLUME_ID}} - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_handles_none(self): filt_cls = self.class_map['InstanceLocalityFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) filter_properties = {'context': self.context, 'scheduler_hints': None, 'request_spec': {'volume_id': fake.VOLUME_ID}} - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_invalid_uuid(self): filt_cls = self.class_map['InstanceLocalityFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) filter_properties = {'context': self.context, 'scheduler_hints': {'local_to_instance': 'e29b11d4-not-valid-a716'}, 'request_spec': {'volume_id': fake.VOLUME_ID}} self.assertRaises(exception.InvalidUUID, - filt_cls.host_passes, host, filter_properties) + filt_cls.backend_passes, host, filter_properties) @mock.patch('cinder.compute.nova.novaclient') def test_nova_no_extended_server_attributes(self, _mock_novaclient): _mock_novaclient.return_value = fakes.FakeNovaClient( ext_srv_attr=False) filt_cls = self.class_map['InstanceLocalityFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) uuid = nova.novaclient().servers.create('host1') filter_properties = {'context': self.context, 'scheduler_hints': {'local_to_instance': uuid}, 'request_spec': {'volume_id': fake.VOLUME_ID}} self.assertRaises(exception.CinderException, - filt_cls.host_passes, host, filter_properties) + filt_cls.backend_passes, host, filter_properties) @mock.patch('cinder.compute.nova.novaclient') def test_nova_down_does_not_alter_other_filters(self, _mock_novaclient): @@ -1056,11 +1057,11 @@ class InstanceLocalityFilterTestCase(HostFiltersTestCase): _mock_novaclient.side_effect = Exception filt_cls = self.class_map['InstanceLocalityFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) filter_properties = {'context': self.context, 'size': 100, 'request_spec': {'volume_id': fake.VOLUME_ID}} - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) @mock.patch('cinder.compute.nova.novaclient') def test_nova_timeout(self, mock_novaclient): @@ -1069,22 +1070,22 @@ class InstanceLocalityFilterTestCase(HostFiltersTestCase): mock_show_all.side_effect = request_exceptions.Timeout filt_cls = self.class_map['InstanceLocalityFilter']() - host = fakes.FakeHostState('host1', {}) + host = fakes.FakeBackendState('host1', {}) filter_properties = \ {'context': self.context, 'scheduler_hints': {'local_to_instance': 'e29b11d4-15ef-34a9-a716-598a6f0b5467'}, 'request_spec': {'volume_id': fake.VOLUME_ID}} self.assertRaises(exception.APITimeout, - filt_cls.host_passes, host, filter_properties) + filt_cls.backend_passes, host, filter_properties) -class TestFilter(filters.BaseHostFilter): +class TestFilter(filters.BaseBackendFilter): pass class TestBogusFilter(object): - """Class that doesn't inherit from BaseHostFilter.""" + """Class that doesn't inherit from BaseBackendFilter.""" pass @@ -1317,7 +1318,7 @@ class ExtraSpecsOpsTestCase(test.TestCase): @ddt.ddt -class BasicFiltersTestCase(HostFiltersTestCase): +class BasicFiltersTestCase(BackendFiltersTestCase): """Test case for host filters.""" def setUp(self): @@ -1341,12 +1342,12 @@ class BasicFiltersTestCase(HostFiltersTestCase): filter_properties = {'resource_type': {'name': 'fake_type', 'extra_specs': especs}, 'request_spec': {'volume_id': fake.VOLUME_ID}} - host = fakes.FakeHostState('host1', - {'free_capacity_gb': 1024, - 'capabilities': capabilities, - 'service': service}) + host = fakes.FakeBackendState('host1', + {'free_capacity_gb': 1024, + 'capabilities': capabilities, + 'service': service}) assertion = self.assertTrue if passes else self.assertFalse - assertion(filt_cls.host_passes(host, filter_properties)) + assertion(filt_cls.backend_passes(host, filter_properties)) def test_capability_filter_passes_extra_specs_simple(self): self._do_test_type_filter_extra_specs( @@ -1500,11 +1501,11 @@ class BasicFiltersTestCase(HostFiltersTestCase): 'scheduler_hints': {'query': self.json_query}, 'request_spec': {'volume_id': fake.VOLUME_ID}} capabilities = {'enabled': True} - host = fakes.FakeHostState('host1', - {'free_ram_mb': 1024, - 'free_disk_mb': 200 * 1024, - 'capabilities': capabilities}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_ram_mb': 1024, + 'free_disk_mb': 200 * 1024, + 'capabilities': capabilities}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_json_filter_passes_with_no_query(self): filt_cls = self.class_map['JsonFilter']() @@ -1513,11 +1514,11 @@ class BasicFiltersTestCase(HostFiltersTestCase): 'ephemeral_gb': 0}, 'request_spec': {'volume_id': fake.VOLUME_ID}} capabilities = {'enabled': True} - host = fakes.FakeHostState('host1', - {'free_ram_mb': 0, - 'free_disk_mb': 0, - 'capabilities': capabilities}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_ram_mb': 0, + 'free_disk_mb': 0, + 'capabilities': capabilities}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_json_filter_fails_on_memory(self): filt_cls = self.class_map['JsonFilter']() @@ -1527,11 +1528,11 @@ class BasicFiltersTestCase(HostFiltersTestCase): 'scheduler_hints': {'query': self.json_query}, 'request_spec': {'volume_id': fake.VOLUME_ID}} capabilities = {'enabled': True} - host = fakes.FakeHostState('host1', - {'free_ram_mb': 1023, - 'free_disk_mb': 200 * 1024, - 'capabilities': capabilities}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_ram_mb': 1023, + 'free_disk_mb': 200 * 1024, + 'capabilities': capabilities}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_json_filter_fails_on_disk(self): filt_cls = self.class_map['JsonFilter']() @@ -1541,11 +1542,11 @@ class BasicFiltersTestCase(HostFiltersTestCase): 'scheduler_hints': {'query': self.json_query}, 'request_spec': {'volume_id': fake.VOLUME_ID}} capabilities = {'enabled': True} - host = fakes.FakeHostState('host1', - {'free_ram_mb': 1024, - 'free_disk_mb': (200 * 1024) - 1, - 'capabilities': capabilities}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_ram_mb': 1024, + 'free_disk_mb': (200 * 1024) - 1, + 'capabilities': capabilities}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_json_filter_fails_on_caps_disabled(self): filt_cls = self.class_map['JsonFilter']() @@ -1559,11 +1560,11 @@ class BasicFiltersTestCase(HostFiltersTestCase): 'scheduler_hints': {'query': json_query}, 'request_spec': {'volume_id': fake.VOLUME_ID}} capabilities = {'enabled': False} - host = fakes.FakeHostState('host1', - {'free_ram_mb': 1024, - 'free_disk_mb': 200 * 1024, - 'capabilities': capabilities}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_ram_mb': 1024, + 'free_disk_mb': 200 * 1024, + 'capabilities': capabilities}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_json_filter_fails_on_service_disabled(self): filt_cls = self.class_map['JsonFilter']() @@ -1576,11 +1577,11 @@ class BasicFiltersTestCase(HostFiltersTestCase): 'scheduler_hints': {'query': json_query}, 'request_spec': {'volume_id': fake.VOLUME_ID}} capabilities = {'enabled': True} - host = fakes.FakeHostState('host1', - {'free_ram_mb': 1024, - 'free_disk_mb': 200 * 1024, - 'capabilities': capabilities}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_ram_mb': 1024, + 'free_disk_mb': 200 * 1024, + 'capabilities': capabilities}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_json_filter_happy_day(self): """Test json filter more thoroughly.""" @@ -1605,67 +1606,67 @@ class BasicFiltersTestCase(HostFiltersTestCase): # Passes capabilities = {'enabled': True, 'opt1': 'match'} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'free_ram_mb': 10, - 'free_disk_mb': 200, - 'capabilities': capabilities, - 'service': service}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_ram_mb': 10, + 'free_disk_mb': 200, + 'capabilities': capabilities, + 'service': service}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) # Passes capabilities = {'enabled': True, 'opt1': 'match'} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'free_ram_mb': 40, - 'free_disk_mb': 400, - 'capabilities': capabilities, - 'service': service}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_ram_mb': 40, + 'free_disk_mb': 400, + 'capabilities': capabilities, + 'service': service}) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) # Fails due to capabilities being disabled capabilities = {'enabled': False, 'opt1': 'match'} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'free_ram_mb': 40, - 'free_disk_mb': 400, - 'capabilities': capabilities, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_ram_mb': 40, + 'free_disk_mb': 400, + 'capabilities': capabilities, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) # Fails due to being exact memory/disk we don't want capabilities = {'enabled': True, 'opt1': 'match'} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'free_ram_mb': 30, - 'free_disk_mb': 300, - 'capabilities': capabilities, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_ram_mb': 30, + 'free_disk_mb': 300, + 'capabilities': capabilities, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) # Fails due to memory lower but disk higher capabilities = {'enabled': True, 'opt1': 'match'} service = {'disabled': False} - host = fakes.FakeHostState('host1', - {'free_ram_mb': 20, - 'free_disk_mb': 400, - 'capabilities': capabilities, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_ram_mb': 20, + 'free_disk_mb': 400, + 'capabilities': capabilities, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) # Fails due to capabilities 'opt1' not equal capabilities = {'enabled': True, 'opt1': 'no-match'} service = {'enabled': True} - host = fakes.FakeHostState('host1', - {'free_ram_mb': 20, - 'free_disk_mb': 400, - 'capabilities': capabilities, - 'service': service}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + host = fakes.FakeBackendState('host1', + {'free_ram_mb': 20, + 'free_disk_mb': 400, + 'capabilities': capabilities, + 'service': service}) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_json_filter_basic_operators(self): filt_cls = self.class_map['JsonFilter']() - host = fakes.FakeHostState('host1', - {'capabilities': {'enabled': True}}) + host = fakes.FakeBackendState('host1', + {'capabilities': {'enabled': True}}) # (operator, arguments, expected_result) ops_to_test = [ ['=', [1, 1], True], @@ -1704,7 +1705,7 @@ class BasicFiltersTestCase(HostFiltersTestCase): 'request_spec': {'volume_id': fake.VOLUME_ID} } self.assertEqual(expected, - filt_cls.host_passes(host, filter_properties)) + filt_cls.backend_passes(host, filter_properties)) # This results in [False, True, False, True] and if any are True # then it passes... @@ -1714,7 +1715,7 @@ class BasicFiltersTestCase(HostFiltersTestCase): 'query': jsonutils.dumps(raw), }, } - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) # This results in [False, False, False] and if any are True # then it passes...which this doesn't @@ -1724,7 +1725,7 @@ class BasicFiltersTestCase(HostFiltersTestCase): 'query': jsonutils.dumps(raw), }, } - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_json_filter_unknown_operator_raises(self): filt_cls = self.class_map['JsonFilter']() @@ -1734,15 +1735,15 @@ class BasicFiltersTestCase(HostFiltersTestCase): 'query': jsonutils.dumps(raw), }, } - host = fakes.FakeHostState('host1', - {'capabilities': {'enabled': True}}) + host = fakes.FakeBackendState('host1', + {'capabilities': {'enabled': True}}) self.assertRaises(KeyError, - filt_cls.host_passes, host, filter_properties) + filt_cls.backend_passes, host, filter_properties) def test_json_filter_empty_filters_pass(self): filt_cls = self.class_map['JsonFilter']() - host = fakes.FakeHostState('host1', - {'capabilities': {'enabled': True}}) + host = fakes.FakeBackendState('host1', + {'capabilities': {'enabled': True}}) raw = [] filter_properties = { @@ -1750,19 +1751,19 @@ class BasicFiltersTestCase(HostFiltersTestCase): 'query': jsonutils.dumps(raw), }, } - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) raw = {} filter_properties = { 'scheduler_hints': { 'query': jsonutils.dumps(raw), }, } - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) def test_json_filter_invalid_num_arguments_fails(self): filt_cls = self.class_map['JsonFilter']() - host = fakes.FakeHostState('host1', - {'capabilities': {'enabled': True}}) + host = fakes.FakeBackendState('host1', + {'capabilities': {'enabled': True}}) raw = ['>', ['and', ['or', ['not', ['<', ['>=', ['<=', ['in', ]]]]]]]] filter_properties = { @@ -1770,7 +1771,7 @@ class BasicFiltersTestCase(HostFiltersTestCase): 'query': jsonutils.dumps(raw), }, } - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) raw = ['>', 1] filter_properties = { @@ -1778,12 +1779,12 @@ class BasicFiltersTestCase(HostFiltersTestCase): 'query': jsonutils.dumps(raw), }, } - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) def test_json_filter_unknown_variable_ignored(self): filt_cls = self.class_map['JsonFilter']() - host = fakes.FakeHostState('host1', - {'capabilities': {'enabled': True}}) + host = fakes.FakeBackendState('host1', + {'capabilities': {'enabled': True}}) raw = ['=', '$........', 1, 1] filter_properties = { @@ -1791,7 +1792,7 @@ class BasicFiltersTestCase(HostFiltersTestCase): 'query': jsonutils.dumps(raw), }, } - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) raw = ['=', '$foo', 2, 2] filter_properties = { @@ -1799,7 +1800,7 @@ class BasicFiltersTestCase(HostFiltersTestCase): 'query': jsonutils.dumps(raw), }, } - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_passes(host, filter_properties)) @staticmethod def _make_zone_request(zone, is_admin=False): @@ -1817,45 +1818,42 @@ class BasicFiltersTestCase(HostFiltersTestCase): filt_cls = self.class_map['AvailabilityZoneFilter']() service = {'availability_zone': 'nova'} request = self._make_zone_request('nova') - host = fakes.FakeHostState('host1', - {'service': service}) - self.assertTrue(filt_cls.host_passes(host, request)) + host = fakes.FakeBackendState('host1', {'service': service}) + self.assertTrue(filt_cls.backend_passes(host, request)) def test_availability_zone_filter_different(self): filt_cls = self.class_map['AvailabilityZoneFilter']() service = {'availability_zone': 'nova'} request = self._make_zone_request('bad') - host = fakes.FakeHostState('host1', - {'service': service}) - self.assertFalse(filt_cls.host_passes(host, request)) + host = fakes.FakeBackendState('host1', {'service': service}) + self.assertFalse(filt_cls.backend_passes(host, request)) def test_availability_zone_filter_empty(self): filt_cls = self.class_map['AvailabilityZoneFilter']() service = {'availability_zone': 'nova'} request = {} - host = fakes.FakeHostState('host1', - {'service': service}) - self.assertTrue(filt_cls.host_passes(host, request)) + host = fakes.FakeBackendState('host1', {'service': service}) + self.assertTrue(filt_cls.backend_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', {}) + host = fakes.FakeBackendState('host1', {}) filter_properties = {} - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_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', {}) + host = fakes.FakeBackendState('host1', {}) attempted = dict(num_attempts=2, hosts=['host2']) filter_properties = dict(retry=attempted) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(filt_cls.backend_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']) + host = fakes.FakeBackendState('host1', {}) + attempted = dict(num_attempts=2, backends=['host1']) filter_properties = dict(retry=attempted) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + self.assertFalse(filt_cls.backend_passes(host, filter_properties)) diff --git a/cinder/tests/unit/scheduler/test_host_manager.py b/cinder/tests/unit/scheduler/test_host_manager.py index 1dc509a29a8..cae1f4ae498 100644 --- a/cinder/tests/unit/scheduler/test_host_manager.py +++ b/cinder/tests/unit/scheduler/test_host_manager.py @@ -34,13 +34,13 @@ from cinder.tests.unit import fake_constants as fake from cinder.tests.unit.objects import test_service -class FakeFilterClass1(filters.BaseHostFilter): - def host_passes(self, host_state, filter_properties): +class FakeFilterClass1(filters.BaseBackendFilter): + def backend_passes(self, host_state, filter_properties): pass -class FakeFilterClass2(filters.BaseHostFilter): - def host_passes(self, host_state, filter_properties): +class FakeFilterClass2(filters.BaseBackendFilter): + def backend_passes(self, host_state, filter_properties): pass @@ -50,46 +50,46 @@ class HostManagerTestCase(test.TestCase): def setUp(self): super(HostManagerTestCase, self).setUp() self.host_manager = host_manager.HostManager() - self.fake_hosts = [host_manager.HostState('fake_host%s' % x, None) - for x in range(1, 5)] + self.fake_backends = [host_manager.BackendState('fake_be%s' % x, None) + for x in range(1, 5)] # For a second scheduler service. self.host_manager_1 = host_manager.HostManager() - def test_choose_host_filters_not_found(self): + def test_choose_backend_filters_not_found(self): self.flags(scheduler_default_filters='FakeFilterClass3') self.host_manager.filter_classes = [FakeFilterClass1, FakeFilterClass2] self.assertRaises(exception.SchedulerHostFilterNotFound, - self.host_manager._choose_host_filters, None) + self.host_manager._choose_backend_filters, None) - def test_choose_host_filters(self): + def test_choose_backend_filters(self): self.flags(scheduler_default_filters=['FakeFilterClass2']) self.host_manager.filter_classes = [FakeFilterClass1, FakeFilterClass2] # Test 'volume' returns 1 correct function - filter_classes = self.host_manager._choose_host_filters(None) + filter_classes = self.host_manager._choose_backend_filters(None) self.assertEqual(1, len(filter_classes)) self.assertEqual('FakeFilterClass2', filter_classes[0].__name__) @mock.patch('cinder.scheduler.host_manager.HostManager.' - '_choose_host_filters') - def test_get_filtered_hosts(self, _mock_choose_host_filters): + '_choose_backend_filters') + def test_get_filtered_backends(self, _mock_choose_backend_filters): filter_class = FakeFilterClass1 mock_func = mock.Mock() mock_func.return_value = True filter_class._filter_one = mock_func - _mock_choose_host_filters.return_value = [filter_class] + _mock_choose_backend_filters.return_value = [filter_class] fake_properties = {'moo': 1, 'cow': 2} expected = [] - for fake_host in self.fake_hosts: - expected.append(mock.call(fake_host, fake_properties)) + for fake_backend in self.fake_backends: + expected.append(mock.call(fake_backend, fake_properties)) - result = self.host_manager.get_filtered_hosts(self.fake_hosts, - fake_properties) + result = self.host_manager.get_filtered_backends(self.fake_backends, + fake_properties) self.assertEqual(expected, mock_func.call_args_list) - self.assertEqual(set(self.fake_hosts), set(result)) + self.assertEqual(set(self.fake_backends), set(result)) @mock.patch('cinder.scheduler.host_manager.HostManager._get_updated_pools') @mock.patch('oslo_utils.timeutils.utcnow') @@ -563,6 +563,10 @@ class HostManagerTestCase(test.TestCase): self.assertEqual(1, len(res)) self.assertEqual(dates[1], res[0]['capabilities']['timestamp']) + # Now we simulate old service that doesn't send timestamp + del mocked_service_states['host1']['timestamp'] + with mock.patch.dict(self.host_manager.service_states, + mocked_service_states): self.host_manager.update_service_capabilities(service_name, 'host1', host_volume_capabs, @@ -572,8 +576,8 @@ class HostManagerTestCase(test.TestCase): self.assertEqual(dates[2], res[0]['capabilities']['timestamp']) @mock.patch('cinder.objects.Service.is_up', True) - def test_get_all_host_states_cluster(self): - """Test get_all_host_states when we have clustered services. + def test_get_all_backend_states_cluster(self): + """Test get_all_backend_states when we have clustered services. Confirm that clustered services are grouped and that only the latest of the capability reports is relevant. @@ -631,7 +635,7 @@ class HostManagerTestCase(test.TestCase): 'volume', services[i].host, capabilities[i][1], services[i].cluster_name, capabilities[i][0]) - res = self.host_manager.get_all_host_states(ctxt) + res = self.host_manager.get_all_backend_states(ctxt) result = {(s.cluster_name or s.host, s.free_capacity_gb) for s in res} expected = {(cluster_name + '#_pool0', 2000), ('non_clustered_host#_pool0', 4000)} @@ -640,8 +644,8 @@ class HostManagerTestCase(test.TestCase): @mock.patch('cinder.db.service_get_all') @mock.patch('cinder.objects.service.Service.is_up', new_callable=mock.PropertyMock) - def test_get_all_host_states(self, _mock_service_is_up, - _mock_service_get_all): + def test_get_all_backend_states(self, _mock_service_is_up, + _mock_service_get_all): context = 'fake_context' timestamp = datetime.utcnow() topic = constants.VOLUME_TOPIC @@ -695,7 +699,7 @@ class HostManagerTestCase(test.TestCase): host_manager.LOG.warning = _mock_warning # Get all states - self.host_manager.get_all_host_states(context) + self.host_manager.get_all_backend_states(context) _mock_service_get_all.assert_called_with(context, disabled=False, topic=topic) @@ -704,14 +708,14 @@ class HostManagerTestCase(test.TestCase): expected = [mock.call() for s in service_objs] self.assertEqual(expected, _mock_service_is_up.call_args_list) - # Get host_state_map and make sure we have the first 3 hosts - host_state_map = self.host_manager.host_state_map - self.assertEqual(3, len(host_state_map)) + # Get backend_state_map and make sure we have the first 3 hosts + backend_state_map = self.host_manager.backend_state_map + self.assertEqual(3, len(backend_state_map)) for i in range(3): volume_node = services[i] host = volume_node['host'] test_service.TestService._compare(self, volume_node, - host_state_map[host].service) + backend_state_map[host].service) # Second test: Now service.is_up returns False for host3 _mock_service_is_up.reset_mock() @@ -720,7 +724,7 @@ class HostManagerTestCase(test.TestCase): _mock_warning.reset_mock() # Get all states, make sure host 3 is reported as down - self.host_manager.get_all_host_states(context) + self.host_manager.get_all_backend_states(context) _mock_service_get_all.assert_called_with(context, disabled=False, topic=topic) @@ -728,15 +732,15 @@ class HostManagerTestCase(test.TestCase): self.assertEqual(expected, _mock_service_is_up.call_args_list) self.assertGreater(_mock_warning.call_count, 0) - # Get host_state_map and make sure we have the first 2 hosts (host3 is - # down, host4 is missing capabilities) - host_state_map = self.host_manager.host_state_map - self.assertEqual(2, len(host_state_map)) + # Get backend_state_map and make sure we have the first 2 hosts (host3 + # is down, host4 is missing capabilities) + backend_state_map = self.host_manager.backend_state_map + self.assertEqual(2, len(backend_state_map)) for i in range(2): volume_node = services[i] host = volume_node['host'] test_service.TestService._compare(self, volume_node, - host_state_map[host].service) + backend_state_map[host].service) @mock.patch('cinder.db.service_get_all') @mock.patch('cinder.objects.service.Service.is_up', @@ -963,12 +967,12 @@ class HostManagerTestCase(test.TestCase): sorted(res2, key=sort_func)) -class HostStateTestCase(test.TestCase): - """Test case for HostState class.""" +class BackendStateTestCase(test.TestCase): + """Test case for BackendState class.""" def test_update_from_volume_capability_nopool(self): - fake_host = host_manager.HostState('host1', None) - self.assertIsNone(fake_host.free_capacity_gb) + fake_backend = host_manager.BackendState('be1', None) + self.assertIsNone(fake_backend.free_capacity_gb) volume_capability = {'total_capacity_gb': 1024, 'free_capacity_gb': 512, @@ -976,34 +980,34 @@ class HostStateTestCase(test.TestCase): 'reserved_percentage': 0, 'timestamp': None} - fake_host.update_from_volume_capability(volume_capability) + fake_backend.update_from_volume_capability(volume_capability) # Backend level stats remain uninitialized - self.assertEqual(0, fake_host.total_capacity_gb) - self.assertIsNone(fake_host.free_capacity_gb) + self.assertEqual(0, fake_backend.total_capacity_gb) + self.assertIsNone(fake_backend.free_capacity_gb) # Pool stats has been updated - self.assertEqual(1024, fake_host.pools['_pool0'].total_capacity_gb) - self.assertEqual(512, fake_host.pools['_pool0'].free_capacity_gb) + self.assertEqual(1024, fake_backend.pools['_pool0'].total_capacity_gb) + self.assertEqual(512, fake_backend.pools['_pool0'].free_capacity_gb) self.assertEqual(512, - fake_host.pools['_pool0'].provisioned_capacity_gb) + fake_backend.pools['_pool0'].provisioned_capacity_gb) # Test update for existing host state volume_capability.update(dict(total_capacity_gb=1000)) - fake_host.update_from_volume_capability(volume_capability) - self.assertEqual(1000, fake_host.pools['_pool0'].total_capacity_gb) + fake_backend.update_from_volume_capability(volume_capability) + self.assertEqual(1000, fake_backend.pools['_pool0'].total_capacity_gb) # Test update for existing host state with different backend name volume_capability.update(dict(volume_backend_name='magic')) - fake_host.update_from_volume_capability(volume_capability) - self.assertEqual(1000, fake_host.pools['magic'].total_capacity_gb) - self.assertEqual(512, fake_host.pools['magic'].free_capacity_gb) + fake_backend.update_from_volume_capability(volume_capability) + self.assertEqual(1000, fake_backend.pools['magic'].total_capacity_gb) + self.assertEqual(512, fake_backend.pools['magic'].free_capacity_gb) self.assertEqual(512, - fake_host.pools['magic'].provisioned_capacity_gb) + fake_backend.pools['magic'].provisioned_capacity_gb) # 'pool0' becomes nonactive pool, and is deleted - self.assertRaises(KeyError, lambda: fake_host.pools['pool0']) + self.assertRaises(KeyError, lambda: fake_backend.pools['pool0']) def test_update_from_volume_capability_with_pools(self): - fake_host = host_manager.HostState('host1', None) - self.assertIsNone(fake_host.free_capacity_gb) + fake_backend = host_manager.BackendState('host1', None) + self.assertIsNone(fake_backend.free_capacity_gb) capability = { 'volume_backend_name': 'Local iSCSI', 'vendor_name': 'OpenStack', @@ -1037,27 +1041,28 @@ class HostStateTestCase(test.TestCase): 'timestamp': None, } - fake_host.update_from_volume_capability(capability) + fake_backend.update_from_volume_capability(capability) - self.assertEqual('Local iSCSI', fake_host.volume_backend_name) - self.assertEqual('iSCSI', fake_host.storage_protocol) - self.assertEqual('OpenStack', fake_host.vendor_name) - self.assertEqual('1.0.1', fake_host.driver_version) + self.assertEqual('Local iSCSI', fake_backend.volume_backend_name) + self.assertEqual('iSCSI', fake_backend.storage_protocol) + self.assertEqual('OpenStack', fake_backend.vendor_name) + self.assertEqual('1.0.1', fake_backend.driver_version) # Backend level stats remain uninitialized - self.assertEqual(0, fake_host.total_capacity_gb) - self.assertIsNone(fake_host.free_capacity_gb) + self.assertEqual(0, fake_backend.total_capacity_gb) + self.assertIsNone(fake_backend.free_capacity_gb) # Pool stats has been updated - self.assertEqual(2, len(fake_host.pools)) + self.assertEqual(2, len(fake_backend.pools)) - self.assertEqual(500, fake_host.pools['1st pool'].total_capacity_gb) - self.assertEqual(230, fake_host.pools['1st pool'].free_capacity_gb) - self.assertEqual(270, - fake_host.pools['1st pool'].provisioned_capacity_gb) - self.assertEqual(1024, fake_host.pools['2nd pool'].total_capacity_gb) - self.assertEqual(1024, fake_host.pools['2nd pool'].free_capacity_gb) - self.assertEqual(0, - fake_host.pools['2nd pool'].provisioned_capacity_gb) + self.assertEqual(500, fake_backend.pools['1st pool'].total_capacity_gb) + self.assertEqual(230, fake_backend.pools['1st pool'].free_capacity_gb) + self.assertEqual( + 270, fake_backend.pools['1st pool'].provisioned_capacity_gb) + self.assertEqual( + 1024, fake_backend.pools['2nd pool'].total_capacity_gb) + self.assertEqual(1024, fake_backend.pools['2nd pool'].free_capacity_gb) + self.assertEqual( + 0, fake_backend.pools['2nd pool'].provisioned_capacity_gb) capability = { 'volume_backend_name': 'Local iSCSI', @@ -1077,83 +1082,85 @@ class HostStateTestCase(test.TestCase): 'timestamp': None, } - # test update HostState Record - fake_host.update_from_volume_capability(capability) + # test update BackendState Record + fake_backend.update_from_volume_capability(capability) - self.assertEqual('1.0.2', fake_host.driver_version) + self.assertEqual('1.0.2', fake_backend.driver_version) # Non-active pool stats has been removed - self.assertEqual(1, len(fake_host.pools)) + self.assertEqual(1, len(fake_backend.pools)) - self.assertRaises(KeyError, lambda: fake_host.pools['1st pool']) - self.assertRaises(KeyError, lambda: fake_host.pools['2nd pool']) + self.assertRaises(KeyError, lambda: fake_backend.pools['1st pool']) + self.assertRaises(KeyError, lambda: fake_backend.pools['2nd pool']) - self.assertEqual(10000, fake_host.pools['3rd pool'].total_capacity_gb) - self.assertEqual(10000, fake_host.pools['3rd pool'].free_capacity_gb) - self.assertEqual(0, - fake_host.pools['3rd pool'].provisioned_capacity_gb) + self.assertEqual(10000, + fake_backend.pools['3rd pool'].total_capacity_gb) + self.assertEqual(10000, + fake_backend.pools['3rd pool'].free_capacity_gb) + self.assertEqual( + 0, fake_backend.pools['3rd pool'].provisioned_capacity_gb) def test_update_from_volume_infinite_capability(self): - fake_host = host_manager.HostState('host1', None) - self.assertIsNone(fake_host.free_capacity_gb) + fake_backend = host_manager.BackendState('host1', None) + self.assertIsNone(fake_backend.free_capacity_gb) volume_capability = {'total_capacity_gb': 'infinite', 'free_capacity_gb': 'infinite', 'reserved_percentage': 0, 'timestamp': None} - fake_host.update_from_volume_capability(volume_capability) + fake_backend.update_from_volume_capability(volume_capability) # Backend level stats remain uninitialized - self.assertEqual(0, fake_host.total_capacity_gb) - self.assertIsNone(fake_host.free_capacity_gb) + self.assertEqual(0, fake_backend.total_capacity_gb) + self.assertIsNone(fake_backend.free_capacity_gb) # Pool stats has been updated self.assertEqual( 'infinite', - fake_host.pools['_pool0'].total_capacity_gb) + fake_backend.pools['_pool0'].total_capacity_gb) self.assertEqual( 'infinite', - fake_host.pools['_pool0'].free_capacity_gb) + fake_backend.pools['_pool0'].free_capacity_gb) def test_update_from_volume_unknown_capability(self): - fake_host = host_manager.HostState('host1', None) - self.assertIsNone(fake_host.free_capacity_gb) + fake_backend = host_manager.BackendState('host1', None) + self.assertIsNone(fake_backend.free_capacity_gb) volume_capability = {'total_capacity_gb': 'infinite', 'free_capacity_gb': 'unknown', 'reserved_percentage': 0, 'timestamp': None} - fake_host.update_from_volume_capability(volume_capability) + fake_backend.update_from_volume_capability(volume_capability) # Backend level stats remain uninitialized - self.assertEqual(0, fake_host.total_capacity_gb) - self.assertIsNone(fake_host.free_capacity_gb) + self.assertEqual(0, fake_backend.total_capacity_gb) + self.assertIsNone(fake_backend.free_capacity_gb) # Pool stats has been updated self.assertEqual( 'infinite', - fake_host.pools['_pool0'].total_capacity_gb) + fake_backend.pools['_pool0'].total_capacity_gb) self.assertEqual( 'unknown', - fake_host.pools['_pool0'].free_capacity_gb) + fake_backend.pools['_pool0'].free_capacity_gb) def test_update_from_empty_volume_capability(self): - fake_host = host_manager.HostState('host1', None) + fake_backend = host_manager.BackendState('host1', None) vol_cap = {'timestamp': None} - fake_host.update_from_volume_capability(vol_cap) - self.assertEqual(0, fake_host.total_capacity_gb) - self.assertIsNone(fake_host.free_capacity_gb) + fake_backend.update_from_volume_capability(vol_cap) + self.assertEqual(0, fake_backend.total_capacity_gb) + self.assertIsNone(fake_backend.free_capacity_gb) # Pool stats has been updated self.assertEqual(0, - fake_host.pools['_pool0'].total_capacity_gb) + fake_backend.pools['_pool0'].total_capacity_gb) self.assertEqual(0, - fake_host.pools['_pool0'].free_capacity_gb) + fake_backend.pools['_pool0'].free_capacity_gb) self.assertEqual(0, - fake_host.pools['_pool0'].provisioned_capacity_gb) + fake_backend.pools['_pool0'].provisioned_capacity_gb) class PoolStateTestCase(test.TestCase): - """Test case for HostState class.""" + """Test case for BackendState class.""" def test_update_from_volume_capability(self): fake_pool = host_manager.PoolState('host1', None, None, 'pool0') diff --git a/cinder/tests/unit/scheduler/test_scheduler.py b/cinder/tests/unit/scheduler/test_scheduler.py index 9e4b6f8a1e1..12f86823995 100644 --- a/cinder/tests/unit/scheduler/test_scheduler.py +++ b/cinder/tests/unit/scheduler/test_scheduler.py @@ -126,9 +126,9 @@ class SchedulerManagerTestCase(test.TestCase): def test_create_volume_exception_puts_volume_in_error_state( self, _mock_volume_update, _mock_message_create, _mock_sched_create): - # Test NoValidHost exception behavior for create_volume. + # Test NoValidBackend exception behavior for create_volume. # Puts the volume in 'error' state and eats the exception. - _mock_sched_create.side_effect = exception.NoValidHost(reason="") + _mock_sched_create.side_effect = exception.NoValidBackend(reason="") volume = fake_volume.fake_volume_obj(self.context) request_spec = {'volume_id': volume.id, 'volume': {'id': volume.id, '_name_id': None, @@ -223,39 +223,39 @@ class SchedulerManagerTestCase(test.TestCase): self.assertFalse(_mock_sleep.called) @mock.patch('cinder.db.volume_get') - @mock.patch('cinder.scheduler.driver.Scheduler.host_passes_filters') + @mock.patch('cinder.scheduler.driver.Scheduler.backend_passes_filters') @mock.patch('cinder.db.volume_update') def test_migrate_volume_exception_returns_volume_state( - self, _mock_volume_update, _mock_host_passes, + self, _mock_volume_update, _mock_backend_passes, _mock_volume_get): - # Test NoValidHost exception behavior for migrate_volume_to_host. + # Test NoValidBackend exception behavior for migrate_volume_to_host. # Puts the volume in 'error_migrating' state and eats the exception. fake_updates = {'migration_status': 'error'} self._test_migrate_volume_exception_returns_volume_state( - _mock_volume_update, _mock_host_passes, _mock_volume_get, + _mock_volume_update, _mock_backend_passes, _mock_volume_get, 'available', fake_updates) @mock.patch('cinder.db.volume_get') - @mock.patch('cinder.scheduler.driver.Scheduler.host_passes_filters') + @mock.patch('cinder.scheduler.driver.Scheduler.backend_passes_filters') @mock.patch('cinder.db.volume_update') def test_migrate_volume_exception_returns_volume_state_maintenance( - self, _mock_volume_update, _mock_host_passes, + self, _mock_volume_update, _mock_backend_passes, _mock_volume_get): fake_updates = {'status': 'available', 'migration_status': 'error'} self._test_migrate_volume_exception_returns_volume_state( - _mock_volume_update, _mock_host_passes, _mock_volume_get, + _mock_volume_update, _mock_backend_passes, _mock_volume_get, 'maintenance', fake_updates) def _test_migrate_volume_exception_returns_volume_state( - self, _mock_volume_update, _mock_host_passes, + self, _mock_volume_update, _mock_backend_passes, _mock_volume_get, status, fake_updates): volume = tests_utils.create_volume(self.context, status=status, previous_status='available') fake_volume_id = volume.id request_spec = {'volume_id': fake_volume_id} - _mock_host_passes.side_effect = exception.NoValidHost(reason="") + _mock_backend_passes.side_effect = exception.NoValidBackend(reason="") _mock_volume_get.return_value = volume self.manager.migrate_volume_to_host(self.context, volume, 'host', True, @@ -264,15 +264,15 @@ class SchedulerManagerTestCase(test.TestCase): _mock_volume_update.assert_called_once_with(self.context, fake_volume_id, fake_updates) - _mock_host_passes.assert_called_once_with(self.context, 'host', - request_spec, {}) + _mock_backend_passes.assert_called_once_with(self.context, 'host', + request_spec, {}) @mock.patch('cinder.db.volume_update') @mock.patch('cinder.db.volume_attachment_get_all_by_volume_id') @mock.patch('cinder.quota.QUOTAS.rollback') def test_retype_volume_exception_returns_volume_state( self, quota_rollback, _mock_vol_attachment_get, _mock_vol_update): - # Test NoValidHost exception behavior for retype. + # Test NoValidBackend exception behavior for retype. # Puts the volume in original state and eats the exception. volume = tests_utils.create_volume(self.context, status='retyping', @@ -287,17 +287,17 @@ class SchedulerManagerTestCase(test.TestCase): 'migration_policy': 'on-demand', 'quota_reservations': reservations} _mock_vol_update.return_value = {'status': 'in-use'} - _mock_find_retype_host = mock.Mock( - side_effect=exception.NoValidHost(reason="")) - orig_retype = self.manager.driver.find_retype_host - self.manager.driver.find_retype_host = _mock_find_retype_host + _mock_find_retype_backend = mock.Mock( + side_effect=exception.NoValidBackend(reason="")) + orig_retype = self.manager.driver.find_retype_backend + self.manager.driver.find_retype_backend = _mock_find_retype_backend self.manager.retype(self.context, volume, request_spec=request_spec, filter_properties={}) - _mock_find_retype_host.assert_called_once_with(self.context, - request_spec, {}, - 'on-demand') + _mock_find_retype_backend.assert_called_once_with(self.context, + request_spec, {}, + 'on-demand') quota_rollback.assert_called_once_with(self.context, reservations) _mock_vol_update.assert_called_once_with(self.context, volume.id, {'status': 'in-use'}) @@ -329,7 +329,7 @@ class SchedulerManagerTestCase(test.TestCase): LOG.exception.reset_mock() db.consistencygroup_update.reset_mock() - mock_cg.side_effect = exception.NoValidHost( + mock_cg.side_effect = exception.NoValidBackend( reason="No weighed hosts available") self.manager.create_consistencygroup( self.context, consistencygroup_obj) diff --git a/cinder/tests/unit/scheduler/test_volume_number_weigher.py b/cinder/tests/unit/scheduler/test_volume_number_weigher.py index 1a0527fbb09..64864c3ffe3 100644 --- a/cinder/tests/unit/scheduler/test_volume_number_weigher.py +++ b/cinder/tests/unit/scheduler/test_volume_number_weigher.py @@ -68,21 +68,21 @@ class VolumeNumberWeigherTestCase(test.TestCase): weight_properties)[0] @mock.patch('cinder.db.sqlalchemy.api.service_get_all') - def _get_all_hosts(self, _mock_service_get_all, disabled=False): + def _get_all_backends(self, _mock_service_get_all, disabled=False): ctxt = context.get_admin_context() fakes.mock_host_manager_db_calls(_mock_service_get_all, disabled=disabled) - host_states = self.host_manager.get_all_host_states(ctxt) + backend_states = self.host_manager.get_all_backend_states(ctxt) _mock_service_get_all.assert_called_once_with( ctxt, None, # backend_match_level topic=constants.VOLUME_TOPIC, disabled=disabled) - return host_states + return backend_states def test_volume_number_weight_multiplier1(self): self.flags(volume_number_multiplier=-1.0) - hostinfo_list = self._get_all_hosts() + backend_info_list = self._get_all_backends() # host1: 1 volume Norm=0.0 # host2: 2 volumes @@ -92,14 +92,14 @@ class VolumeNumberWeigherTestCase(test.TestCase): # so, host1 should win: with mock.patch.object(api, 'volume_data_get_for_host', fake_volume_data_get_for_host): - weighed_host = self._get_weighed_host(hostinfo_list) + weighed_host = self._get_weighed_host(backend_info_list) self.assertEqual(0.0, weighed_host.weight) self.assertEqual('host1', utils.extract_host(weighed_host.obj.host)) def test_volume_number_weight_multiplier2(self): self.flags(volume_number_multiplier=1.0) - hostinfo_list = self._get_all_hosts() + backend_info_list = self._get_all_backends() # host1: 1 volume Norm=0 # host2: 2 volumes @@ -109,7 +109,7 @@ class VolumeNumberWeigherTestCase(test.TestCase): # so, host5 should win: with mock.patch.object(api, 'volume_data_get_for_host', fake_volume_data_get_for_host): - weighed_host = self._get_weighed_host(hostinfo_list) + weighed_host = self._get_weighed_host(backend_info_list) self.assertEqual(1.0, weighed_host.weight) self.assertEqual('host5', utils.extract_host(weighed_host.obj.host)) diff --git a/cinder/tests/unit/test_db_api.py b/cinder/tests/unit/test_db_api.py index 1598fa12f11..26d37391941 100644 --- a/cinder/tests/unit/test_db_api.py +++ b/cinder/tests/unit/test_db_api.py @@ -203,20 +203,30 @@ class DBAPIServiceTestCase(BaseTest): def test_service_get_all(self): expired = (datetime.datetime.utcnow() - datetime.timedelta(seconds=CONF.service_down_time + 1)) + db.cluster_create(self.ctxt, {'name': 'cluster_disabled', + 'binary': 'fake_binary', + 'disabled': True}) + db.cluster_create(self.ctxt, {'name': 'cluster_enabled', + 'binary': 'fake_binary', + 'disabled': False}) values = [ # Now we are updating updated_at at creation as well so this one # is up. {'host': 'host1', 'binary': 'b1', 'created_at': expired}, {'host': 'host1@ceph', 'binary': 'b2'}, {'host': 'host2', 'binary': 'b2'}, + {'disabled': False, 'cluster_name': 'cluster_enabled'}, + {'disabled': True, 'cluster_name': 'cluster_enabled'}, + {'disabled': False, 'cluster_name': 'cluster_disabled'}, + {'disabled': True, 'cluster_name': 'cluster_disabled'}, {'disabled': True, 'created_at': expired, 'updated_at': expired}, ] services = [self._create_service(vals) for vals in values] - disabled_services = services[-1:] - non_disabled_services = services[:-1] - up_services = services[0:3] - down_services = [services[3]] + disabled_services = services[-3:] + non_disabled_services = services[:-3] + up_services = services[:7] + down_services = [services[7]] expected = services[:2] expected_bin = services[1:3] compares = [ diff --git a/cinder/tests/unit/test_volume_rpcapi.py b/cinder/tests/unit/test_volume_rpcapi.py index 01fc9ef332b..5fc54a0c14c 100644 --- a/cinder/tests/unit/test_volume_rpcapi.py +++ b/cinder/tests/unit/test_volume_rpcapi.py @@ -156,15 +156,14 @@ class VolumeRpcAPITestCase(test.TestCase): if 'host' in expected_msg: del expected_msg['host'] - if 'dest_host' in expected_msg: - dest_host = expected_msg.pop('dest_host') - dest_host_dict = {'host': dest_host.host, - 'cluster_name': dest_host.cluster_name, - 'capabilities': dest_host.capabilities} - expected_msg['host'] = dest_host_dict + if 'dest_backend' in expected_msg: + dest_backend = expected_msg.pop('dest_backend') + dest_backend_dict = {'host': dest_backend.host, + 'cluster_name': dest_backend.cluster_name, + 'capabilities': dest_backend.capabilities} + expected_msg['host'] = dest_backend_dict if 'force_copy' in expected_msg: expected_msg['force_host_copy'] = expected_msg.pop('force_copy') - if 'new_volume' in expected_msg: volume = expected_msg['new_volume'] expected_msg['new_volume_id'] = volume['id'] @@ -544,16 +543,16 @@ class VolumeRpcAPITestCase(test.TestCase): @mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True) def test_migrate_volume(self, can_send_version): - class FakeHost(object): + class FakeBackend(object): def __init__(self): self.host = 'host' self.cluster_name = 'cluster_name' self.capabilities = {} - dest_host = FakeHost() + dest_backend = FakeBackend() self._test_volume_api('migrate_volume', rpc_method='cast', volume=self.fake_volume_obj, - dest_host=dest_host, + dest_backend=dest_backend, force_host_copy=True, version='3.5') @@ -567,17 +566,17 @@ class VolumeRpcAPITestCase(test.TestCase): @mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True) def test_retype(self, can_send_version): - class FakeHost(object): + class FakeBackend(object): def __init__(self): self.host = 'host' self.cluster_name = 'cluster_name' self.capabilities = {} - dest_host = FakeHost() + dest_backend = FakeBackend() self._test_volume_api('retype', rpc_method='cast', volume=self.fake_volume_obj, new_type_id='fake', - dest_host=dest_host, + dest_backend=dest_backend, migration_policy='never', reservations=self.fake_reservations, old_reservations=self.fake_reservations, @@ -608,7 +607,7 @@ class VolumeRpcAPITestCase(test.TestCase): rpc_method='cast', snapshot=my_fake_snapshot_obj, ref='foo', - host='fake_host', + backend='fake_host', version='3.0') def test_freeze_host(self): diff --git a/cinder/tests/unit/volume/drivers/ibm/test_ibm_flashsystem.py b/cinder/tests/unit/volume/drivers/ibm/test_ibm_flashsystem.py index e2fbb7cbcfd..63bec428f27 100644 --- a/cinder/tests/unit/volume/drivers/ibm/test_ibm_flashsystem.py +++ b/cinder/tests/unit/volume/drivers/ibm/test_ibm_flashsystem.py @@ -1164,7 +1164,7 @@ class FlashSystemDriverTestCase(test.TestCase): # case 3: host name is neither unicode nor string conn = {'host': 12345} - self.assertRaises(exception.NoValidHost, + self.assertRaises(exception.NoValidBackend, self.driver._connector_to_hostname_prefix, conn) diff --git a/cinder/tests/unit/volume/drivers/netapp/eseries/test_driver.py b/cinder/tests/unit/volume/drivers/netapp/eseries/test_driver.py index f2dcfa5022f..408d9732dca 100644 --- a/cinder/tests/unit/volume/drivers/netapp/eseries/test_driver.py +++ b/cinder/tests/unit/volume/drivers/netapp/eseries/test_driver.py @@ -350,7 +350,7 @@ class NetAppESeriesDriverTestCase(object): mock.Mock(side_effect=socket.gaierror)) self.assertRaises( - exception.NoValidHost, + exception.NoValidBackend, driver.library._check_mode_get_or_register_storage_system) def test_setup_error_invalid_first_controller_ip(self): @@ -361,7 +361,7 @@ class NetAppESeriesDriverTestCase(object): mock.Mock(side_effect=socket.gaierror)) self.assertRaises( - exception.NoValidHost, + exception.NoValidBackend, driver.library._check_mode_get_or_register_storage_system) def test_setup_error_invalid_second_controller_ip(self): @@ -372,7 +372,7 @@ class NetAppESeriesDriverTestCase(object): mock.Mock(side_effect=socket.gaierror)) self.assertRaises( - exception.NoValidHost, + exception.NoValidBackend, driver.library._check_mode_get_or_register_storage_system) def test_setup_error_invalid_both_controller_ips(self): @@ -383,7 +383,7 @@ class NetAppESeriesDriverTestCase(object): mock.Mock(side_effect=socket.gaierror)) self.assertRaises( - exception.NoValidHost, + exception.NoValidBackend, driver.library._check_mode_get_or_register_storage_system) def test_manage_existing_get_size(self): diff --git a/cinder/volume/drivers/ibm/flashsystem_common.py b/cinder/volume/drivers/ibm/flashsystem_common.py index 41853f7cca2..4a3784f3bfb 100644 --- a/cinder/volume/drivers/ibm/flashsystem_common.py +++ b/cinder/volume/drivers/ibm/flashsystem_common.py @@ -189,7 +189,7 @@ class FlashSystemDriver(san.SanDriver, msg = _('_create_host: Can not translate host name. Host name ' 'is not unicode or string.') LOG.error(msg) - raise exception.NoValidHost(reason=msg) + raise exception.NoValidBackend(reason=msg) host_name = six.text_type(host_name) diff --git a/cinder/volume/drivers/netapp/eseries/library.py b/cinder/volume/drivers/netapp/eseries/library.py index 65ccc6e1bc9..58dbca68d74 100644 --- a/cinder/volume/drivers/netapp/eseries/library.py +++ b/cinder/volume/drivers/netapp/eseries/library.py @@ -259,7 +259,7 @@ class NetAppESeriesLibrary(object): except socket.gaierror as e: LOG.error(_LE('Error resolving host %(host)s. Error - %(e)s.'), {'host': host, 'e': e}) - raise exception.NoValidHost( + raise exception.NoValidBackend( _("Controller IP '%(host)s' could not be resolved: %(e)s.") % {'host': host, 'e': e}) diff --git a/cinder/volume/rpcapi.py b/cinder/volume/rpcapi.py index 368660db368..8decac677ed 100644 --- a/cinder/volume/rpcapi.py +++ b/cinder/volume/rpcapi.py @@ -244,10 +244,10 @@ class VolumeAPI(rpc.RPCAPI): cctxt.cast(ctxt, 'extend_volume', volume=volume, new_size=new_size, reservations=reservations) - def migrate_volume(self, ctxt, volume, dest_host, force_host_copy): - backend_p = {'host': dest_host.host, - 'cluster_name': dest_host.cluster_name, - 'capabilities': dest_host.capabilities} + def migrate_volume(self, ctxt, volume, dest_backend, force_host_copy): + backend_p = {'host': dest_backend.host, + 'cluster_name': dest_backend.cluster_name, + 'capabilities': dest_backend.capabilities} version = '3.5' if not self.client.can_send_version(version): @@ -263,12 +263,12 @@ class VolumeAPI(rpc.RPCAPI): return cctxt.call(ctxt, 'migrate_volume_completion', volume=volume, new_volume=new_volume, error=error,) - def retype(self, ctxt, volume, new_type_id, dest_host, + def retype(self, ctxt, volume, new_type_id, dest_backend, migration_policy='never', reservations=None, old_reservations=None): - backend_p = {'host': dest_host.host, - 'cluster_name': dest_host.cluster_name, - 'capabilities': dest_host.capabilities} + backend_p = {'host': dest_backend.host, + 'cluster_name': dest_backend.cluster_name, + 'capabilities': dest_backend.capabilities} version = '3.5' if not self.client.can_send_version(version): version = '3.0' @@ -308,8 +308,8 @@ class VolumeAPI(rpc.RPCAPI): cctxt.cast(ctxt, 'failover_host', secondary_backend_id=secondary_backend_id) - def manage_existing_snapshot(self, ctxt, snapshot, ref, host): - cctxt = self._get_cctxt(host) + def manage_existing_snapshot(self, ctxt, snapshot, ref, backend): + cctxt = self._get_cctxt(backend) cctxt.cast(ctxt, 'manage_existing_snapshot', snapshot=snapshot, ref=ref)