libvirt: persist lxc attached volumes across reboots and power down

Currently, attached volumes to a LXC instance will be lost, when
hard rebooting or powering it down.
Adjusting the get_storage_config() to include LXC volumes in the
domain configuration.
The change will add all volumes to the instance config, a part from
the root device mapping.
When (re)creating a LXC instance, get_bdms_to_connect() generator
from block_device module, will be used to exclude the root device
mapping for a domain configuration.

Co-authored-by: Sam Morrison<sorrison@gmail.com>
Closes-Bug: #1269990
Change-Id: I0aa227ede5fca065c6da15506d8cc4391d993e20
This commit is contained in:
Vladik Romanovsky 2014-06-27 10:59:57 -04:00
parent 65688f4751
commit cc134ab2dc
2 changed files with 52 additions and 11 deletions

View File

@ -1302,6 +1302,46 @@ class LibvirtConnTestCase(test.TestCase,
self.assertTrue(info['block_device_mapping'][0].save.called)
self.assertTrue(info['block_device_mapping'][1].save.called)
def test_get_guest_config_lxc_with_attached_volume(self):
self.flags(virt_type='lxc', group='libvirt')
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
instance_ref = db.instance_create(self.context, self.test_instance)
conn_info = {'driver_volume_type': 'fake'}
info = {'block_device_mapping': driver_block_device.convert_volumes([
fake_block_device.FakeDbBlockDeviceDict(
{'id': 1,
'source_type': 'volume', 'destination_type': 'volume',
'boot_index': 0}),
fake_block_device.FakeDbBlockDeviceDict(
{'id': 2,
'source_type': 'volume', 'destination_type': 'volume',
}),
fake_block_device.FakeDbBlockDeviceDict(
{'id': 3,
'source_type': 'volume', 'destination_type': 'volume',
}),
])}
info['block_device_mapping'][0]['connection_info'] = conn_info
info['block_device_mapping'][1]['connection_info'] = conn_info
info['block_device_mapping'][2]['connection_info'] = conn_info
info['block_device_mapping'][0]['mount_device'] = '/dev/vda'
info['block_device_mapping'][1]['mount_device'] = '/dev/vdc'
info['block_device_mapping'][2]['mount_device'] = '/dev/vdd'
with mock.patch.object(
driver_block_device.DriverVolumeBlockDevice, 'save'):
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
instance_ref, info)
cfg = conn._get_guest_config(instance_ref, [], {}, disk_info,
None, info)
self.assertIsInstance(cfg.devices[1],
vconfig.LibvirtConfigGuestDisk)
self.assertEqual(cfg.devices[1].target_dev, 'vdc')
self.assertIsInstance(cfg.devices[2],
vconfig.LibvirtConfigGuestDisk)
self.assertEqual(cfg.devices[2].target_dev, 'vdd')
def test_get_guest_config_with_configdrive(self):
# It's necessary to check if the architecture is power, because
# power doesn't have support to ide, and so libvirt translate

View File

@ -3041,8 +3041,8 @@ class LibvirtDriver(driver.ComputeDriver):
block_device_mapping = driver.block_device_info_get_mapping(
block_device_info)
if CONF.libvirt.virt_type == "lxc":
mount_rootfs = CONF.libvirt.virt_type == "lxc"
if mount_rootfs:
fs = vconfig.LibvirtConfigGuestFilesys()
fs.source_type = "mount"
fs.source_dir = os.path.join(
@ -3099,15 +3099,6 @@ class LibvirtDriver(driver.ComputeDriver):
block_device.prepend_dev(diskswap.target_dev))
instance.save()
for vol in block_device_mapping:
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)
devices.append(cfg)
vol['connection_info'] = connection_info
vol.save()
if 'disk.config' in disk_mapping:
diskconfig = self._get_guest_disk_config(instance,
'disk.config',
@ -3116,6 +3107,16 @@ class LibvirtDriver(driver.ComputeDriver):
'raw')
devices.append(diskconfig)
for vol in block_device.get_bdms_to_connect(block_device_mapping,
mount_rootfs):
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)
devices.append(cfg)
vol['connection_info'] = connection_info
vol.save(nova_context.get_admin_context())
for d in devices:
self._set_cache_mode(d)