Libvirt support for tagged volume attachment

This patch adds support for tagged volume attachment to the libvirt
driver.

Change-Id: I8b475992b881db08cf1354299cc86042413074cc
Implements: blueprint bp/virt-device-tagged-attach-detach
This commit is contained in:
Artom Lifshitz 2017-01-09 18:57:17 +00:00 committed by Matt Riedemann
parent 92524c2115
commit 7280f4fc4c
4 changed files with 31 additions and 5 deletions

View File

@ -6329,11 +6329,16 @@ class LibvirtConnTestCase(test.NoDBTestCase):
mock.patch.object(drvr, '_get_volume_config',
return_value=mock_conf),
mock.patch.object(drvr, '_set_cache_mode'),
mock.patch.object(drvr, '_check_discard_for_attach_volume')
mock.patch.object(drvr, '_check_discard_for_attach_volume'),
mock.patch.object(drvr, '_build_device_metadata'),
mock.patch.object(objects.Instance, 'save')
) as (mock_connect_volume, mock_get_volume_config,
mock_set_cache_mode, mock_check_discard):
mock_set_cache_mode, mock_check_discard,
mock_build_metadata, mock_save):
for state in (power_state.RUNNING, power_state.PAUSED):
mock_dom.info.return_value = [state, 512, 512, 2, 1234, 5678]
mock_build_metadata.return_value = \
objects.InstanceDeviceMetadata()
drvr.attach_volume(self.context, connection_info, instance,
"/dev/vdb", disk_bus=bdm['disk_bus'],
@ -6353,6 +6358,8 @@ class LibvirtConnTestCase(test.NoDBTestCase):
mock_dom.attachDeviceFlags.assert_called_with(
mock_conf.to_xml(), flags=flags)
mock_check_discard.assert_called_with(mock_conf, instance)
mock_build_metadata.assert_called_with(self.context, instance)
mock_save.assert_called_with()
@mock.patch('nova.virt.libvirt.host.Host.get_domain')
def test_detach_volume_with_vir_domain_affect_live_flag(self,

View File

@ -469,7 +469,9 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase):
self.assertEqual(storage_ip, result['ip'])
@catch_notimplementederror
def test_attach_detach_volume(self):
@mock.patch.object(libvirt.driver.LibvirtDriver, '_build_device_metadata',
return_value=objects.InstanceDeviceMetadata())
def test_attach_detach_volume(self, _):
instance_ref, network_info = self._get_running_instance()
connection_info = {
"driver_volume_type": "fake",
@ -484,7 +486,9 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase):
'/dev/sda'))
@catch_notimplementederror
def test_swap_volume(self):
@mock.patch.object(libvirt.driver.LibvirtDriver, '_build_device_metadata',
return_value=objects.InstanceDeviceMetadata())
def test_swap_volume(self, _):
instance_ref, network_info = self._get_running_instance()
self.assertIsNone(
self.connection.attach_volume(None, {'driver_volume_type': 'fake',
@ -500,7 +504,9 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase):
'/dev/sda', 2))
@catch_notimplementederror
def test_attach_detach_different_power_states(self):
@mock.patch.object(libvirt.driver.LibvirtDriver, '_build_device_metadata',
return_value=objects.InstanceDeviceMetadata())
def test_attach_detach_different_power_states(self, _):
instance_ref, network_info = self._get_running_instance()
connection_info = {
"driver_volume_type": "fake",

View File

@ -129,6 +129,7 @@ class ComputeDriver(object):
"supports_attach_interface": False,
"supports_device_tagging": False,
"supports_tagged_attach_interface": False,
"supports_tagged_attach_volume": False,
}
def __init__(self, virtapi):

View File

@ -302,6 +302,7 @@ class LibvirtDriver(driver.ComputeDriver):
"supports_attach_interface": True,
"supports_device_tagging": True,
"supports_tagged_attach_interface": True,
"supports_tagged_attach_volume": True,
}
def __init__(self, virtapi, read_only=False):
@ -1234,6 +1235,17 @@ class LibvirtDriver(driver.ComputeDriver):
encryptor.attach_volume(context, **encryption)
guest.attach_device(conf, persistent=True, live=live)
# NOTE(artom) If we're attaching with a device role tag, we need to
# rebuild device_metadata. If we're attaching without a role
# tag, we're rebuilding it here needlessly anyways. This isn't a
# massive deal, and it helps reduce code complexity by not having
# to indicate to the virt driver that the attach is tagged. The
# really important optimization of not calling the database unless
# device_metadata has actually changed is done for us by
# instance.save().
instance.device_metadata = self._build_device_metadata(
context, instance)
instance.save()
except Exception as ex:
LOG.exception(_LE('Failed to attach volume at mountpoint: %s'),
mountpoint, instance=instance)