Skip to content

Commit a4a53bf

Browse files
Zuulopenstack-gerrit
Zuul
authored andcommitted
Merge "Ensure attachment_id always exists for block device mapping" into stable/queens
2 parents c716600 + 58af9ba commit a4a53bf

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

nova/compute/api.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,13 @@ def _validate_bdm(self, context, instance, instance_type,
13461346
# compatibility can be removed after Ocata EOL.
13471347
self._check_attach(context, volume, instance)
13481348
bdm.volume_size = volume.get('size')
1349+
1350+
# NOTE(mnaser): If we end up reserving the volume, it will
1351+
# not have an attachment_id which is needed
1352+
# for cleanups. This can be removed once
1353+
# all calls to reserve_volume are gone.
1354+
if 'attachment_id' not in bdm:
1355+
bdm.attachment_id = None
13491356
except (exception.CinderConnectionFailed,
13501357
exception.InvalidVolume,
13511358
exception.MultiattachNotSupportedOldMicroversion,

nova/tests/functional/wsgi/test_servers.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,7 @@ def test_bfv_delete_build_request_pre_scheduling_ocata(self, mock_get):
276276

277277
# The volume should no longer have any attachments as instance delete
278278
# should have removed them.
279-
# self.assertNotIn(volume_id, cinder.reserved_volumes)
280-
# FIXME(mnaser): This is part of bug 1750666 where the BDMs aren't
281-
# properly deleted because they don't exist in the database.
282-
self.assertIn(volume_id, cinder.reserved_volumes)
279+
self.assertNotIn(volume_id, cinder.reserved_volumes)
283280

284281
def test_bfv_delete_build_request_pre_scheduling(self):
285282
cinder = self.useFixture(

nova/tests/unit/compute/test_compute_api.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4005,6 +4005,46 @@ def test_get_bdm_image_metadata_with_cinder_down(self, mock_get):
40054005
self.context,
40064006
bdms, legacy_bdm=True)
40074007

4008+
@mock.patch.object(objects.service, 'get_minimum_version_all_cells',
4009+
return_value=17)
4010+
@mock.patch.object(objects.Service, 'get_minimum_version',
4011+
return_value=17)
4012+
@mock.patch.object(cinder.API, 'get')
4013+
@mock.patch.object(cinder.API, 'reserve_volume')
4014+
def test_validate_bdm_returns_attachment_id(self, mock_reserve_volume,
4015+
mock_get, mock_get_min_ver,
4016+
mock_get_min_ver_all):
4017+
# Tests that bdm validation *always* returns an attachment_id even if
4018+
# it's None.
4019+
instance = self._create_instance_obj()
4020+
instance_type = self._create_flavor()
4021+
volume_id = 'e856840e-9f5b-4894-8bde-58c6e29ac1e8'
4022+
volume_info = {'status': 'available',
4023+
'attach_status': 'detached',
4024+
'id': volume_id,
4025+
'multiattach': False}
4026+
mock_get.return_value = volume_info
4027+
4028+
# NOTE(mnaser): We use the AnonFakeDbBlockDeviceDict to make sure that
4029+
# the attachment_id field does not get any defaults to
4030+
# properly test this function.
4031+
bdms = [objects.BlockDeviceMapping(
4032+
**fake_block_device.AnonFakeDbBlockDeviceDict(
4033+
{
4034+
'boot_index': 0,
4035+
'volume_id': volume_id,
4036+
'source_type': 'volume',
4037+
'destination_type': 'volume',
4038+
'device_name': 'vda',
4039+
}))]
4040+
self.compute_api._validate_bdm(self.context, instance, instance_type,
4041+
bdms)
4042+
self.assertIsNone(bdms[0].attachment_id)
4043+
4044+
mock_get.assert_called_once_with(self.context, volume_id)
4045+
mock_reserve_volume.assert_called_once_with(
4046+
self.context, volume_id)
4047+
40084048
@mock.patch.object(objects.service, 'get_minimum_version_all_cells',
40094049
return_value=17)
40104050
@mock.patch.object(objects.Service, 'get_minimum_version',

0 commit comments

Comments
 (0)