Skip to content

Commit

Permalink
Introduce ImagePropertiesFilter scheduler filter
Browse files Browse the repository at this point in the history
Commit d39137f added functionality to the ComputeFilter to filter on
architecture, hypervisor_type, and vm_mode. The existing ArchFilter
already filtered on architecture. This patch merges the ComputeFilter
functionality introduced in d39137f with the ArchFilter to create the
ImagePropertiesFilter.  The ImagePropertiesFilter uses image properties
specified in the request_spec to filter hosts.

This patch also adds the ImagePropertiesFilter to the list of default
filters specified by the scheduler_default_filters FLAG.

Fixes LP Bug #1037339

DocImpact

Change-Id: Ifa6fccf2db266b0fe3457d58fc81fdb50ffcbc0f
  • Loading branch information
jfehlig committed Aug 18, 2012
1 parent a10be15 commit 5ea7db9
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 224 deletions.
27 changes: 18 additions & 9 deletions doc/source/devref/filter_scheduler.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ There are some standard filter classes to use (:mod:`nova.scheduler.filters`):

* |AllHostsFilter| - frankly speaking, this filter does no operation. It
passes all the available hosts.
* |ArchFilter| - filters hosts based on architecture. It passes hosts
that can support the architecture specified in the instance properties.
* |ImagePropertiesFilter| - filters hosts based on properties defined
on the instance's image. It passes hosts that can support the specified
image properties contained in the instance.
* |AvailabilityZoneFilter| - filters hosts by availability zone. It passes
hosts matching the availability zone specfied in the instance properties.
* |ComputeCapabilityFilter| - checks that the capabilities provided by the
Expand Down Expand Up @@ -86,10 +87,17 @@ scheduler with availability zones support and can configure availability zones
on each compute host. This classes method `host_passes` returns `True` if
availability zone mentioned in request is the same on the current compute host.

The |ArchFilter| filters hosts based on the architecture specified in the
instance properties. E.g., an instance might require a host that supports
the arm architecture. The |ArchFilter| will only pass hosts that can
support the architecture requested by the instance.
The |ImagePropertiesFilter| filters hosts based on the architecture,
hypervisor type, and virtual machine mode specified in the
instance. E.g., an instance might require a host that supports the arm
architecture on a qemu compute host. The |ImagePropertiesFilter| will only
pass hosts that can statisfy this request. These instance
properties are populated from properties define on the instance's image.
E.g. an image can be decorated with these properties using
`glance image-update img-uuid --property architecture=arm --property
hypervisor_type=qemu`
Only hosts that statify these requirements will pass the
|ImagePropertiesFilter|.

|ComputeCapabilitesFilter| checks if the host satisfies any 'extra specs'
specfied on the instance type. The 'extra specs' can contain key/value pairs,
Expand Down Expand Up @@ -160,11 +168,12 @@ The default values for these settings in nova.conf are:
::

--scheduler_available_filters=nova.scheduler.filters.standard_filters
--scheduler_default_filters=RamFilter,ComputeFilter,AvailabilityZoneFilter,ComputeCapabilityFilter
--scheduler_default_filters=RamFilter,ComputeFilter,AvailabilityZoneFilter,ComputeCapabilityFilter,ImagePropertiesFilter

With this configuration, all filters in `nova.scheduler.filters`
would be available, and by default the |RamFilter|, |ComputeFilter|,
|AvailabilityZoneFilter|, and |ComputeCapabilityFilter| would be used.
|AvailabilityZoneFilter|, |ComputeCapabilityFilter|, and
|ImagePropertiesFilter| would be used.

If you want to create **your own filter** you just need to inherit from
|BaseHostFilter| and implement one method:
Expand Down Expand Up @@ -278,7 +287,7 @@ P.S.: you can find more examples of using Filter Scheduler and standard filters
in :mod:`nova.tests.scheduler`.

.. |AllHostsFilter| replace:: :class:`AllHostsFilter <nova.scheduler.filters.all_hosts_filter.AllHostsFilter>`
.. |ArchFilter| replace:: :class:`ArchFilter <nova.scheduler.filters.arch_filter.ArchFilter>`
.. |ImagePropertiesFilter| replace:: :class:`ImagePropertiesFilter <nova.scheduler.filters.image_props_filter.ImagePropertiesFilter>`
.. |AvailabilityZoneFilter| replace:: :class:`AvailabilityZoneFilter <nova.scheduler.filters.availability_zone_filter.AvailabilityZoneFilter>`
.. |BaseHostFilter| replace:: :class:`BaseHostFilter <nova.scheduler.filters.BaseHostFilter>`
.. |ComputeCapabilitiesFilter| replace:: :class:`ComputeCapabilitiesFilter <nova.scheduler.filters.compute_capabilities_filter.ComputeCapabilitiesFilter>`
Expand Down
2 changes: 1 addition & 1 deletion etc/nova/nova.conf.sample
Original file line number Diff line number Diff line change
Expand Up @@ -1211,7 +1211,7 @@
#### "nova.scheduler.filters.standard_filters" maps to all
#### filters included with nova.

# scheduler_default_filters=AvailabilityZoneFilter,RamFilter,ComputeFilter,ComputeCapabilitiesFilter
# scheduler_default_filters=AvailabilityZoneFilter,RamFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter
#### (ListOpt) Which filter class names to use for filtering hosts when not
#### specified in the request.

Expand Down
44 changes: 0 additions & 44 deletions nova/scheduler/filters/arch_filter.py

This file was deleted.

57 changes: 2 additions & 55 deletions nova/scheduler/filters/compute_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,59 +22,10 @@


class ComputeFilter(filters.BaseHostFilter):
"""Filter on active Compute nodes that satisfy the instance properties"""

def _instance_supported(self, capabilities, instance_meta):
"""Check if the instance is supported by the hypervisor.
The instance may specify an architecture, hypervisor, and
vm_mode, e.g. (x86_64, kvm, hvm).
"""
inst_arch = instance_meta.get('image_architecture', None)
inst_h_type = instance_meta.get('image_hypervisor_type', None)
inst_vm_mode = instance_meta.get('image_vm_mode', None)
inst_props_req = (inst_arch, inst_h_type, inst_vm_mode)

# Supported if no compute-related instance properties are specified
if not any(inst_props_req):
return True

supp_instances = capabilities.get('supported_instances', None)
# Not supported if an instance property is requested but nothing
# advertised by the host.
if not supp_instances:
LOG.debug(_("Instance contains properties %(instance_meta)s, "
"but no corresponding capabilities are advertised "
"by the compute node"), locals())
return False

def _compare_props(props, other_props):
for i in props:
if i and i not in other_props:
return False
return True

for supp_inst in supp_instances:
if _compare_props(inst_props_req, supp_inst):
LOG.debug(_("Instance properties %(instance_meta)s "
"are satisfied by compute host capabilities "
"%(capabilities)s"), locals())
return True

LOG.debug(_("Instance contains properties %(instance_meta)s "
"that are not provided by the compute node "
"capabilities %(capabilities)s"), locals())
return False
"""Filter on active Compute nodes"""

def host_passes(self, host_state, filter_properties):
"""Check if host passes instance compute properties.
Returns True for active compute nodes that satisfy
the compute properties specified in the instance.
"""
spec = filter_properties.get('request_spec', {})
instance_props = spec.get('instance_properties', {})
instance_meta = instance_props.get('system_metadata', {})
"""Returns True for only active compute nodes"""
instance_type = filter_properties.get('instance_type')
if host_state.topic != 'compute' or not instance_type:
return True
Expand All @@ -89,8 +40,4 @@ def host_passes(self, host_state, filter_properties):
LOG.debug(_("%(host_state)s is disabled via capabilities"),
locals())
return False
if not self._instance_supported(capabilities, instance_meta):
LOG.debug(_("%(host_state)s does not support requested "
"instance_properties"), locals())
return False
return True
86 changes: 86 additions & 0 deletions nova/scheduler/filters/image_props_filter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Copyright (c) 2011-2012 OpenStack, LLC
# Copyright (c) 2012 Canonical Ltd
# Copyright (c) 2012 SUSE LINUX Products GmbH
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from nova.openstack.common import log as logging
from nova.scheduler import filters
from nova import utils


LOG = logging.getLogger(__name__)


class ImagePropertiesFilter(filters.BaseHostFilter):
"""Filter compute nodes that satisfy instance image properties.
The ImagePropertiesFilter filters compute nodes that satisfy
any architecture, hpervisor type, or virtual machine mode properties
specified on the instance's image properties. Image properties are
contained in the image dictionary in the request_spec.
"""

def _instance_supported(self, capabilities, image_props):
img_arch = image_props.get('architecture', None)
img_h_type = image_props.get('hypervisor_type', None)
img_vm_mode = image_props.get('vm_mode', None)
checked_img_props = (img_arch, img_h_type, img_vm_mode)

# Supported if no compute-related instance properties are specified
if not any(checked_img_props):
return True

supp_instances = capabilities.get('supported_instances', None)
# Not supported if an instance property is requested but nothing
# advertised by the host.
if not supp_instances:
LOG.debug(_("Instance contains properties %(image_props)s, "
"but no corresponding capabilities are advertised "
"by the compute node"), locals())
return False

def _compare_props(props, other_props):
for i in props:
if i and i not in other_props:
return False
return True

for supp_inst in supp_instances:
if _compare_props(checked_img_props, supp_inst):
LOG.debug(_("Instance properties %(image_props)s "
"are satisfied by compute host capabilities "
"%(capabilities)s"), locals())
return True

LOG.debug(_("Instance contains properties %(image_props)s "
"that are not provided by the compute node "
"capabilities %(capabilities)s"), locals())
return False

def host_passes(self, host_state, filter_properties):
"""Check if host passes specified image properties.
Returns True for compute nodes that satisfy image properties
contained in the request_spec.
"""
spec = filter_properties.get('request_spec', {})
image_props = spec.get('image', {}).get('properties', {})
capabilities = host_state.capabilities

if not self._instance_supported(capabilities, image_props):
LOG.debug(_("%(host_state)s does not support requested "
"instance_properties"), locals())
return False
return True
3 changes: 2 additions & 1 deletion nova/scheduler/host_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
'AvailabilityZoneFilter',
'RamFilter',
'ComputeFilter',
'ComputeCapabilitiesFilter'
'ComputeCapabilitiesFilter',
'ImagePropertiesFilter'
],
help='Which filter class names to use for filtering hosts '
'when not specified in the request.'),
Expand Down

0 comments on commit 5ea7db9

Please sign in to comment.