Disable limit if affinity(anti)/same(different)host is requested
When max_placement_results is less than the total number of nodes in
a deployment it may not be possible to use the affinity, anti-affinity,
same host or different host filters as there is no guarantee
for placement to return the expected hosts under such situations. This
patch disables the max_placement_results parameter when nova queries
placement for ``GET /allocation_candidates`` if the
request_spec.scheduler_hints containts any of group, same_host or
different_host keys.
Note that due to change If7ea02df42d220c5042947efdef4777509492a0b only
being in Train the test in the backport calls resources_from_request_spec
without the context or fake HostManager parameters.
Change-Id: Ia2d5f80b6db59a8f6da03344aeaa6aa599407672
Closes-Bug: #1827628
(cherry picked from commit 2f9e972ba3
)
This commit is contained in:
parent
de9151acaf
commit
c094a6ef0c
|
@ -491,6 +491,12 @@ def resources_from_request_spec(spec_obj):
|
||||||
if 'force_nodes' in spec_obj and spec_obj.force_nodes:
|
if 'force_nodes' in spec_obj and spec_obj.force_nodes:
|
||||||
res_req._limit = None
|
res_req._limit = None
|
||||||
|
|
||||||
|
# Don't limit allocation candidates when using affinity/anti-affinity.
|
||||||
|
if ('scheduler_hints' in spec_obj and any(
|
||||||
|
key in ['group', 'same_host', 'different_host']
|
||||||
|
for key in spec_obj.scheduler_hints)):
|
||||||
|
res_req._limit = None
|
||||||
|
|
||||||
return res_req
|
return res_req
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import ddt
|
||||||
import mock
|
import mock
|
||||||
from oslo_utils.fixture import uuidsentinel as uuids
|
from oslo_utils.fixture import uuidsentinel as uuids
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@ from nova.tests.unit import fake_instance
|
||||||
from nova.tests.unit.scheduler import fakes
|
from nova.tests.unit.scheduler import fakes
|
||||||
|
|
||||||
|
|
||||||
|
@ddt.ddt
|
||||||
class TestUtils(test.NoDBTestCase):
|
class TestUtils(test.NoDBTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -490,6 +492,42 @@ class TestUtils(test.NoDBTestCase):
|
||||||
req.get_request_group(None).resources)
|
req.get_request_group(None).resources)
|
||||||
self.assertEqual(1, len(list(req.resource_groups())))
|
self.assertEqual(1, len(list(req.resource_groups())))
|
||||||
|
|
||||||
|
@ddt.data(
|
||||||
|
# Test single hint that we are checking for.
|
||||||
|
{'group': [uuids.fake]},
|
||||||
|
# Test hint we care about and some other random hint.
|
||||||
|
{'same_host': [uuids.fake], 'fake-hint': ['fake-value']},
|
||||||
|
# Test multiple hints we are checking for.
|
||||||
|
{'same_host': [uuids.server1], 'different_host': [uuids.server2]})
|
||||||
|
def test_resources_from_request_spec_no_limit_based_on_hint(self, hints):
|
||||||
|
"""Tests that there is no limit applied to the
|
||||||
|
GET /allocation_candidates query string if a given scheduler hint
|
||||||
|
is in the request spec.
|
||||||
|
"""
|
||||||
|
flavor = objects.Flavor(vcpus=1,
|
||||||
|
memory_mb=1024,
|
||||||
|
root_gb=15,
|
||||||
|
ephemeral_gb=0,
|
||||||
|
swap=0)
|
||||||
|
fake_spec = objects.RequestSpec(
|
||||||
|
flavor=flavor, scheduler_hints=hints)
|
||||||
|
expected = utils.ResourceRequest()
|
||||||
|
expected._rg_by_id[None] = objects.RequestGroup(
|
||||||
|
use_same_provider=False,
|
||||||
|
resources={
|
||||||
|
'VCPU': 1,
|
||||||
|
'MEMORY_MB': 1024,
|
||||||
|
'DISK_GB': 15,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
expected._limit = None
|
||||||
|
resources = utils.resources_from_request_spec(fake_spec)
|
||||||
|
self.assertResourceRequestsEqual(expected, resources)
|
||||||
|
expected_querystring = (
|
||||||
|
'resources=DISK_GB%3A15%2CMEMORY_MB%3A1024%2CVCPU%3A1'
|
||||||
|
)
|
||||||
|
self.assertEqual(expected_querystring, resources.to_querystring())
|
||||||
|
|
||||||
@mock.patch('nova.compute.utils.is_volume_backed_instance',
|
@mock.patch('nova.compute.utils.is_volume_backed_instance',
|
||||||
return_value=False)
|
return_value=False)
|
||||||
def test_resources_from_flavor_no_bfv(self, mock_is_bfv):
|
def test_resources_from_flavor_no_bfv(self, mock_is_bfv):
|
||||||
|
|
Loading…
Reference in New Issue