Fix dropped check for boot_index 0 in _validate_bdm

This reverts commit 7f4b49c9c9.

During refactor change I8a3e7e6c4b72eb1c3707d54049d18dc29f606fe5
the conditional that at least one BDM had to be the boot
device was inadvertantly dropped, presumably because there was
no test for that case.

The validation is added back here along with a test.

Change-Id: I299bf846b658f2bb6903c898d7deac748f8d90e4
Related-Bug: #1766306
(cherry picked from commit b9815c2331)
This commit is contained in:
Matt Riedemann 2018-04-23 14:33:25 -04:00
parent bf0a069773
commit dcb5180412
2 changed files with 18 additions and 3 deletions

View File

@ -1286,6 +1286,11 @@ class API(base.Base):
def _validate_bdm(self, context, instance, instance_type,
block_device_mappings, supports_multiattach=False):
def _subsequent_list(l):
# Each device which is capable of being used as boot device should
# be given a unique boot index, starting from 0 in ascending order.
return all(el + 1 == l[i + 1] for i, el in enumerate(l[:-1]))
# Make sure that the boot indexes make sense.
# Setting a negative value or None indicates that the device should not
# be used for booting.
@ -1294,9 +1299,7 @@ class API(base.Base):
if bdm.boot_index is not None
and bdm.boot_index >= 0])
# Each device which is capable of being used as boot device should
# be given a unique boot index, starting from 0 in ascending order.
if any(i != v for i, v in enumerate(boot_indexes)):
if 0 not in boot_indexes or not _subsequent_list(boot_indexes):
# Convert the BlockDeviceMappingList to a list for repr details.
LOG.debug('Invalid block device mapping boot sequence for '
'instance: %s', list(block_device_mappings),

View File

@ -4218,6 +4218,18 @@ class _ComputeAPIUnitTestMixIn(object):
mock_attach_create.assert_called_once_with(
self.context, volume_id, instance.uuid)
def test_validate_bdm_missing_boot_index(self):
"""Tests that _validate_bdm will fail if there is no boot_index=0 entry
"""
bdms = objects.BlockDeviceMappingList(objects=[
objects.BlockDeviceMapping(
boot_index=None, image_id=uuids.image_id,
source_type='image', destination_type='volume')])
self.assertRaises(exception.InvalidBDMBootSequence,
self.compute_api._validate_bdm,
self.context, objects.Instance(), objects.Flavor(),
bdms)
def _test_provision_instances_with_cinder_error(self,
expected_exception):
@mock.patch('nova.compute.utils.check_num_instances_quota')