Skip to content

Commit

Permalink
Import Ironic scheduler filters and host manager
Browse files Browse the repository at this point in the history
This is an import of the Ironic scheduler changes as of
commit da967d77894be6f23d81fb5cc948f9d13898ba84

implements bp: add-ironic-driver

Co-authored-by: Adam Gandelman <adamg@ubuntu.com>
Co-authored-by: ChangBo Guo(gcb) <eric.guo@easystack.cn>
Co-authored-by: Chris Behrens <cbehrens@codestud.com>
Co-authored-by: Chris Krelle <nobodycam@gmail.com>
Co-authored-by: Devananda van der Veen <devananda.vdv@gmail.com>
Co-authored-by: Fengqian Gao <fengqian.gao@intel.com>
Co-authored-by: Hans Lindgren <hanlind@kth.se>
Co-authored-by: Jenkins <jenkins@review.openstack.org>
Co-authored-by: Lucas Alvares Gomes <lucasagomes@gmail.com>
Co-authored-by: Michael Davies <michael@the-davies.net>
Co-authored-by: Rohan Kanade <openstack@rohankanade.com>
Co-authored-by: Zhongyue Luo <zhongyue.nah@intel.com>

Change-Id: I358d9c0485c5dcf81498871faa9150e3bf167c6b
  • Loading branch information
AevaOnline authored and mrda committed Aug 1, 2014
1 parent e6015ce commit 53c1794
Show file tree
Hide file tree
Showing 8 changed files with 778 additions and 43 deletions.
54 changes: 11 additions & 43 deletions nova/scheduler/baremetal_host_manager.py
Expand Up @@ -18,57 +18,25 @@
Manage hosts in the current zone.
"""

from nova.openstack.common import jsonutils
import nova.scheduler.base_baremetal_host_manager as bbhm
from nova.scheduler import host_manager


class BaremetalNodeState(host_manager.HostState):
class BaremetalNodeState(bbhm.BaseBaremetalNodeState):
"""Mutable and immutable information tracked for a host.
This is an attempt to remove the ad-hoc data structures
previously used and lock down access.
"""
pass

def update_from_compute_node(self, compute):
"""Update information about a host from its compute_node info."""
all_ram_mb = compute['memory_mb']

free_disk_mb = compute['free_disk_gb'] * 1024
free_ram_mb = compute['free_ram_mb']

self.free_ram_mb = free_ram_mb
self.total_usable_ram_mb = all_ram_mb
self.free_disk_mb = free_disk_mb
self.vcpus_total = compute['vcpus']
self.vcpus_used = compute['vcpus_used']

stats = compute.get('stats', '{}')
self.stats = jsonutils.loads(stats)

def consume_from_instance(self, instance):
self.free_ram_mb = 0
self.free_disk_mb = 0
self.vcpus_used = self.vcpus_total


def new_host_state(self, host, node, **kwargs):
"""Returns an instance of BaremetalNodeState or HostState according to
compute['cpu_info']. If 'cpu_info' equals 'baremetal cpu', it returns an
instance of BaremetalNodeState. If not, returns an instance of HostState.
"""
compute = kwargs.get('compute')

if compute and compute.get('cpu_info') == 'baremetal cpu':
return BaremetalNodeState(host, node, **kwargs)
else:
return host_manager.HostState(host, node, **kwargs)


class BaremetalHostManager(host_manager.HostManager):
class BaremetalHostManager(bbhm.BaseBaremetalHostManager):
"""Bare-Metal HostManager class."""

# Override.
# Yes, this is not a class, and it is OK
host_state_cls = new_host_state

def __init__(self):
super(BaremetalHostManager, self).__init__()
def host_state_cls(self, host, node, **kwargs):
"""Factory function/property to create a new HostState."""
compute = kwargs.get('compute')
if compute and compute.get('cpu_info') == 'baremetal cpu':
return BaremetalNodeState(host, node, **kwargs)
else:
return host_manager.HostState(host, node, **kwargs)
57 changes: 57 additions & 0 deletions nova/scheduler/base_baremetal_host_manager.py
@@ -0,0 +1,57 @@
# Copyright (c) 2012 NTT DOCOMO, INC.
# Copyright (c) 2011 OpenStack Foundation
# 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.

"""
Manage hosts in the current zone.
"""

from nova.openstack.common import jsonutils
from nova.scheduler import host_manager


class BaseBaremetalNodeState(host_manager.HostState):
"""Mutable and immutable information tracked for a host.
This is an attempt to remove the ad-hoc data structures
previously used and lock down access.
"""

def update_from_compute_node(self, compute):
"""Update information about a host from its compute_node info."""
self.vcpus_total = compute['vcpus']
self.vcpus_used = compute['vcpus_used']

self.free_ram_mb = compute['free_ram_mb']
self.total_usable_ram_mb = compute['memory_mb']
self.free_disk_mb = compute['free_disk_gb'] * 1024

stats = compute.get('stats', '{}')
self.stats = jsonutils.loads(stats)

def consume_from_instance(self, instance):
"""Consume nodes entire resources regardless of instance request."""
self.free_ram_mb = 0
self.free_disk_mb = 0
self.vcpus_used = self.vcpus_total


class BaseBaremetalHostManager(host_manager.HostManager):
"""Base class for Baremetal and Ironic HostManager classes."""

def host_state_cls(self, host, node, **kwargs):
"""Factory function to create a new HostState. May be overridden
in subclasses to extend functionality.
"""
return BaseBaremetalNodeState(host, node, **kwargs)
51 changes: 51 additions & 0 deletions nova/scheduler/filters/exact_core_filter.py
@@ -0,0 +1,51 @@
# Copyright (c) 2014 OpenStack Foundation
#
# 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.i18n import _
from nova.openstack.common import log as logging
from nova.scheduler import filters

LOG = logging.getLogger(__name__)


class ExactCoreFilter(filters.BaseHostFilter):
"""Exact Core Filter."""

def host_passes(self, host_state, filter_properties):
"""Return True if host has the exact number of CPU cores."""
instance_type = filter_properties.get('instance_type')
if not instance_type:
return True

if not host_state.vcpus_total:
# Fail safe
LOG.warning(_("VCPUs not set; assuming CPU collection broken"))
return False

required_vcpus = instance_type['vcpus']
usable_vcpus = host_state.vcpus_total - host_state.vcpus_used

if required_vcpus != usable_vcpus:
LOG.debug("%(host_state)s does not have exactly "
"%(requested_vcpus)s cores of usable vcpu, it has "
"%(usable_vcpus)s.",
{'host_state': host_state,
'requested_vcpus': required_vcpus,
'usable_vcpus': usable_vcpus})
return False

return True
41 changes: 41 additions & 0 deletions nova/scheduler/filters/exact_disk_filter.py
@@ -0,0 +1,41 @@
# Copyright (c) 2014 OpenStack Foundation
# 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

LOG = logging.getLogger(__name__)


class ExactDiskFilter(filters.BaseHostFilter):
"""Exact Disk Filter."""

def host_passes(self, host_state, filter_properties):
"""Return True if host has the exact amount of disk available."""
instance_type = filter_properties.get('instance_type')
requested_disk = (1024 * (instance_type['root_gb'] +
instance_type['ephemeral_gb']) +
instance_type['swap'])

if requested_disk != host_state.free_disk_mb:
LOG.debug("%(host_state)s does not have exactly "
"%(requested_disk)s MB usable disk, it "
"has %(usable_disk_mb)s.",
{'host_state': host_state,
'requested_disk': requested_disk,
'usable_disk_mb': host_state.free_disk_mb})
return False

return True
38 changes: 38 additions & 0 deletions nova/scheduler/filters/exact_ram_filter.py
@@ -0,0 +1,38 @@
# Copyright (c) 2014 OpenStack Foundation
# 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

LOG = logging.getLogger(__name__)


class ExactRamFilter(filters.BaseHostFilter):
"""Exact RAM Filter."""

def host_passes(self, host_state, filter_properties):
"""Return True if host has the exact amount of RAM available."""
instance_type = filter_properties.get('instance_type')
requested_ram = instance_type['memory_mb']
if requested_ram != host_state.free_ram_mb:
LOG.debug("%(host_state)s does not have exactly "
"%(requested_ram)s MB usable RAM, it has "
"%(usable_ram)s.",
{'host_state': host_state,
'requested_ram': requested_ram,
'usable_ram': host_state.free_ram_mb})
return False

return True
93 changes: 93 additions & 0 deletions nova/scheduler/ironic_host_manager.py
@@ -0,0 +1,93 @@
# Copyright (c) 2012 NTT DOCOMO, INC.
# Copyright (c) 2011-2014 OpenStack Foundation
# 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.

"""
Ironic host manager.
This host manager will consume all cpu's, disk space, and
ram from a host / node as it is supporting Baremetal hosts, which can not be
subdivided into multiple instances.
"""
from oslo.config import cfg

from nova.openstack.common import log as logging
from nova.openstack.common import timeutils
import nova.scheduler.base_baremetal_host_manager as bbhm
from nova.scheduler import host_manager

host_manager_opts = [
cfg.ListOpt('baremetal_scheduler_default_filters',
default=[
'RetryFilter',
'AvailabilityZoneFilter',
'ComputeFilter',
'ComputeCapabilitiesFilter',
'ImagePropertiesFilter',
'ExactRamFilter',
'ExactDiskFilter',
'ExactCoreFilter',
],
help='Which filter class names to use for filtering '
'baremetal hosts when not specified in the request.'),
cfg.BoolOpt('scheduler_use_baremetal_filters',
default=False,
help='Flag to decide whether to use '
'baremetal_scheduler_default_filters or not.'),

]

CONF = cfg.CONF
CONF.register_opts(host_manager_opts)

LOG = logging.getLogger(__name__)


class IronicNodeState(bbhm.BaseBaremetalNodeState):
"""Mutable and immutable information tracked for a host.
This is an attempt to remove the ad-hoc data structures
previously used and lock down access.
"""

def update_from_compute_node(self, compute):
"""Update information about a host from its compute_node info."""
super(IronicNodeState, self).update_from_compute_node(compute)

self.total_usable_disk_gb = compute['local_gb']
self.updated = compute['updated_at']

def consume_from_instance(self, instance):
"""Consume nodes entire resources regardless of instance request."""
super(IronicNodeState, self).consume_from_instance(instance)

self.updated = timeutils.utcnow()


class IronicHostManager(bbhm.BaseBaremetalHostManager):
"""Ironic HostManager class."""

def __init__(self):
super(IronicHostManager, self).__init__()
if CONF.scheduler_use_baremetal_filters:
baremetal_default = CONF.baremetal_scheduler_default_filters
CONF.scheduler_default_filters = baremetal_default

def host_state_cls(self, host, node, **kwargs):
"""Factory function/property to create a new HostState."""
compute = kwargs.get('compute')
if compute and compute.get('cpu_info') == 'baremetal cpu':
return IronicNodeState(host, node, **kwargs)
else:
return host_manager.HostState(host, node, **kwargs)

0 comments on commit 53c1794

Please sign in to comment.