Fix NoneType error in _notify_volume_usage_detach

If the driver.block_stats() method returns None, like the
libvirt driver will if the guest is gone during an evacuate,
we'll get a NoneType error trying to unpack the return value
from the driver. Instead, simply return as if the driver
raised NotImplementedError.

Since handling None is changing the contract on the virt
driver API, the docstring is updated to explain the acceptable
return values of the driver method.

Conflicts:
      nova/tests/unit/compute/test_compute_mgr.py

NOTE(mriedem): The conflict is due to not having the
test_get_scheduler_hints test from change
I49ffebcd129990f1835f404d98b51732a32171eb which was
added in Queens.

Change-Id: I98a2785c07f7af02ad83650c72d9e1868290ece4
Closes-Bug: #1796981
(cherry picked from commit 4da54c0786)
(cherry picked from commit 940034c27c)
(cherry picked from commit 62fbfdfa8f)
This commit is contained in:
Matt Riedemann 2018-10-10 15:07:00 -04:00
parent 32482352e4
commit d004b0ecfa
3 changed files with 26 additions and 1 deletions

View File

@ -4958,13 +4958,14 @@ class ComputeManager(manager.Manager):
if CONF.volume_usage_poll_interval <= 0:
return
vol_stats = []
mp = bdm.device_name
# Handle bootable volumes which will not contain /dev/
if '/dev/' in mp:
mp = mp[5:]
try:
vol_stats = self.driver.block_stats(instance, mp)
if vol_stats is None:
return
except NotImplementedError:
return

View File

@ -4202,6 +4202,23 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
mock.call(self.context, inst_obj, 'fake-mini',
action='soft_delete', phase='end')])
def test_notify_volume_usage_detach_no_block_stats(self):
"""Tests the case that the virt driver returns None from the
block_stats() method and no notification is sent, similar to the
virt driver raising NotImplementedError.
"""
self.flags(volume_usage_poll_interval=60)
fake_instance = objects.Instance()
fake_bdm = objects.BlockDeviceMapping(device_name='/dev/vda')
with mock.patch.object(self.compute.driver, 'block_stats',
return_value=None) as block_stats:
# Assert a notification isn't sent.
with mock.patch.object(self.compute.notifier, 'info',
new_callable=mock.NonCallableMock):
self.compute._notify_volume_usage_detach(
self.context, fake_instance, fake_bdm)
block_stats.assert_called_once_with(fake_instance, 'vda')
class ComputeManagerBuildInstanceTestCase(test.NoDBTestCase):
def setUp(self):

View File

@ -1262,6 +1262,13 @@ class ComputeDriver(object):
unused.
Note that this function takes an instance ID.
:param instance: nova.objects.Instance to get block storage statistics
:param disk_id: mountpoint name, e.g. "vda"
:returns: None if block statistics could not be retrieved, otherwise a
list of the form: [rd_req, rd_bytes, wr_req, wr_bytes, errs]
:raises: NotImplementedError if the driver does not implement this
method
"""
raise NotImplementedError()