Add scope to extra_specs entries

Do to conflicts between different scheduler filters it is necessary
to allow an optional scope for the different keys.  This scope is a
leading string followed by a ':' character, e.g.:

        foo:bar

is the `bar' entry with scope `foo'.

The Trusted filter will now use the scope `trust' and the
AggregateInstanceExtraSpecs and ComputeCapabilities filters will
check against any unscoped keys in the `extra_specs' table.
Any new filters that utilize the `extra_specs' table will need to
use a unique scope string for any keys they require.

Resolves bug 1039386

Change-Id: I2466dc3d4de8e9aeb76b294eeda1c939c0413366
Signed-off-by: Don Dugger <donald.d.dugger@intel.com
This commit is contained in:
Don Dugger 2012-09-04 15:58:57 -06:00
parent 6c6e6a8f48
commit 851705db95
4 changed files with 17 additions and 10 deletions

View File

@ -40,6 +40,8 @@ class AggregateInstanceExtraSpecsFilter(filters.BaseHostFilter):
metadata = db.aggregate_metadata_get_by_host(context, host_state.host)
for key, req in instance_type['extra_specs'].iteritems():
if key.count(':'):
continue
aggregate_vals = metadata.get(key, None)
if not aggregate_vals:
LOG.debug(_("%(host_state)s fails instance_type extra_specs "

View File

@ -31,6 +31,8 @@ class ComputeCapabilitiesFilter(filters.BaseHostFilter):
return True
for key, req in instance_type['extra_specs'].iteritems():
if key.count(':'):
continue
cap = capabilities.get(key, None)
if not extra_specs_ops.match(cap, req):
return False

View File

@ -199,7 +199,7 @@ class TrustedFilter(filters.BaseHostFilter):
def host_passes(self, host_state, filter_properties):
instance = filter_properties.get('instance_type', {})
extra = instance.get('extra_specs', {})
trust = extra.get('trusted_host')
trust = extra.get('trust:trusted_host')
host = host_state.host
if trust:
return self._is_trusted(host, trust)

View File

@ -693,13 +693,13 @@ class HostFiltersTestCase(test.TestCase):
def test_compute_filter_passes_extra_specs_simple(self):
self._do_test_compute_filter_extra_specs(
ecaps={'opt1': '1', 'opt2': '2'},
especs={'opt1': '1', 'opt2': '2'},
especs={'opt1': '1', 'opt2': '2', 'trust:trusted_host': 'true'},
passes=True)
def test_compute_filter_fails_extra_specs_simple(self):
self._do_test_compute_filter_extra_specs(
ecaps={'opt1': '1', 'opt2': '2'},
especs={'opt1': '1', 'opt2': '222'},
especs={'opt1': '1', 'opt2': '222', 'trust:trusted_host': 'true'},
passes=False)
def test_aggregate_filter_passes_no_extra_specs(self):
@ -736,7 +736,8 @@ class HostFiltersTestCase(test.TestCase):
def test_aggregate_filter_fails_extra_specs_deleted_host(self):
self._stub_service_is_up(True)
filt_cls = self.class_map['AggregateInstanceExtraSpecsFilter']()
extra_specs = {'opt1': 's== 1', 'opt2': 's== 2'}
extra_specs = {'opt1': 's== 1', 'opt2': 's== 2',
'trust:trusted_host': 'true'}
self._create_aggregate_with_host(metadata={'opt1': '1'})
agg2 = self._create_aggregate_with_host(name='fake2',
metadata={'opt2': '2'})
@ -749,13 +750,15 @@ class HostFiltersTestCase(test.TestCase):
def test_aggregate_filter_passes_extra_specs_simple(self):
self._do_test_aggregate_filter_extra_specs(
emeta={'opt1': '1', 'opt2': '2'},
especs={'opt1': '1', 'opt2': '2'},
especs={'opt1': '1', 'opt2': '2',
'trust:trusted_host': 'true'},
passes=True)
def test_aggregate_filter_fails_extra_specs_simple(self):
self._do_test_aggregate_filter_extra_specs(
emeta={'opt1': '1', 'opt2': '2'},
especs={'opt1': '1', 'opt2': '222'},
especs={'opt1': '1', 'opt2': '222',
'trust:trusted_host': 'true'},
passes=False)
def test_isolated_hosts_fails_isolated_on_non_isolated(self):
@ -1116,7 +1119,7 @@ class HostFiltersTestCase(test.TestCase):
DATA = '{"hosts":[{"host_name":"host1","trust_lvl":"trusted"}]}'
self._stub_service_is_up(True)
filt_cls = self.class_map['TrustedFilter']()
extra_specs = {'trusted_host': 'trusted'}
extra_specs = {'trust:trusted_host': 'trusted'}
filter_properties = {'instance_type': {'memory_mb': 1024,
'extra_specs': extra_specs}}
host = fakes.FakeHostState('host1', 'compute', {})
@ -1127,7 +1130,7 @@ class HostFiltersTestCase(test.TestCase):
DATA = '{"hosts":[{"host_name":"host1","trust_lvl":"untrusted"}]}'
self._stub_service_is_up(True)
filt_cls = self.class_map['TrustedFilter']()
extra_specs = {'trusted_host': 'trusted'}
extra_specs = {'trust:trusted_host': 'trusted'}
filter_properties = {'instance_type': {'memory_mb': 1024,
'extra_specs': extra_specs}}
host = fakes.FakeHostState('host1', 'compute', {})
@ -1138,7 +1141,7 @@ class HostFiltersTestCase(test.TestCase):
DATA = '{"hosts":[{"host_name":"host1","trust_lvl":"trusted"}]}'
self._stub_service_is_up(True)
filt_cls = self.class_map['TrustedFilter']()
extra_specs = {'trusted_host': 'untrusted'}
extra_specs = {'trust:trusted_host': 'untrusted'}
filter_properties = {'instance_type': {'memory_mb': 1024,
'extra_specs': extra_specs}}
host = fakes.FakeHostState('host1', 'compute', {})
@ -1149,7 +1152,7 @@ class HostFiltersTestCase(test.TestCase):
DATA = '{"hosts":[{"host_name":"host1","trust_lvl":"untrusted"}]}'
self._stub_service_is_up(True)
filt_cls = self.class_map['TrustedFilter']()
extra_specs = {'trusted_host': 'untrusted'}
extra_specs = {'trust:trusted_host': 'untrusted'}
filter_properties = {'instance_type': {'memory_mb': 1024,
'extra_specs': extra_specs}}
host = fakes.FakeHostState('host1', 'compute', {})