Merge "Support scoped keys in aggregate extra specs filter"
This commit is contained in:
		@@ -67,7 +67,8 @@ There are some standard filter classes to use (:mod:`nova.scheduler.filters`):
 | 
			
		||||
 | 
			
		||||
* |AggregateInstanceExtraSpecsFilter| - checks that the aggregate metadata
 | 
			
		||||
  satisfies any extra specifications associated with the instance type (that
 | 
			
		||||
  have no scope).  It passes hosts that can create the specified instance type.
 | 
			
		||||
  have no scope or are scoped with 'aggregate_instance_extra_specs').
 | 
			
		||||
  It passes hosts that can create the specified instance type.
 | 
			
		||||
  The extra specifications can have the same operators as
 | 
			
		||||
  |ComputeCapabilitiesFilter|.
 | 
			
		||||
* |ComputeFilter| - passes all hosts that are operational and enabled.
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,8 @@ from nova.scheduler.filters import extra_specs_ops
 | 
			
		||||
 | 
			
		||||
LOG = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
_SCOPE = 'aggregate_instance_extra_specs'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AggregateInstanceExtraSpecsFilter(filters.BaseHostFilter):
 | 
			
		||||
    """AggregateInstanceExtraSpecsFilter works with InstanceType records."""
 | 
			
		||||
@@ -43,10 +45,14 @@ class AggregateInstanceExtraSpecsFilter(filters.BaseHostFilter):
 | 
			
		||||
        metadata = db.aggregate_metadata_get_by_host(context, host_state.host)
 | 
			
		||||
 | 
			
		||||
        for key, req in instance_type['extra_specs'].iteritems():
 | 
			
		||||
            # NOTE(jogo) any key containing a scope (scope is terminated
 | 
			
		||||
            # by a `:') will be ignored by this filter. (bug 1039386)
 | 
			
		||||
            if key.count(':'):
 | 
			
		||||
                continue
 | 
			
		||||
            # Either not scope format, or aggregate_instance_extra_specs scope
 | 
			
		||||
            scope = key.split(':', 1)
 | 
			
		||||
            if len(scope) > 1:
 | 
			
		||||
                if scope[0] != _SCOPE:
 | 
			
		||||
                    continue
 | 
			
		||||
                else:
 | 
			
		||||
                    del scope[0]
 | 
			
		||||
            key = scope[0]
 | 
			
		||||
            aggregate_vals = metadata.get(key, None)
 | 
			
		||||
            if not aggregate_vals:
 | 
			
		||||
                LOG.debug(_("%(host_state)s fails instance_type extra_specs "
 | 
			
		||||
 
 | 
			
		||||
@@ -860,11 +860,26 @@ class HostFiltersTestCase(test.NoDBTestCase):
 | 
			
		||||
        self.assertFalse(filt_cls.host_passes(host, filter_properties))
 | 
			
		||||
 | 
			
		||||
    def test_aggregate_filter_passes_extra_specs_simple(self):
 | 
			
		||||
        especs = {
 | 
			
		||||
            # Un-scoped extra spec
 | 
			
		||||
            'opt1': '1',
 | 
			
		||||
            # Scoped extra spec that applies to this filter
 | 
			
		||||
            'aggregate_instance_extra_specs:opt2': '2',
 | 
			
		||||
            # Scoped extra spec that does not apply to this filter
 | 
			
		||||
            'trust:trusted_host': 'true',
 | 
			
		||||
        }
 | 
			
		||||
        self._do_test_aggregate_filter_extra_specs(
 | 
			
		||||
            emeta={'opt1': '1', 'opt2': '2'},
 | 
			
		||||
            especs={'opt1': '1', 'opt2': '2',
 | 
			
		||||
                    'trust:trusted_host': 'true'},
 | 
			
		||||
            passes=True)
 | 
			
		||||
                emeta={'opt1': '1', 'opt2': '2'}, especs=especs, passes=True)
 | 
			
		||||
 | 
			
		||||
    def test_aggregate_filter_passes_with_key_same_as_scope(self):
 | 
			
		||||
        especs = {
 | 
			
		||||
                # Un-scoped extra spec, make sure we don't blow up if it
 | 
			
		||||
                # happens to match our scope.
 | 
			
		||||
                'aggregate_instance_extra_specs': '1',
 | 
			
		||||
        }
 | 
			
		||||
        self._do_test_aggregate_filter_extra_specs(
 | 
			
		||||
                emeta={'aggregate_instance_extra_specs': '1'},
 | 
			
		||||
                especs=especs, passes=True)
 | 
			
		||||
 | 
			
		||||
    def test_aggregate_filter_fails_extra_specs_simple(self):
 | 
			
		||||
        self._do_test_aggregate_filter_extra_specs(
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user