Merge "Add ram filter"
This commit is contained in:
@@ -64,7 +64,8 @@ Related options:
|
|||||||
cfg.ListOpt("enabled_filters",
|
cfg.ListOpt("enabled_filters",
|
||||||
default=[
|
default=[
|
||||||
"NoopFilter",
|
"NoopFilter",
|
||||||
"CPUFilter"
|
"CPUFilter",
|
||||||
|
"RamFilter"
|
||||||
],
|
],
|
||||||
help="""
|
help="""
|
||||||
Filters that the scheduler will use.
|
Filters that the scheduler will use.
|
||||||
|
|||||||
42
zun/scheduler/filters/ram_filter.py
Normal file
42
zun/scheduler/filters/ram_filter.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# Copyright (c) 2017 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 oslo_log import log as logging
|
||||||
|
|
||||||
|
from zun.scheduler import filters
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class RamFilter(filters.BaseHostFilter):
|
||||||
|
"""Filter the containers by memory request"""
|
||||||
|
|
||||||
|
run_filter_once_per_request = True
|
||||||
|
|
||||||
|
def host_passes(self, host_state, container):
|
||||||
|
if not container.memory:
|
||||||
|
return True
|
||||||
|
|
||||||
|
request_ram = int(container.memory[:-1])
|
||||||
|
usable_ram = host_state.mem_total - host_state.mem_used
|
||||||
|
if usable_ram < request_ram:
|
||||||
|
LOG.debug("%(host_state)s does not have %(request_ram)d "
|
||||||
|
"usable memory, it only has %(usable_ram)d usable "
|
||||||
|
"memory.",
|
||||||
|
{'host_state': host_state,
|
||||||
|
'request_ram': request_ram,
|
||||||
|
'usable_ram': usable_ram})
|
||||||
|
return False
|
||||||
|
return True
|
||||||
41
zun/tests/unit/scheduler/filters/test_ram_filter.py
Normal file
41
zun/tests/unit/scheduler/filters/test_ram_filter.py
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# 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 zun.common import context
|
||||||
|
from zun import objects
|
||||||
|
from zun.scheduler.filters import ram_filter
|
||||||
|
from zun.tests import base
|
||||||
|
|
||||||
|
|
||||||
|
class TestRamFilter(base.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestRamFilter, self).setUp()
|
||||||
|
self.context = context.RequestContext('fake_user', 'fake_project')
|
||||||
|
|
||||||
|
def test_ram_filter_pass(self):
|
||||||
|
self.filt_cls = ram_filter.RamFilter()
|
||||||
|
container = objects.Container(self.context)
|
||||||
|
container.memory = '1024M'
|
||||||
|
host = objects.ComputeNode(self.context)
|
||||||
|
host.mem_total = 1024 * 128
|
||||||
|
host.mem_used = 1024
|
||||||
|
self.assertTrue(self.filt_cls.host_passes(host, container))
|
||||||
|
|
||||||
|
def test_ram_filter_fail(self):
|
||||||
|
self.filt_cls = ram_filter.RamFilter()
|
||||||
|
container = objects.Container(self.context)
|
||||||
|
container.memory = '4096M'
|
||||||
|
host = objects.ComputeNode(self.context)
|
||||||
|
host.mem_total = 1024 * 128
|
||||||
|
host.mem_used = 1024 * 127
|
||||||
|
self.assertFalse(self.filt_cls.host_passes(host, container))
|
||||||
@@ -58,18 +58,26 @@ class FilterSchedulerTestCase(base.TestCase):
|
|||||||
node1 = objects.ComputeNode(self.context)
|
node1 = objects.ComputeNode(self.context)
|
||||||
node1.cpus = 48
|
node1.cpus = 48
|
||||||
node1.cpu_used = 0.0
|
node1.cpu_used = 0.0
|
||||||
|
node1.mem_total = 1024 * 128
|
||||||
|
node1.mem_used = 1024 * 4
|
||||||
node1.hostname = 'host1'
|
node1.hostname = 'host1'
|
||||||
node2 = objects.ComputeNode(self.context)
|
node2 = objects.ComputeNode(self.context)
|
||||||
node2.cpus = 48
|
node2.cpus = 48
|
||||||
node2.cpu_used = 0.0
|
node2.cpu_used = 0.0
|
||||||
|
node2.mem_total = 1024 * 128
|
||||||
|
node2.mem_used = 1024 * 4
|
||||||
node2.hostname = 'host2'
|
node2.hostname = 'host2'
|
||||||
node3 = objects.ComputeNode(self.context)
|
node3 = objects.ComputeNode(self.context)
|
||||||
node3.cpus = 48
|
node3.cpus = 48
|
||||||
node3.cpu_used = 0.0
|
node3.cpu_used = 0.0
|
||||||
|
node3.mem_total = 1024 * 128
|
||||||
|
node3.mem_used = 1024 * 4
|
||||||
node3.hostname = 'host3'
|
node3.hostname = 'host3'
|
||||||
node4 = objects.ComputeNode(self.context)
|
node4 = objects.ComputeNode(self.context)
|
||||||
node4.cpus = 48
|
node4.cpus = 48
|
||||||
node4.cpu_used = 0.0
|
node4.cpu_used = 0.0
|
||||||
|
node4.mem_total = 1024 * 128
|
||||||
|
node4.mem_used = 1024 * 4
|
||||||
node4.hostname = 'host4'
|
node4.hostname = 'host4'
|
||||||
nodes = [node1, node2, node3, node4]
|
nodes = [node1, node2, node3, node4]
|
||||||
mock_compute_list.return_value = nodes
|
mock_compute_list.return_value = nodes
|
||||||
|
|||||||
Reference in New Issue
Block a user