From dcb51804127a40768f543fa30b6b505695bf64d1 Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Mon, 23 Apr 2018 14:33:25 -0400 Subject: [PATCH] Fix dropped check for boot_index 0 in _validate_bdm This reverts commit 7f4b49c9c97e06babf82f6846c804ad176cd4cde. 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 b9815c2331904a3749269289b861229796aa6c91) --- nova/compute/api.py | 9 ++++++--- nova/tests/unit/compute/test_compute_api.py | 12 ++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index 6594c29981b6..6dba744117ab 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -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), diff --git a/nova/tests/unit/compute/test_compute_api.py b/nova/tests/unit/compute/test_compute_api.py index f24721122271..5053f4536115 100644 --- a/nova/tests/unit/compute/test_compute_api.py +++ b/nova/tests/unit/compute/test_compute_api.py @@ -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')