diff --git a/nova/tests/virt/libvirt/test_driver.py b/nova/tests/virt/libvirt/test_driver.py index b6564f92e815..1ee2ff5773db 100644 --- a/nova/tests/virt/libvirt/test_driver.py +++ b/nova/tests/virt/libvirt/test_driver.py @@ -4928,10 +4928,12 @@ class LibvirtConnTestCase(test.NoDBTestCase): fakelibvirt.VIR_DOMAIN_AFFECT_LIVE) with contextlib.nested( - mock.patch.object(conn, '_connect_volume', + mock.patch.object(conn, '_connect_volume'), + mock.patch.object(conn, '_get_volume_config', return_value=mock_conf), mock.patch.object(conn, '_set_cache_mode') - ) as (mock_connect_volume, mock_set_cache_mode): + ) as (mock_connect_volume, mock_get_volume_config, + mock_set_cache_mode): for state in (power_state.RUNNING, power_state.PAUSED): mock_dom.info.return_value = [state, 512, 512, 2, 1234, 5678] @@ -4943,6 +4945,8 @@ class LibvirtConnTestCase(test.NoDBTestCase): mock_get_info.assert_called_with(CONF.libvirt.virt_type, bdm) mock_connect_volume.assert_called_with( connection_info, disk_info) + mock_get_volume_config.assert_called_with( + connection_info, disk_info) mock_set_cache_mode.assert_called_with(mock_conf) mock_dom.attachDeviceFlags.assert_called_with( mock_conf.to_xml(), flags) @@ -6645,6 +6649,7 @@ class LibvirtConnTestCase(test.NoDBTestCase): 'serial': 'afc1', 'data': { 'access_mode': 'rw', + 'device_path': '/dev/path/to/dev', 'target_discovered': False, 'encrypted': False, 'qos_specs': None, @@ -6702,7 +6707,8 @@ class LibvirtConnTestCase(test.NoDBTestCase): mock.patch.object(conn.firewall_driver, 'prepare_instance_filter'), mock.patch.object(conn.firewall_driver, 'apply_instance_filter'), mock.patch.object(conn, '_create_domain'), - mock.patch.object(conn, '_connect_volume', + mock.patch.object(conn, '_connect_volume'), + mock.patch.object(conn, '_get_volume_config', return_value=disk_mock), mock.patch.object(conn, 'get_info', return_value={'state': power_state.RUNNING}), @@ -10123,12 +10129,8 @@ Active: 8381604 kB bdi = {'block_device_mapping': [mock_volume]} network_info = [network_model.VIF(id='1'), network_model.VIF(id='2', active=True)] - disk_info = {'bus': 'virtio', 'type': 'file', - 'dev': 'vda'} - get_info_from_bdm.return_value = disk_info with contextlib.nested( - mock.patch.object(conn, '_connect_volume'), mock.patch.object(conn, '_get_volume_encryptor'), mock.patch.object(conn, 'plug_vifs'), mock.patch.object(conn.firewall_driver, 'setup_basic_filtering'), @@ -10136,23 +10138,14 @@ Active: 8381604 kB 'prepare_instance_filter'), mock.patch.object(conn, '_create_domain'), mock.patch.object(conn.firewall_driver, 'apply_instance_filter'), - ) as (connect_volume, get_volume_encryptor, plug_vifs, - setup_basic_filtering, prepare_instance_filter, create_domain, - apply_instance_filter): - connect_volume.return_value = mock.MagicMock( - source_path='/path/fake-volume1') + ) as (get_volume_encryptor, plug_vifs, setup_basic_filtering, + prepare_instance_filter, create_domain, apply_instance_filter): create_domain.return_value = mock_dom domain = conn._create_domain_and_network(self.context, fake_xml, instance, network_info, block_device_info=bdi) - get_info_from_bdm.assert_called_once_with(CONF.libvirt.virt_type, - mock_volume) - connect_volume.assert_called_once_with(connection_info, disk_info) - self.assertEqual(connection_info['data']['device_path'], - '/path/fake-volume1') - mock_volume.save.assert_called_once_with(self.context) get_encryption_metadata.assert_called_once_with(self.context, conn._volume_api, fake_volume_id, connection_info) get_volume_encryptor.assert_called_once_with(connection_info, @@ -10167,6 +10160,50 @@ Active: 8381604 kB power_on=True) self.assertEqual(mock_dom, domain) + def test_get_guest_storage_config(self): + conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + + test_instance = copy.deepcopy(self.test_instance) + test_instance["default_swap_device"] = None + instance = objects.Instance(**test_instance) + flavor = instance.get_flavor() + flavor.extra_specs = {} + conn_info = {'driver_volume_type': 'fake', 'data': {}} + bdi = {'block_device_mapping': + driver_block_device.convert_volumes([ + fake_block_device.FakeDbBlockDeviceDict({ + 'id': 1, + 'source_type': 'volume', + 'destination_type': 'volume', + 'device_name': '/dev/vdc'}) + ])} + bdm = bdi['block_device_mapping'][0] + bdm['connection_info'] = conn_info + disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type, + instance, bdi) + mock_conf = mock.MagicMock(source_path='fake') + + with contextlib.nested( + mock.patch.object(driver_block_device.DriverVolumeBlockDevice, + 'save'), + mock.patch.object(conn, '_connect_volume'), + mock.patch.object(conn, '_get_volume_config', + return_value=mock_conf), + mock.patch.object(conn, '_set_cache_mode') + ) as (volume_save, connect_volume, get_volume_config, set_cache_mode): + devices = conn._get_guest_storage_config(instance, None, + disk_info, False, bdi, flavor) + + self.assertEqual(3, len(devices)) + self.assertEqual('/dev/vdb', instance.default_ephemeral_device) + self.assertIsNone(instance.default_swap_device) + connect_volume.assert_called_with(bdm['connection_info'], + {'bus': 'virtio', 'type': 'disk', 'dev': 'vdc'}) + get_volume_config.assert_called_with(bdm['connection_info'], + {'bus': 'virtio', 'type': 'disk', 'dev': 'vdc'}) + self.assertEqual(1, volume_save.call_count) + self.assertEqual(3, set_cache_mode.call_count) + def test_get_neutron_events(self): conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) network_info = [network_model.VIF(id='1'), diff --git a/nova/tests/virt/libvirt/test_volume.py b/nova/tests/virt/libvirt/test_volume.py index 8688bb35e730..0e2a2117fd44 100644 --- a/nova/tests/virt/libvirt/test_volume.py +++ b/nova/tests/virt/libvirt/test_volume.py @@ -104,7 +104,7 @@ class LibvirtVolumeTestCase(test.NoDBTestCase): }, 'serial': 'fake_serial', } - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) + conf = libvirt_driver.get_config(connection_info, self.disk_info) tree = conf.format_dom() self._assertDiskInfoEquals(tree, self.disk_info) @@ -129,7 +129,7 @@ class LibvirtVolumeTestCase(test.NoDBTestCase): }, 'serial': 'fake_serial', } - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) + conf = libvirt_driver.get_config(connection_info, self.disk_info) tree = conf.format_dom() self.assertEqual('block', tree.get('type')) self.assertEqual('fake_serial', tree.find('./serial').text) @@ -151,7 +151,7 @@ class LibvirtVolumeTestCase(test.NoDBTestCase): "dev": "vde", "type": "disk", } - conf = libvirt_driver.connect_volume(connection_info, disk_info) + conf = libvirt_driver.get_config(connection_info, disk_info) tree = conf.format_dom() blockio = tree.find('./blockio') self.assertEqual('4096', blockio.get('logical_block_size')) @@ -171,7 +171,7 @@ class LibvirtVolumeTestCase(test.NoDBTestCase): "dev": "vde", "type": "disk", } - conf = libvirt_driver.connect_volume(connection_info, disk_info) + conf = libvirt_driver.get_config(connection_info, disk_info) tree = conf.format_dom() iotune = tree.find('./iotune') # ensure invalid qos_specs is ignored @@ -187,7 +187,7 @@ class LibvirtVolumeTestCase(test.NoDBTestCase): } del connection_info['data']['qos_specs'] connection_info['data'].update(dict(qos_specs=specs)) - conf = libvirt_driver.connect_volume(connection_info, disk_info) + conf = libvirt_driver.get_config(connection_info, disk_info) tree = conf.format_dom() self.assertEqual('102400', tree.find('./iotune/total_bytes_sec').text) self.assertEqual('51200', tree.find('./iotune/read_bytes_sec').text) @@ -211,17 +211,17 @@ class LibvirtVolumeTestCase(test.NoDBTestCase): "type": "disk", } self.assertRaises(exception.InvalidVolumeAccessMode, - libvirt_driver.connect_volume, + libvirt_driver.get_config, connection_info, self.disk_info) connection_info['data']['access_mode'] = 'rw' - conf = libvirt_driver.connect_volume(connection_info, disk_info) + conf = libvirt_driver.get_config(connection_info, disk_info) tree = conf.format_dom() readonly = tree.find('./readonly') self.assertIsNone(readonly) connection_info['data']['access_mode'] = 'ro' - conf = libvirt_driver.connect_volume(connection_info, disk_info) + conf = libvirt_driver.get_config(connection_info, disk_info) tree = conf.format_dom() readonly = tree.find('./readonly') self.assertIsNotNone(readonly) @@ -236,7 +236,7 @@ class LibvirtVolumeTestCase(test.NoDBTestCase): 'target_portal': location, 'target_iqn': iqn, 'target_lun': 1, - 'host_device': dev_path, + 'device_path': dev_path, 'qos_specs': { 'total_bytes_sec': '102400', 'read_iops_sec': '200', @@ -279,13 +279,7 @@ Setting up iSCSI targets: unused libvirt_driver = volume.LibvirtISCSIVolumeDriver(self.fake_conn) connection_info = self.iscsi_connection(self.vol, self.location, self.iqn) - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) - self.assertEqual('qemu', conf.driver_name) - tree = conf.format_dom() - dev_str = '/dev/disk/by-path/ip-%s-iscsi-%s-lun-1' % (self.location, - self.iqn) - self.assertEqual(tree.get('type'), 'block') - self.assertEqual(tree.find('./source').get('dev'), dev_str) + libvirt_driver.connect_volume(connection_info, self.disk_info) libvirt_driver.disconnect_volume(connection_info, "vde") expected_commands = [('iscsiadm', '-m', 'node', '-T', self.iqn, '-p', self.location), @@ -304,7 +298,6 @@ Setting up iSCSI targets: unused '-p', self.location, '--logout'), ('iscsiadm', '-m', 'node', '-T', self.iqn, '-p', self.location, '--op', 'delete')] - self.assertEqual('102400', tree.find('./iotune/total_bytes_sec').text) self.assertEqual(self.executes, expected_commands) def test_libvirt_iscsi_driver_still_in_use(self): @@ -316,12 +309,8 @@ Setting up iSCSI targets: unused self.stubs.Set(self.fake_conn, '_get_all_block_devices', lambda: devs) vol = {'id': 1, 'name': self.name} connection_info = self.iscsi_connection(vol, self.location, self.iqn) - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) - tree = conf.format_dom() + libvirt_driver.connect_volume(connection_info, self.disk_info) dev_name = 'ip-%s-iscsi-%s-lun-1' % (self.location, self.iqn) - dev_str = '/dev/disk/by-path/%s' % dev_name - self.assertEqual(tree.get('type'), 'block') - self.assertEqual(tree.find('./source').get('dev'), dev_str) libvirt_driver.disconnect_volume(connection_info, "vde") expected_commands = [('iscsiadm', '-m', 'node', '-T', self.iqn, '-p', self.location), @@ -361,13 +350,7 @@ Setting up iSCSI targets: unused vol = {'id': 1, 'name': self.name} connection_info = self.iscsi_connection(vol, self.location, self.iqn) - conf = libvirt_driver.connect_volume(connection_info, - self.disk_info) - tree = conf.format_dom() - dev_name = 'ip-%s-iscsi-%s-lun-1' % (self.location, self.iqn) - dev_str = '/dev/disk/by-path/%s' % dev_name - self.assertEqual('block', tree.get('type')) - self.assertEqual(dev_str, tree.find('./source').get('dev')) + libvirt_driver.connect_volume(connection_info, self.disk_info) libvirt_driver.use_multipath = True libvirt_driver.disconnect_volume(connection_info, "vde") @@ -435,7 +418,7 @@ Setting up iSCSI targets: unused def test_libvirt_sheepdog_driver(self): libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn) connection_info = self.sheepdog_connection(self.vol) - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) + conf = libvirt_driver.get_config(connection_info, self.disk_info) tree = conf.format_dom() self.assertEqual(tree.get('type'), 'network') self.assertEqual(tree.find('./source').get('protocol'), 'sheepdog') @@ -461,7 +444,7 @@ Setting up iSCSI targets: unused def test_libvirt_rbd_driver(self): libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn) connection_info = self.rbd_connection(self.vol) - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) + conf = libvirt_driver.get_config(connection_info, self.disk_info) tree = conf.format_dom() self._assertNetworkAndProtocolEquals(tree) self.assertIsNone(tree.find('./source/auth')) @@ -476,7 +459,7 @@ Setting up iSCSI targets: unused ports = [None, '6790', '6791'] connection_info['data']['hosts'] = hosts connection_info['data']['ports'] = ports - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) + conf = libvirt_driver.get_config(connection_info, self.disk_info) tree = conf.format_dom() self._assertNetworkAndProtocolEquals(tree) self.assertIsNone(tree.find('./source/auth')) @@ -494,7 +477,7 @@ Setting up iSCSI targets: unused connection_info['data']['secret_type'] = secret_type connection_info['data']['secret_uuid'] = self.uuid - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) + conf = libvirt_driver.get_config(connection_info, self.disk_info) tree = conf.format_dom() self._assertNetworkAndProtocolEquals(tree) self.assertEqual(tree.find('./auth').get('username'), self.user) @@ -517,7 +500,7 @@ Setting up iSCSI targets: unused rbd_secret_uuid=flags_uuid, group='libvirt') - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) + conf = libvirt_driver.get_config(connection_info, self.disk_info) tree = conf.format_dom() self._assertNetworkAndProtocolEquals(tree) self.assertEqual(tree.find('./auth').get('username'), flags_user) @@ -534,7 +517,7 @@ Setting up iSCSI targets: unused connection_info['data']['secret_type'] = secret_type connection_info['data']['secret_uuid'] = self.uuid - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) + conf = libvirt_driver.get_config(connection_info, self.disk_info) tree = conf.format_dom() self._assertNetworkAndProtocolEquals(tree) self.assertIsNone(tree.find('./auth')) @@ -557,7 +540,7 @@ Setting up iSCSI targets: unused rbd_secret_uuid=flags_uuid, group='libvirt') - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) + conf = libvirt_driver.get_config(connection_info, self.disk_info) tree = conf.format_dom() self._assertNetworkAndProtocolEquals(tree) self.assertEqual(tree.find('./auth').get('username'), flags_user) @@ -570,7 +553,7 @@ Setting up iSCSI targets: unused libvirt_driver = volume.LibvirtISCSIVolumeDriver(self.fake_conn) connection_info = self.iscsi_connection(self.vol, self.location, self.iqn) - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) + conf = libvirt_driver.get_config(connection_info, self.disk_info) tree = conf.format_dom() dev_str = '/dev/disk/by-path/ip-%s-iscsi-%s-lun-1' % (self.location, self.iqn) @@ -592,7 +575,8 @@ Setting up iSCSI targets: unused self.stubs.Set(libvirt_driver, '_get_target_portals_from_iscsiadm_output', lambda x: [[self.location, self.iqn]]) - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) + libvirt_driver.connect_volume(connection_info, self.disk_info) + conf = libvirt_driver.get_config(connection_info, self.disk_info) tree = conf.format_dom() self.assertEqual(tree.find('./source').get('dev'), mpdev_filepath) libvirt_driver._get_multipath_iqn = lambda x: self.iqn @@ -667,7 +651,8 @@ Setting up iSCSI targets: unused self.stubs.Set(libvirt_driver, '_get_target_portals_from_iscsiadm_output', lambda x: [['fake_portal1', 'fake_iqn1']]) - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) + libvirt_driver.connect_volume(connection_info, self.disk_info) + conf = libvirt_driver.get_config(connection_info, self.disk_info) tree = conf.format_dom() self.assertEqual(tree.find('./source').get('dev'), mpdev_filepath) libvirt_driver.disconnect_volume(connection_info, 'vde') @@ -695,7 +680,8 @@ Setting up iSCSI targets: unused self.stubs.Set(libvirt_driver, '_get_target_portals_from_iscsiadm_output', lambda x: [[location, iqn]]) - conf = libvirt_driver.connect_volume(connection_info, disk_info) + libvirt_driver.connect_volume(connection_info, disk_info) + conf = libvirt_driver.get_config(connection_info, disk_info) tree = conf.format_dom() self.assertEqual(tree.find('./source').get('dev'), mpdev_filepath) libvirt_driver._get_multipath_iqn = lambda x: iqn @@ -731,7 +717,8 @@ Setting up iSCSI targets: unused self.stubs.Set(libvirt_driver, '_get_target_portals_from_iscsiadm_output', lambda x: [['fake_portal1', 'fake_iqn1']]) - conf = libvirt_driver.connect_volume(connection_info, disk_info) + libvirt_driver.connect_volume(connection_info, disk_info) + conf = libvirt_driver.get_config(connection_info, disk_info) tree = conf.format_dom() self.assertEqual(tree.find('./source').get('dev'), mpdev_filepath) libvirt_driver.disconnect_volume(connection_info, 'vde') @@ -747,15 +734,15 @@ Setting up iSCSI targets: unused export_string = '192.168.1.1:/nfs/share1' export_mnt_base = os.path.join(mnt_base, utils.get_hash_str(export_string)) - file_path = os.path.join(export_mnt_base, self.name) connection_info = {'data': {'export': export_string, 'name': self.name}} - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) - tree = conf.format_dom() - self._assertFileTypeEquals(tree, file_path) + libvirt_driver.connect_volume(connection_info, self.disk_info) libvirt_driver.disconnect_volume(connection_info, "vde") + device_path = os.path.join(export_mnt_base, + connection_info['data']['name']) + self.assertEqual(device_path, connection_info['data']['device_path']) expected_commands = [ ('mkdir', '-p', export_mnt_base), ('mount', '-t', 'nfs', export_string, export_mnt_base), @@ -794,7 +781,8 @@ Setting up iSCSI targets: unused file_path = os.path.join(export_mnt_base, self.name) connection_info = {'data': {'export': export_string, - 'name': self.name}} + 'name': self.name, + 'device_path': file_path}} conf = libvirt_driver.get_config(connection_info, self.disk_info) tree = conf.format_dom() self._assertFileTypeEquals(tree, file_path) @@ -810,13 +798,10 @@ Setting up iSCSI targets: unused export_string = '192.168.1.1:/nfs/share1' export_mnt_base = os.path.join(mnt_base, utils.get_hash_str(export_string)) - file_path = os.path.join(export_mnt_base, self.name) connection_info = {'data': {'export': export_string, 'name': self.name}} - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) - tree = conf.format_dom() - self._assertFileTypeEquals(tree, file_path) + libvirt_driver.connect_volume(connection_info, self.disk_info) libvirt_driver.disconnect_volume(connection_info, "vde") expected_commands = [ @@ -835,14 +820,11 @@ Setting up iSCSI targets: unused options = '-o intr,nfsvers=3' export_mnt_base = os.path.join(mnt_base, utils.get_hash_str(export_string)) - file_path = os.path.join(export_mnt_base, self.name) connection_info = {'data': {'export': export_string, 'name': self.name, 'options': options}} - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) - tree = conf.format_dom() - self._assertFileTypeEquals(tree, file_path) + libvirt_driver.connect_volume(connection_info, self.disk_info) libvirt_driver.disconnect_volume(connection_info, "vde") expected_commands = [ @@ -854,27 +836,31 @@ Setting up iSCSI targets: unused self.assertEqual(expected_commands, self.executes) def aoe_connection(self, shelf, lun): + aoedev = 'e%s.%s' % (shelf, lun) + aoedevpath = '/dev/etherd/%s' % (aoedev) return { 'driver_volume_type': 'aoe', 'data': { 'target_shelf': shelf, 'target_lun': lun, + 'device_path': aoedevpath } } - def test_libvirt_aoe_driver(self): - # NOTE(jbr_) exists is to make driver assume connecting worked - self.stubs.Set(os.path, 'exists', lambda x: True) + @mock.patch('os.path.exists', return_value=True) + def test_libvirt_aoe_driver(self, exists): libvirt_driver = volume.LibvirtAOEVolumeDriver(self.fake_conn) shelf = '100' lun = '1' connection_info = self.aoe_connection(shelf, lun) - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) - tree = conf.format_dom() - aoedevpath = '/dev/etherd/e%s.%s' % (shelf, lun) - self.assertEqual(tree.get('type'), 'block') - self.assertEqual(tree.find('./source').get('dev'), aoedevpath) + aoedev = 'e%s.%s' % (shelf, lun) + aoedevpath = '/dev/etherd/%s' % (aoedev) + libvirt_driver.connect_volume(connection_info, self.disk_info) + exists.assert_called_with(aoedevpath) libvirt_driver.disconnect_volume(connection_info, "vde") + self.assertEqual(aoedevpath, connection_info['data']['device_path']) + expected_commands = [('aoe-revalidate', aoedev)] + self.assertEqual(expected_commands, self.executes) def test_libvirt_aoe_driver_get_config(self): libvirt_driver = volume.LibvirtAOEVolumeDriver(self.fake_conn) @@ -897,15 +883,15 @@ Setting up iSCSI targets: unused export_string = '192.168.1.1:/volume-00001' export_mnt_base = os.path.join(mnt_base, utils.get_hash_str(export_string)) - file_path = os.path.join(export_mnt_base, self.name) connection_info = {'data': {'export': export_string, 'name': self.name}} - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) - tree = conf.format_dom() - self._assertFileTypeEquals(tree, file_path) + libvirt_driver.connect_volume(connection_info, self.disk_info) libvirt_driver.disconnect_volume(connection_info, "vde") + device_path = os.path.join(export_mnt_base, + connection_info['data']['name']) + self.assertEqual(device_path, connection_info['data']['device_path']) expected_commands = [ ('mkdir', '-p', export_mnt_base), ('mount', '-t', 'glusterfs', export_string, export_mnt_base), @@ -922,13 +908,25 @@ Setting up iSCSI targets: unused utils.get_hash_str(export_string)) file_path = os.path.join(export_mnt_base, self.name) + # Test default format - raw connection_info = {'data': {'export': export_string, - 'name': self.name}} + 'name': self.name, + 'device_path': file_path}} conf = libvirt_driver.get_config(connection_info, self.disk_info) tree = conf.format_dom() self._assertFileTypeEquals(tree, file_path) self.assertEqual('raw', tree.find('./driver').get('type')) + # Test specified format - qcow2 + connection_info = {'data': {'export': export_string, + 'name': self.name, + 'device_path': file_path, + 'format': 'qcow2'}} + conf = libvirt_driver.get_config(connection_info, self.disk_info) + tree = conf.format_dom() + self._assertFileTypeEquals(tree, file_path) + self.assertEqual('qcow2', tree.find('./driver').get('type')) + def test_libvirt_glusterfs_driver_already_mounted(self): mnt_base = '/mnt' self.flags(glusterfs_mount_point_base=mnt_base, group='libvirt') @@ -937,13 +935,10 @@ Setting up iSCSI targets: unused export_string = '192.168.1.1:/volume-00001' export_mnt_base = os.path.join(mnt_base, utils.get_hash_str(export_string)) - file_path = os.path.join(export_mnt_base, self.name) connection_info = {'data': {'export': export_string, 'name': self.name}} - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) - tree = conf.format_dom() - self._assertFileTypeEquals(tree, file_path) + libvirt_driver.connect_volume(connection_info, self.disk_info) libvirt_driver.disconnect_volume(connection_info, "vde") expected_commands = [ @@ -952,27 +947,6 @@ Setting up iSCSI targets: unused ('umount', export_mnt_base)] self.assertEqual(self.executes, expected_commands) - def test_libvirt_glusterfs_driver_qcow2(self): - libvirt_driver = volume.LibvirtGlusterfsVolumeDriver(self.fake_conn) - self.stubs.Set(libvirt_utils, 'is_mounted', lambda x, d: False) - export_string = '192.168.1.1:/volume-00001' - name = 'volume-00001' - format = 'qcow2' - - connection_info = {'data': {'export': export_string, - 'name': name, - 'format': format}} - disk_info = { - "bus": "virtio", - "dev": "vde", - "type": "disk", - } - conf = libvirt_driver.connect_volume(connection_info, disk_info) - tree = conf.format_dom() - self.assertEqual(tree.get('type'), 'file') - self.assertEqual(tree.find('./driver').get('type'), 'qcow2') - libvirt_driver.disconnect_volume(connection_info, "vde") - def test_libvirt_glusterfs_driver_with_opts(self): mnt_base = '/mnt' self.flags(glusterfs_mount_point_base=mnt_base, group='libvirt') @@ -983,14 +957,11 @@ Setting up iSCSI targets: unused options = '-o backupvolfile-server=192.168.1.2' export_mnt_base = os.path.join(mnt_base, utils.get_hash_str(export_string)) - file_path = os.path.join(export_mnt_base, self.name) connection_info = {'data': {'export': export_string, 'name': self.name, 'options': options}} - conf = libvirt_driver.connect_volume(connection_info, self.disk_info) - tree = conf.format_dom() - self._assertFileTypeEquals(tree, file_path) + libvirt_driver.connect_volume(connection_info, self.disk_info) libvirt_driver.disconnect_volume(connection_info, "vde") expected_commands = [ @@ -1017,7 +988,8 @@ Setting up iSCSI targets: unused "bus": "virtio", } - conf = libvirt_driver.connect_volume(connection_info, disk_info) + libvirt_driver.connect_volume(connection_info, disk_info) + conf = libvirt_driver.get_config(connection_info, disk_info) tree = conf.format_dom() self.assertEqual(tree.get('type'), 'network') self.assertEqual(tree.find('./driver').get('type'), 'raw') @@ -1066,16 +1038,12 @@ Setting up iSCSI targets: unused connection_info = self.fibrechan_connection(self.vol, self.location, wwn) mount_device = "vde" - conf = libvirt_driver.connect_volume(connection_info, - self.disk_info) - self.assertEqual('1234567890', - connection_info['data']['multipath_id']) - tree = conf.format_dom() - self.assertEqual('block', tree.get('type')) - self.assertEqual(multipath_devname, - tree.find('./source').get('dev')) + libvirt_driver.connect_volume(connection_info, self.disk_info) + # Test the scenario where multipath_id is returned libvirt_driver.disconnect_volume(connection_info, mount_device) + self.assertEqual(multipath_devname, + connection_info['data']['device_path']) expected_commands = [] self.assertEqual(expected_commands, self.executes) # Test the scenario where multipath_id is not returned @@ -1150,7 +1118,13 @@ Setting up iSCSI targets: unused scality_sofs_mount_point=TEST_MOUNT, group='libvirt') driver = volume.LibvirtScalityVolumeDriver(self.fake_conn) - conf = driver.connect_volume(TEST_CONN_INFO, self.disk_info) + driver.connect_volume(TEST_CONN_INFO, self.disk_info) + device_path = os.path.join(TEST_MOUNT, + TEST_CONN_INFO['data']['sofs_path']) + self.assertEqual(device_path, + TEST_CONN_INFO['data']['device_path']) + + conf = driver.get_config(TEST_CONN_INFO, self.disk_info) tree = conf.format_dom() self._assertFileTypeEquals(tree, TEST_VOLPATH) diff --git a/nova/tests/virt/test_virt_drivers.py b/nova/tests/virt/test_virt_drivers.py index 097db05b1ca1..3a50aba66c29 100644 --- a/nova/tests/virt/test_virt_drivers.py +++ b/nova/tests/virt/test_virt_drivers.py @@ -429,6 +429,7 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase): connection_info = { "driver_volume_type": "fake", "serial": "fake_serial", + "data": {} } self.assertIsNone( self.connection.attach_volume(None, connection_info, instance_ref, @@ -441,12 +442,15 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase): def test_swap_volume(self): instance_ref, network_info = self._get_running_instance() self.assertIsNone( - self.connection.attach_volume(None, {'driver_volume_type': 'fake'}, + self.connection.attach_volume(None, {'driver_volume_type': 'fake', + 'data': {}}, instance_ref, '/dev/sda')) self.assertIsNone( - self.connection.swap_volume({'driver_volume_type': 'fake'}, - {'driver_volume_type': 'fake'}, + self.connection.swap_volume({'driver_volume_type': 'fake', + 'data': {}}, + {'driver_volume_type': 'fake', + 'data': {}}, instance_ref, '/dev/sda', 2)) @@ -456,6 +460,7 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase): connection_info = { "driver_volume_type": "fake", "serial": "fake_serial", + "data": {} } self.connection.power_off(instance_ref) self.connection.attach_volume(None, connection_info, instance_ref, @@ -480,7 +485,7 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase): ]) } bdm['block_device_mapping'][0]['connection_info'] = ( - {'driver_volume_type': 'fake'}) + {'driver_volume_type': 'fake', 'data': {}}) with mock.patch.object( driver_block_device.DriverVolumeBlockDevice, 'save'): self.connection.power_on( diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index f89b8a5e4423..7e0cb3c1215a 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -1305,7 +1305,7 @@ class LibvirtDriver(driver.ComputeDriver): if driver_type not in self.volume_drivers: raise exception.VolumeDriverNotFound(driver_type=driver_type) driver = self.volume_drivers[driver_type] - return driver.connect_volume(connection_info, disk_info) + driver.connect_volume(connection_info, disk_info) def _disconnect_volume(self, connection_info, disk_dev): driver_type = connection_info.get('driver_volume_type') @@ -1358,7 +1358,8 @@ class LibvirtDriver(driver.ComputeDriver): raise exception.Invalid(msg) disk_info = blockinfo.get_info_from_bdm(CONF.libvirt.virt_type, bdm) - conf = self._connect_volume(connection_info, disk_info) + self._connect_volume(connection_info, disk_info) + conf = self._get_volume_config(connection_info, disk_info) self._set_cache_mode(conf) try: @@ -1370,10 +1371,6 @@ class LibvirtDriver(driver.ComputeDriver): if state in (power_state.RUNNING, power_state.PAUSED): flags |= libvirt.VIR_DOMAIN_AFFECT_LIVE - # cache device_path in connection_info -- required by encryptors - if 'data' in connection_info: - connection_info['data']['device_path'] = conf.source_path - if encryption: encryptor = self._get_volume_encryptor(connection_info, encryption) @@ -1450,7 +1447,8 @@ class LibvirtDriver(driver.ComputeDriver): CONF.libvirt.virt_type, disk_dev), 'type': 'disk', } - conf = self._connect_volume(new_connection_info, disk_info) + self._connect_volume(new_connection_info, disk_info) + conf = self._get_volume_config(new_connection_info, disk_info) if not conf.source_path: self._disconnect_volume(new_connection_info, disk_dev) raise NotImplementedError(_("Swap only supports host devices")) @@ -3465,7 +3463,8 @@ class LibvirtDriver(driver.ComputeDriver): connection_info = vol['connection_info'] vol_dev = block_device.prepend_dev(vol['mount_device']) info = disk_mapping[vol_dev] - cfg = self._connect_volume(connection_info, info) + self._connect_volume(connection_info, info) + cfg = self._get_volume_config(connection_info, info) devices.append(cfg) vol['connection_info'] = connection_info vol.save(nova_context.get_admin_context()) @@ -4348,15 +4347,6 @@ class LibvirtDriver(driver.ComputeDriver): for vol in block_device_mapping: connection_info = vol['connection_info'] - info = blockinfo.get_info_from_bdm( - CONF.libvirt.virt_type, vol) - conf = self._connect_volume(connection_info, info) - - # cache device_path in connection_info -- required by encryptors - if 'data' in connection_info: - connection_info['data']['device_path'] = conf.source_path - vol['connection_info'] = connection_info - vol.save(context) if (not reboot and 'data' in connection_info and 'volume_id' in connection_info['data']): diff --git a/nova/virt/libvirt/volume.py b/nova/virt/libvirt/volume.py index a8913c1bb7ec..3d20f2d7d547 100644 --- a/nova/virt/libvirt/volume.py +++ b/nova/virt/libvirt/volume.py @@ -148,7 +148,7 @@ class LibvirtBaseVolumeDriver(object): def connect_volume(self, connection_info, disk_info): """Connect the volume. Returns xml for libvirt.""" - return self.get_config(connection_info, disk_info) + pass def disconnect_volume(self, connection_info, disk_dev): """Disconnect the volume.""" @@ -264,7 +264,7 @@ class LibvirtISCSIVolumeDriver(LibvirtBaseVolumeDriver): conf = super(LibvirtISCSIVolumeDriver, self).get_config(connection_info, disk_info) conf.source_type = "block" - conf.source_path = connection_info['data']['host_device'] + conf.source_path = connection_info['data']['device_path'] return conf @utils.synchronized('connect_volume') @@ -335,8 +335,7 @@ class LibvirtISCSIVolumeDriver(LibvirtBaseVolumeDriver): if multipath_device is not None: host_device = multipath_device - connection_info['data']['host_device'] = host_device - return self.get_config(connection_info, disk_info) + connection_info['data']['device_path'] = host_device @utils.synchronized('connect_volume') def disconnect_volume(self, connection_info, disk_dev): @@ -654,16 +653,19 @@ class LibvirtNFSVolumeDriver(LibvirtBaseVolumeDriver): super(LibvirtNFSVolumeDriver, self).__init__(connection, is_block_dev=False) + def _get_device_path(self, connection_info): + path = os.path.join(CONF.libvirt.nfs_mount_point_base, + utils.get_hash_str(connection_info['data']['export'])) + path = os.path.join(path, connection_info['data']['name']) + return path + def get_config(self, connection_info, disk_info): """Returns xml for libvirt.""" conf = super(LibvirtNFSVolumeDriver, self).get_config(connection_info, disk_info) - path = os.path.join(CONF.libvirt.nfs_mount_point_base, - utils.get_hash_str(connection_info['data']['export'])) - path = os.path.join(path, connection_info['data']['name']) conf.source_type = 'file' - conf.source_path = path + conf.source_path = connection_info['data']['device_path'] conf.driver_format = connection_info['data'].get('format', 'raw') return conf @@ -672,7 +674,8 @@ class LibvirtNFSVolumeDriver(LibvirtBaseVolumeDriver): options = connection_info['data'].get('options') self._ensure_mounted(connection_info['data']['export'], options) - return self.get_config(connection_info, disk_info) + connection_info['data']['device_path'] = \ + self._get_device_path(connection_info) def disconnect_volume(self, connection_info, disk_dev): """Disconnect the volume.""" @@ -739,18 +742,20 @@ class LibvirtAOEVolumeDriver(LibvirtBaseVolumeDriver): run_as_root=True, check_exit_code=0) return (out, err) + def _get_device_path(self, connection_info): + shelf = connection_info['data']['target_shelf'] + lun = connection_info['data']['target_lun'] + aoedev = 'e%s.%s' % (shelf, lun) + aoedevpath = '/dev/etherd/%s' % (aoedev) + return aoedevpath + def get_config(self, connection_info, disk_info): """Returns xml for libvirt.""" conf = super(LibvirtAOEVolumeDriver, self).get_config(connection_info, disk_info) - shelf = connection_info['data']['target_shelf'] - lun = connection_info['data']['target_lun'] - aoedev = 'e%s.%s' % (shelf, lun) - aoedevpath = '/dev/etherd/%s' % (aoedev) - conf.source_type = "block" - conf.source_path = aoedevpath + conf.source_path = connection_info['data']['device_path'] return conf def connect_volume(self, connection_info, mount_device): @@ -794,7 +799,8 @@ class LibvirtAOEVolumeDriver(LibvirtBaseVolumeDriver): {'aoedevpath': aoedevpath, 'tries': tries}) - return self.get_config(connection_info, mount_device) + connection_info['data']['device_path'] = \ + self._get_device_path(connection_info) class LibvirtGlusterfsVolumeDriver(LibvirtBaseVolumeDriver): @@ -805,6 +811,12 @@ class LibvirtGlusterfsVolumeDriver(LibvirtBaseVolumeDriver): super(LibvirtGlusterfsVolumeDriver, self).__init__(connection, is_block_dev=False) + def _get_device_path(self, connection_info): + path = os.path.join(CONF.libvirt.glusterfs_mount_point_base, + utils.get_hash_str(connection_info['data']['export'])) + path = os.path.join(path, connection_info['data']['name']) + return path + def get_config(self, connection_info, disk_info): """Returns xml for libvirt.""" conf = super(LibvirtGlusterfsVolumeDriver, @@ -822,11 +834,8 @@ class LibvirtGlusterfsVolumeDriver(LibvirtBaseVolumeDriver): conf.source_hosts = [source_host] conf.source_name = '%s/%s' % (vol_name, data['name']) else: - path = os.path.join(CONF.libvirt.glusterfs_mount_point_base, - utils.get_hash_str(data['export'])) - path = os.path.join(path, data['name']) conf.source_type = 'file' - conf.source_path = path + conf.source_path = connection_info['data']['device_path'] conf.driver_format = connection_info['data'].get('format', 'raw') @@ -837,8 +846,8 @@ class LibvirtGlusterfsVolumeDriver(LibvirtBaseVolumeDriver): if 'gluster' not in CONF.libvirt.qemu_allowed_storage_drivers: self._ensure_mounted(data['export'], data.get('options')) - - return self.get_config(connection_info, mount_device) + connection_info['data']['device_path'] = \ + self._get_device_path(connection_info) def disconnect_volume(self, connection_info, disk_dev): """Disconnect the volume.""" @@ -1020,8 +1029,6 @@ class LibvirtFibreChannelVolumeDriver(LibvirtBaseVolumeDriver): connection_info['data']['device_path'] = device_path connection_info['data']['devices'] = [device_info] - return self.get_config(connection_info, disk_info) - @utils.synchronized('connect_volume') def disconnect_volume(self, connection_info, mount_device): """Detach the volume from instance_name.""" @@ -1059,14 +1066,17 @@ class LibvirtScalityVolumeDriver(LibvirtBaseVolumeDriver): super(LibvirtScalityVolumeDriver, self).__init__(connection, is_block_dev=False) + def _get_device_path(self, connection_info): + path = os.path.join(CONF.libvirt.scality_sofs_mount_point, + connection_info['data']['sofs_path']) + return path + def get_config(self, connection_info, disk_info): """Returns xml for libvirt.""" conf = super(LibvirtScalityVolumeDriver, self).get_config(connection_info, disk_info) - path = os.path.join(CONF.libvirt.scality_sofs_mount_point, - connection_info['data']['sofs_path']) conf.source_type = 'file' - conf.source_path = path + conf.source_path = connection_info['data']['device_path'] # The default driver cache policy is 'none', and this causes # qemu/kvm to open the volume file with O_DIRECT, which is @@ -1081,7 +1091,8 @@ class LibvirtScalityVolumeDriver(LibvirtBaseVolumeDriver): self._check_prerequisites() self._mount_sofs() - return self.get_config(connection_info, disk_info) + connection_info['data']['device_path'] = \ + self._get_device_path(connection_info) def _check_prerequisites(self): """Sanity checks before attempting to mount SOFS."""