Apply scheduler limits to Exact* filters
The DiskFilter, RamFilter and CoreFilter scheduler filters set the
resource limit on the HostState object during filtering. This is
later checked in compute during the claim, and used to enforce
the allocation ratios in a safe manner. The Exact* filters do not
set the resource limits, so scheduler race conditions can result
in multiple bare metal instances claiming a single host.
This change sets the resource limits on the HostState object in
the ExactCoreFilter, ExactDiskFilter and ExactRamFilter, ensuring
that only a single baremetal instance can claim a compute host.
Conflicts:
nova/tests/unit/scheduler/filters/test_exact_core_filter.py
nova/tests/unit/scheduler/filters/test_exact_disk_filter.py
nova/tests/unit/scheduler/filters/test_exact_ram_filter.py
Change-Id: I31d0331afc4698046a4568935a95f70f30e335dd
Partial-Bug: #1341420
Co-Authored-By: Will Miller <wmiller@cray.com>
(cherry picked from commit 3471cc8b74
)
This commit is contained in:
parent
c5d0d2d0f4
commit
19e7abad96
|
@ -48,4 +48,8 @@ class ExactCoreFilter(filters.BaseHostFilter):
|
|||
'usable_vcpus': usable_vcpus})
|
||||
return False
|
||||
|
||||
# NOTE(mgoddard): Setting the limit ensures that it is enforced in
|
||||
# compute. This ensures that if multiple instances are scheduled to a
|
||||
# single host, then all after the first will fail in the claim.
|
||||
host_state.limits['vcpu'] = host_state.vcpus_total
|
||||
return True
|
||||
|
|
|
@ -39,4 +39,8 @@ class ExactDiskFilter(filters.BaseHostFilter):
|
|||
'usable_disk_mb': host_state.free_disk_mb})
|
||||
return False
|
||||
|
||||
# NOTE(mgoddard): Setting the limit ensures that it is enforced in
|
||||
# compute. This ensures that if multiple instances are scheduled to a
|
||||
# single host, then all after the first will fail in the claim.
|
||||
host_state.limits['disk_gb'] = host_state.total_usable_disk_gb
|
||||
return True
|
||||
|
|
|
@ -36,4 +36,8 @@ class ExactRamFilter(filters.BaseHostFilter):
|
|||
'usable_ram': host_state.free_ram_mb})
|
||||
return False
|
||||
|
||||
# NOTE(mgoddard): Setting the limit ensures that it is enforced in
|
||||
# compute. This ensures that if multiple instances are scheduled to a
|
||||
# single host, then all after the first will fail in the claim.
|
||||
host_state.limits['memory_mb'] = host_state.total_usable_ram_mb
|
||||
return True
|
||||
|
|
|
@ -25,11 +25,13 @@ class TestExactCoreFilter(test.NoDBTestCase):
|
|||
filter_properties = {'instance_type': {'vcpus': 1}}
|
||||
host = self._get_host({'vcpus_total': 3, 'vcpus_used': 2})
|
||||
self.assertTrue(self.filt_cls.host_passes(host, filter_properties))
|
||||
self.assertEqual(host.limits.get('vcpu'), 3)
|
||||
|
||||
def test_exact_core_filter_fails(self):
|
||||
filter_properties = {'instance_type': {'vcpus': 2}}
|
||||
host = self._get_host({'vcpus_total': 3, 'vcpus_used': 2})
|
||||
self.assertFalse(self.filt_cls.host_passes(host, filter_properties))
|
||||
self.assertNotIn('vcpu', host.limits)
|
||||
|
||||
def test_exact_core_filter_passes_no_instance_type(self):
|
||||
filter_properties = {}
|
||||
|
@ -40,6 +42,7 @@ class TestExactCoreFilter(test.NoDBTestCase):
|
|||
filter_properties = {'instance_type': {'vcpus': 1}}
|
||||
host = self._get_host({})
|
||||
self.assertFalse(self.filt_cls.host_passes(host, filter_properties))
|
||||
self.assertNotIn('vcpu', host.limits)
|
||||
|
||||
def _get_host(self, host_attributes):
|
||||
return fakes.FakeHostState('host1', 'node1', host_attributes)
|
||||
|
|
|
@ -29,8 +29,11 @@ class TestExactDiskFilter(test.NoDBTestCase):
|
|||
'swap': 1024
|
||||
}
|
||||
}
|
||||
host = self._get_host({'free_disk_mb': 3 * 1024})
|
||||
disk_gb = 3
|
||||
host = self._get_host({'free_disk_mb': disk_gb * 1024,
|
||||
'total_usable_disk_gb': disk_gb})
|
||||
self.assertTrue(self.filt_cls.host_passes(host, filter_properties))
|
||||
self.assertEqual(host.limits.get('disk_gb'), disk_gb)
|
||||
|
||||
def test_exact_disk_filter_fails(self):
|
||||
filter_properties = {
|
||||
|
@ -42,6 +45,7 @@ class TestExactDiskFilter(test.NoDBTestCase):
|
|||
}
|
||||
host = self._get_host({'free_disk_mb': 2 * 1024})
|
||||
self.assertFalse(self.filt_cls.host_passes(host, filter_properties))
|
||||
self.assertNotIn('disk_gb', host.limits)
|
||||
|
||||
def _get_host(self, host_attributes):
|
||||
return fakes.FakeHostState('host1', 'node1', host_attributes)
|
||||
|
|
|
@ -23,13 +23,17 @@ class TestRamFilter(test.NoDBTestCase):
|
|||
|
||||
def test_exact_ram_filter_passes(self):
|
||||
filter_properties = {'instance_type': {'memory_mb': 1024}}
|
||||
host = self._get_host({'free_ram_mb': 1024})
|
||||
ram_mb = 1024
|
||||
host = self._get_host({'free_ram_mb': ram_mb,
|
||||
'total_usable_ram_mb': ram_mb})
|
||||
self.assertTrue(self.filt_cls.host_passes(host, filter_properties))
|
||||
self.assertEqual(host.limits.get('memory_mb'), ram_mb)
|
||||
|
||||
def test_exact_ram_filter_fails(self):
|
||||
filter_properties = {'instance_type': {'memory_mb': 512}}
|
||||
host = self._get_host({'free_ram_mb': 1024})
|
||||
self.assertFalse(self.filt_cls.host_passes(host, filter_properties))
|
||||
self.assertNotIn('memory_mb', host.limits)
|
||||
|
||||
def _get_host(self, host_attributes):
|
||||
return fakes.FakeHostState('host1', 'node1', host_attributes)
|
||||
|
|
Loading…
Reference in New Issue