Merge "libvirt: start lxc from block device"
This commit is contained in:
commit
d946915e06
|
@ -2175,7 +2175,6 @@ class LibvirtConnTestCase(test.TestCase,
|
||||||
"""
|
"""
|
||||||
self.flags(virt_type='lxc', group='libvirt')
|
self.flags(virt_type='lxc', group='libvirt')
|
||||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
mock_domain = mock.MagicMock()
|
|
||||||
mock_instance = mock.MagicMock()
|
mock_instance = mock.MagicMock()
|
||||||
mock_get_inst_path.return_value = '/tmp/'
|
mock_get_inst_path.return_value = '/tmp/'
|
||||||
mock_image_backend = mock.MagicMock()
|
mock_image_backend = mock.MagicMock()
|
||||||
|
@ -2185,14 +2184,22 @@ class LibvirtConnTestCase(test.TestCase,
|
||||||
conn.image_backend.image.return_value = mock_image
|
conn.image_backend.image.return_value = mock_image
|
||||||
mock_setup_container.return_value = '/dev/nbd0'
|
mock_setup_container.return_value = '/dev/nbd0'
|
||||||
mock_get_info.side_effect = exception.InstanceNotFound(
|
mock_get_info.side_effect = exception.InstanceNotFound(
|
||||||
instance_id='foo')
|
instance_id='foo')
|
||||||
|
conn._conn.defineXML = mock.Mock()
|
||||||
|
conn._conn.defineXML.side_effect = ValueError('somethingbad')
|
||||||
|
with contextlib.nested(
|
||||||
|
mock.patch.object(conn, '_is_booted_from_volume',
|
||||||
|
return_value=False),
|
||||||
|
mock.patch.object(conn, 'plug_vifs'),
|
||||||
|
mock.patch.object(conn, 'firewall_driver'),
|
||||||
|
mock.patch.object(conn, 'cleanup')):
|
||||||
|
self.assertRaises(ValueError,
|
||||||
|
conn._create_domain_and_network,
|
||||||
|
self.context,
|
||||||
|
'xml',
|
||||||
|
mock_instance, None)
|
||||||
|
|
||||||
mock_domain.createWithFlags.side_effect = ValueError('somethingbad')
|
mock_teardown.assert_called_with(container_dir='/tmp/rootfs')
|
||||||
|
|
||||||
self.assertRaises(ValueError, conn._create_domain, domain=mock_domain,
|
|
||||||
instance=mock_instance)
|
|
||||||
|
|
||||||
mock_teardown.assert_called_with(container_dir='/tmp/rootfs')
|
|
||||||
|
|
||||||
def test_video_driver_flavor_limit_not_set(self):
|
def test_video_driver_flavor_limit_not_set(self):
|
||||||
self.flags(virt_type='kvm', group='libvirt')
|
self.flags(virt_type='kvm', group='libvirt')
|
||||||
|
@ -6000,6 +6007,95 @@ class LibvirtConnTestCase(test.TestCase,
|
||||||
self.assertTrue(self.cache_called_for_disk)
|
self.assertTrue(self.cache_called_for_disk)
|
||||||
db.instance_destroy(self.context, instance['uuid'])
|
db.instance_destroy(self.context, instance['uuid'])
|
||||||
|
|
||||||
|
def test_start_lxc_from_volume(self):
|
||||||
|
self.flags(virt_type="lxc",
|
||||||
|
group='libvirt')
|
||||||
|
|
||||||
|
def check_setup_container(path, container_dir=None, use_cow=False):
|
||||||
|
self.assertEqual(path, '/dev/path/to/dev')
|
||||||
|
self.assertTrue(use_cow)
|
||||||
|
return '/dev/nbd1'
|
||||||
|
|
||||||
|
bdm = {
|
||||||
|
'guest_format': None,
|
||||||
|
'boot_index': 0,
|
||||||
|
'mount_device': '/dev/sda',
|
||||||
|
'connection_info': {
|
||||||
|
'driver_volume_type': 'iscsi',
|
||||||
|
'serial': 'afc1',
|
||||||
|
'data': {
|
||||||
|
'access_mode': 'rw',
|
||||||
|
'target_discovered': False,
|
||||||
|
'encrypted': False,
|
||||||
|
'qos_specs': None,
|
||||||
|
'target_iqn': 'iqn: volume-afc1',
|
||||||
|
'target_portal': 'ip: 3260',
|
||||||
|
'volume_id': 'afc1',
|
||||||
|
'target_lun': 1,
|
||||||
|
'auth_password': 'uj',
|
||||||
|
'auth_username': '47',
|
||||||
|
'auth_method': 'CHAP'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'disk_bus': 'scsi',
|
||||||
|
'device_type': 'disk',
|
||||||
|
'delete_on_termination': False
|
||||||
|
}
|
||||||
|
|
||||||
|
def _get(key, opt=None):
|
||||||
|
return bdm.get(key, opt)
|
||||||
|
|
||||||
|
def getitem(key):
|
||||||
|
return bdm[key]
|
||||||
|
|
||||||
|
def setitem(key, val):
|
||||||
|
bdm[key] = val
|
||||||
|
|
||||||
|
bdm_mock = mock.MagicMock()
|
||||||
|
bdm_mock.__getitem__.side_effect = getitem
|
||||||
|
bdm_mock.__setitem__.side_effect = setitem
|
||||||
|
bdm_mock.get = _get
|
||||||
|
|
||||||
|
disk_mock = mock.MagicMock()
|
||||||
|
disk_mock.source_path = '/dev/path/to/dev'
|
||||||
|
|
||||||
|
block_device_info = {'block_device_mapping': [bdm_mock],
|
||||||
|
'root_device_name': '/dev/sda'}
|
||||||
|
|
||||||
|
# Volume-backed instance created without image
|
||||||
|
instance_ref = self.test_instance
|
||||||
|
instance_ref['image_ref'] = ''
|
||||||
|
instance_ref['root_device_name'] = '/dev/sda'
|
||||||
|
instance_ref['ephemeral_gb'] = 0
|
||||||
|
instance_ref['uuid'] = uuidutils.generate_uuid()
|
||||||
|
instance_ref['system_metadata']['image_disk_format'] = 'qcow2'
|
||||||
|
instance = db.instance_create(self.context, instance_ref)
|
||||||
|
self.addCleanup(db.instance_destroy, self.context, instance['uuid'])
|
||||||
|
inst_obj = objects.Instance.get_by_uuid(self.context, instance['uuid'])
|
||||||
|
|
||||||
|
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||||
|
with contextlib.nested(
|
||||||
|
mock.patch.object(conn, '_create_images_and_backing'),
|
||||||
|
mock.patch.object(conn, 'plug_vifs'),
|
||||||
|
mock.patch.object(conn.firewall_driver, 'setup_basic_filtering'),
|
||||||
|
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',
|
||||||
|
return_value=disk_mock),
|
||||||
|
mock.patch.object(conn, 'get_info',
|
||||||
|
return_value={'state': power_state.RUNNING}),
|
||||||
|
mock.patch('nova.virt.disk.api.setup_container',
|
||||||
|
side_effect=check_setup_container),
|
||||||
|
mock.patch('nova.virt.disk.api.teardown_container'),):
|
||||||
|
|
||||||
|
conn.spawn(self.context, inst_obj, None, [], None,
|
||||||
|
network_info=[],
|
||||||
|
block_device_info=block_device_info)
|
||||||
|
self.assertEqual('/dev/nbd1',
|
||||||
|
inst_obj.system_metadata.get(
|
||||||
|
'rootfs_device_name'))
|
||||||
|
|
||||||
def test_spawn_with_pci_devices(self):
|
def test_spawn_with_pci_devices(self):
|
||||||
def fake_none(*args, **kwargs):
|
def fake_none(*args, **kwargs):
|
||||||
return None
|
return None
|
||||||
|
@ -8487,7 +8583,6 @@ Active: 8381604 kB
|
||||||
mock_setup_container, mock_get_info, mock_clean):
|
mock_setup_container, mock_get_info, mock_clean):
|
||||||
self.flags(virt_type='lxc', group='libvirt')
|
self.flags(virt_type='lxc', group='libvirt')
|
||||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
mock_domain = mock.MagicMock()
|
|
||||||
mock_instance = mock.MagicMock()
|
mock_instance = mock.MagicMock()
|
||||||
inst_sys_meta = dict()
|
inst_sys_meta = dict()
|
||||||
mock_instance.system_metadata = inst_sys_meta
|
mock_instance.system_metadata = inst_sys_meta
|
||||||
|
@ -8500,13 +8595,20 @@ Active: 8381604 kB
|
||||||
mock_setup_container.return_value = '/dev/nbd0'
|
mock_setup_container.return_value = '/dev/nbd0'
|
||||||
mock_get_info.return_value = {'state': power_state.RUNNING}
|
mock_get_info.return_value = {'state': power_state.RUNNING}
|
||||||
|
|
||||||
domain = conn._create_domain(domain=mock_domain,
|
with contextlib.nested(
|
||||||
instance=mock_instance)
|
mock.patch.object(conn, '_create_images_and_backing'),
|
||||||
|
mock.patch.object(conn, '_is_booted_from_volume',
|
||||||
|
return_value=False),
|
||||||
|
mock.patch.object(conn, '_create_domain'),
|
||||||
|
mock.patch.object(conn, 'plug_vifs'),
|
||||||
|
mock.patch.object(conn.firewall_driver, 'setup_basic_filtering'),
|
||||||
|
mock.patch.object(conn.firewall_driver, 'prepare_instance_filter'),
|
||||||
|
mock.patch.object(conn.firewall_driver, 'apply_instance_filter')):
|
||||||
|
conn._create_domain_and_network(self.context, 'xml',
|
||||||
|
mock_instance, [])
|
||||||
|
|
||||||
self.assertEqual(mock_domain, domain)
|
|
||||||
self.assertEqual('/dev/nbd0', inst_sys_meta['rootfs_device_name'])
|
self.assertEqual('/dev/nbd0', inst_sys_meta['rootfs_device_name'])
|
||||||
mock_instance.save.assert_has_calls([mock.call()])
|
mock_instance.save.assert_has_calls([mock.call()])
|
||||||
mock_domain.createWithFlags.assert_has_calls([mock.call(0)])
|
|
||||||
mock_get_inst_path.assert_has_calls([mock.call(mock_instance)])
|
mock_get_inst_path.assert_has_calls([mock.call(mock_instance)])
|
||||||
mock_ensure_tree.assert_has_calls([mock.call('/tmp/rootfs')])
|
mock_ensure_tree.assert_has_calls([mock.call('/tmp/rootfs')])
|
||||||
conn.image_backend.image.assert_has_calls([mock.call(mock_instance,
|
conn.image_backend.image.assert_has_calls([mock.call(mock_instance,
|
||||||
|
@ -8542,7 +8644,6 @@ Active: 8381604 kB
|
||||||
self.assertEqual(100, id_maps[1].count)
|
self.assertEqual(100, id_maps[1].count)
|
||||||
|
|
||||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
mock_domain = mock.MagicMock()
|
|
||||||
mock_instance = mock.MagicMock()
|
mock_instance = mock.MagicMock()
|
||||||
inst_sys_meta = dict()
|
inst_sys_meta = dict()
|
||||||
mock_instance.system_metadata = inst_sys_meta
|
mock_instance.system_metadata = inst_sys_meta
|
||||||
|
@ -8556,13 +8657,20 @@ Active: 8381604 kB
|
||||||
mock_chown.side_effect = chown_side_effect
|
mock_chown.side_effect = chown_side_effect
|
||||||
mock_get_info.return_value = {'state': power_state.RUNNING}
|
mock_get_info.return_value = {'state': power_state.RUNNING}
|
||||||
|
|
||||||
domain = conn._create_domain(domain=mock_domain,
|
with contextlib.nested(
|
||||||
instance=mock_instance)
|
mock.patch.object(conn, '_create_images_and_backing'),
|
||||||
|
mock.patch.object(conn, '_is_booted_from_volume',
|
||||||
|
return_value=False),
|
||||||
|
mock.patch.object(conn, '_create_domain'),
|
||||||
|
mock.patch.object(conn, 'plug_vifs'),
|
||||||
|
mock.patch.object(conn.firewall_driver, 'setup_basic_filtering'),
|
||||||
|
mock.patch.object(conn.firewall_driver, 'prepare_instance_filter'),
|
||||||
|
mock.patch.object(conn.firewall_driver, 'apply_instance_filter')):
|
||||||
|
conn._create_domain_and_network(self.context, 'xml',
|
||||||
|
mock_instance, [])
|
||||||
|
|
||||||
self.assertEqual(mock_domain, domain)
|
|
||||||
self.assertEqual('/dev/nbd0', inst_sys_meta['rootfs_device_name'])
|
self.assertEqual('/dev/nbd0', inst_sys_meta['rootfs_device_name'])
|
||||||
mock_instance.save.assert_has_calls([mock.call()])
|
mock_instance.save.assert_has_calls([mock.call()])
|
||||||
mock_domain.createWithFlags.assert_has_calls([mock.call(0)])
|
|
||||||
mock_get_inst_path.assert_has_calls([mock.call(mock_instance)])
|
mock_get_inst_path.assert_has_calls([mock.call(mock_instance)])
|
||||||
mock_ensure_tree.assert_has_calls([mock.call('/tmp/rootfs')])
|
mock_ensure_tree.assert_has_calls([mock.call('/tmp/rootfs')])
|
||||||
conn.image_backend.image.assert_has_calls([mock.call(mock_instance,
|
conn.image_backend.image.assert_has_calls([mock.call(mock_instance,
|
||||||
|
@ -8585,7 +8693,6 @@ Active: 8381604 kB
|
||||||
mock_get_info, mock_teardown):
|
mock_get_info, mock_teardown):
|
||||||
self.flags(virt_type='lxc', group='libvirt')
|
self.flags(virt_type='lxc', group='libvirt')
|
||||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
mock_domain = mock.MagicMock()
|
|
||||||
mock_instance = mock.MagicMock()
|
mock_instance = mock.MagicMock()
|
||||||
inst_sys_meta = dict()
|
inst_sys_meta = dict()
|
||||||
mock_instance.system_metadata = inst_sys_meta
|
mock_instance.system_metadata = inst_sys_meta
|
||||||
|
@ -8598,13 +8705,20 @@ Active: 8381604 kB
|
||||||
mock_setup_container.return_value = '/dev/nbd0'
|
mock_setup_container.return_value = '/dev/nbd0'
|
||||||
mock_get_info.return_value = {'state': power_state.SHUTDOWN}
|
mock_get_info.return_value = {'state': power_state.SHUTDOWN}
|
||||||
|
|
||||||
domain = conn._create_domain(domain=mock_domain,
|
with contextlib.nested(
|
||||||
instance=mock_instance)
|
mock.patch.object(conn, '_create_images_and_backing'),
|
||||||
|
mock.patch.object(conn, '_is_booted_from_volume',
|
||||||
|
return_value=False),
|
||||||
|
mock.patch.object(conn, '_create_domain'),
|
||||||
|
mock.patch.object(conn, 'plug_vifs'),
|
||||||
|
mock.patch.object(conn.firewall_driver, 'setup_basic_filtering'),
|
||||||
|
mock.patch.object(conn.firewall_driver, 'prepare_instance_filter'),
|
||||||
|
mock.patch.object(conn.firewall_driver, 'apply_instance_filter')):
|
||||||
|
conn._create_domain_and_network(self.context, 'xml',
|
||||||
|
mock_instance, [])
|
||||||
|
|
||||||
self.assertEqual(mock_domain, domain)
|
|
||||||
self.assertEqual('/dev/nbd0', inst_sys_meta['rootfs_device_name'])
|
self.assertEqual('/dev/nbd0', inst_sys_meta['rootfs_device_name'])
|
||||||
mock_instance.save.assert_has_calls([mock.call()])
|
mock_instance.save.assert_has_calls([mock.call()])
|
||||||
mock_domain.createWithFlags.assert_has_calls([mock.call(0)])
|
|
||||||
mock_get_inst_path.assert_has_calls([mock.call(mock_instance)])
|
mock_get_inst_path.assert_has_calls([mock.call(mock_instance)])
|
||||||
mock_ensure_tree.assert_has_calls([mock.call('/tmp/rootfs')])
|
mock_ensure_tree.assert_has_calls([mock.call('/tmp/rootfs')])
|
||||||
conn.image_backend.image.assert_has_calls([mock.call(mock_instance,
|
conn.image_backend.image.assert_has_calls([mock.call(mock_instance,
|
||||||
|
@ -9098,15 +9212,18 @@ Active: 8381604 kB
|
||||||
self.flags(virt_type='lxc', group='libvirt')
|
self.flags(virt_type='lxc', group='libvirt')
|
||||||
|
|
||||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||||
instance = objects.Instance(id=1, uuid='fake-uuid')
|
instance = objects.Instance(id=1, uuid='fake-uuid',
|
||||||
|
image_ref='my_fake_image')
|
||||||
|
|
||||||
with contextlib.nested(
|
with contextlib.nested(
|
||||||
|
mock.patch.object(conn, '_is_booted_from_volume',
|
||||||
|
return_value=False),
|
||||||
mock.patch.object(conn, 'plug_vifs'),
|
mock.patch.object(conn, 'plug_vifs'),
|
||||||
mock.patch.object(conn, 'firewall_driver'),
|
mock.patch.object(conn, 'firewall_driver'),
|
||||||
mock.patch.object(conn, '_create_domain',
|
mock.patch.object(conn, '_create_domain',
|
||||||
side_effect=exception.NovaException),
|
side_effect=exception.NovaException),
|
||||||
mock.patch.object(conn, 'cleanup')) as (
|
mock.patch.object(conn, 'cleanup')) as (
|
||||||
cleanup, firewall_driver, create, plug_vifs):
|
cleanup, firewall_driver, create, plug_vifs, boot):
|
||||||
self.assertRaises(exception.NovaException,
|
self.assertRaises(exception.NovaException,
|
||||||
conn._create_domain_and_network,
|
conn._create_domain_and_network,
|
||||||
self.context,
|
self.context,
|
||||||
|
@ -9116,43 +9233,26 @@ Active: 8381604 kB
|
||||||
def test_create_without_pause(self):
|
def test_create_without_pause(self):
|
||||||
self.flags(virt_type='lxc', group='libvirt')
|
self.flags(virt_type='lxc', group='libvirt')
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def fake_lxc_disk_handler(*args, **kwargs):
|
||||||
|
yield
|
||||||
|
|
||||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||||
instance = objects.Instance(id=1, uuid='fake-uuid')
|
instance = objects.Instance(id=1, uuid='fake-uuid')
|
||||||
|
|
||||||
with contextlib.nested(
|
with contextlib.nested(
|
||||||
|
mock.patch.object(conn, '_lxc_disk_handler',
|
||||||
|
side_effect=fake_lxc_disk_handler),
|
||||||
mock.patch.object(conn, 'plug_vifs'),
|
mock.patch.object(conn, 'plug_vifs'),
|
||||||
mock.patch.object(conn, 'firewall_driver'),
|
mock.patch.object(conn, 'firewall_driver'),
|
||||||
mock.patch.object(conn, '_create_domain'),
|
mock.patch.object(conn, '_create_domain'),
|
||||||
mock.patch.object(conn, 'cleanup')) as (
|
mock.patch.object(conn, 'cleanup')) as (
|
||||||
cleanup, firewall_driver, create, plug_vifs):
|
_handler, cleanup, firewall_driver, create, plug_vifs):
|
||||||
domain = conn._create_domain_and_network(self.context, 'xml',
|
domain = conn._create_domain_and_network(self.context, 'xml',
|
||||||
instance, None)
|
instance, None)
|
||||||
self.assertEqual(0, create.call_args_list[0][1]['launch_flags'])
|
self.assertEqual(0, create.call_args_list[0][1]['launch_flags'])
|
||||||
self.assertEqual(0, domain.resume.call_count)
|
self.assertEqual(0, domain.resume.call_count)
|
||||||
|
|
||||||
def test_lxc_create_and_rootfs_saved(self):
|
|
||||||
self.flags(virt_type='lxc', group='libvirt')
|
|
||||||
|
|
||||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
|
||||||
instance = db.instance_create(self.context, self.test_instance)
|
|
||||||
inst_obj = objects.Instance.get_by_uuid(self.context, instance['uuid'])
|
|
||||||
|
|
||||||
with contextlib.nested(
|
|
||||||
mock.patch('nova.virt.disk.api.setup_container',
|
|
||||||
return_value='/dev/nbd1'),
|
|
||||||
mock.patch('nova.virt.disk.api.clean_lxc_namespace'),
|
|
||||||
mock.patch('nova.openstack.common.fileutils.ensure_tree'),
|
|
||||||
mock.patch.object(conn.image_backend, 'image'),
|
|
||||||
mock.patch.object(conn, '_enable_hairpin'),
|
|
||||||
mock.patch.object(conn, 'get_info',
|
|
||||||
return_value={'state': power_state.RUNNING})
|
|
||||||
):
|
|
||||||
conn._conn.defineXML = mock.Mock()
|
|
||||||
conn._create_domain('xml', instance=inst_obj)
|
|
||||||
self.assertEqual('/dev/nbd1',
|
|
||||||
inst_obj.system_metadata.get(
|
|
||||||
'rootfs_device_name'))
|
|
||||||
|
|
||||||
def _test_create_with_network_events(self, neutron_failure=None,
|
def _test_create_with_network_events(self, neutron_failure=None,
|
||||||
power_on=True):
|
power_on=True):
|
||||||
generated_events = []
|
generated_events = []
|
||||||
|
|
|
@ -25,6 +25,7 @@ Supports KVM, LXC, QEMU, UML, and XEN.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import contextlib
|
||||||
import errno
|
import errno
|
||||||
import functools
|
import functools
|
||||||
import glob
|
import glob
|
||||||
|
@ -2589,9 +2590,8 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
disk_info, image_meta,
|
disk_info, image_meta,
|
||||||
block_device_info=block_device_info,
|
block_device_info=block_device_info,
|
||||||
write_to_disk=True)
|
write_to_disk=True)
|
||||||
|
|
||||||
self._create_domain_and_network(context, xml, instance, network_info,
|
self._create_domain_and_network(context, xml, instance, network_info,
|
||||||
block_device_info)
|
block_device_info, disk_info=disk_info)
|
||||||
LOG.debug("Instance is running", instance=instance)
|
LOG.debug("Instance is running", instance=instance)
|
||||||
|
|
||||||
def _wait_for_boot():
|
def _wait_for_boot():
|
||||||
|
@ -4031,15 +4031,33 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
'cpu_time': dom_info[4],
|
'cpu_time': dom_info[4],
|
||||||
'id': virt_dom.ID()}
|
'id': virt_dom.ID()}
|
||||||
|
|
||||||
def _create_domain_setup_lxc(self, instance):
|
def _create_domain_setup_lxc(self, instance, block_device_info, disk_info):
|
||||||
inst_path = libvirt_utils.get_instance_path(instance)
|
inst_path = libvirt_utils.get_instance_path(instance)
|
||||||
|
block_device_mapping = driver.block_device_info_get_mapping(
|
||||||
|
block_device_info)
|
||||||
|
disk_info = disk_info or {}
|
||||||
|
disk_mapping = disk_info.get('mapping', [])
|
||||||
|
|
||||||
|
if self._is_booted_from_volume(instance, disk_mapping):
|
||||||
|
root_disk = block_device.get_root_bdm(block_device_mapping)
|
||||||
|
disk_path = root_disk['connection_info']['data']['device_path']
|
||||||
|
disk_info = blockinfo.get_info_from_bdm(
|
||||||
|
CONF.libvirt.virt_type, root_disk)
|
||||||
|
self._connect_volume(root_disk['connection_info'], disk_info)
|
||||||
|
|
||||||
|
# Get the system metadata from the instance
|
||||||
|
system_meta = utils.instance_sys_meta(instance)
|
||||||
|
use_cow = system_meta['image_disk_format'] == 'qcow2'
|
||||||
|
else:
|
||||||
|
image = self.image_backend.image(instance, 'disk')
|
||||||
|
disk_path = image.path
|
||||||
|
use_cow = CONF.use_cow_images
|
||||||
|
|
||||||
container_dir = os.path.join(inst_path, 'rootfs')
|
container_dir = os.path.join(inst_path, 'rootfs')
|
||||||
fileutils.ensure_tree(container_dir)
|
fileutils.ensure_tree(container_dir)
|
||||||
|
rootfs_dev = disk.setup_container(disk_path,
|
||||||
image = self.image_backend.image(instance, 'disk')
|
container_dir=container_dir,
|
||||||
rootfs_dev = disk.setup_container(image.path,
|
use_cow=use_cow)
|
||||||
container_dir=container_dir,
|
|
||||||
use_cow=CONF.use_cow_images)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Save rootfs device to disconnect it when deleting the instance
|
# Save rootfs device to disconnect it when deleting the instance
|
||||||
|
@ -4072,6 +4090,28 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
else:
|
else:
|
||||||
disk.teardown_container(container_dir=container_dir)
|
disk.teardown_container(container_dir=container_dir)
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def _lxc_disk_handler(self, instance, block_device_info, disk_info):
|
||||||
|
"""Context manager to handle the pre and post instance boot,
|
||||||
|
LXC specific disk operations.
|
||||||
|
|
||||||
|
An image or a volume path will be prepared and setup to be
|
||||||
|
used by the container, prior to starting it.
|
||||||
|
The disk will be disconnected and unmounted if a container has
|
||||||
|
failed to start.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if CONF.libvirt.virt_type != 'lxc':
|
||||||
|
yield
|
||||||
|
return
|
||||||
|
|
||||||
|
self._create_domain_setup_lxc(instance, block_device_info, disk_info)
|
||||||
|
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
self._create_domain_cleanup_lxc(instance)
|
||||||
|
|
||||||
def _create_domain(self, xml=None, domain=None,
|
def _create_domain(self, xml=None, domain=None,
|
||||||
instance=None, launch_flags=0, power_on=True):
|
instance=None, launch_flags=0, power_on=True):
|
||||||
"""Create a domain.
|
"""Create a domain.
|
||||||
|
@ -4080,8 +4120,6 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
the domain definition is overwritten from the xml.
|
the domain definition is overwritten from the xml.
|
||||||
"""
|
"""
|
||||||
err = None
|
err = None
|
||||||
if instance and CONF.libvirt.virt_type == 'lxc':
|
|
||||||
self._create_domain_setup_lxc(instance)
|
|
||||||
try:
|
try:
|
||||||
if xml:
|
if xml:
|
||||||
err = _LE('Error defining a domain with XML: %s') % xml
|
err = _LE('Error defining a domain with XML: %s') % xml
|
||||||
|
@ -4100,9 +4138,6 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
if err:
|
if err:
|
||||||
LOG.error(err)
|
LOG.error(err)
|
||||||
finally:
|
|
||||||
if instance and CONF.libvirt.virt_type == 'lxc':
|
|
||||||
self._create_domain_cleanup_lxc(instance)
|
|
||||||
|
|
||||||
return domain
|
return domain
|
||||||
|
|
||||||
|
@ -4124,7 +4159,8 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
|
|
||||||
def _create_domain_and_network(self, context, xml, instance, network_info,
|
def _create_domain_and_network(self, context, xml, instance, network_info,
|
||||||
block_device_info=None, power_on=True,
|
block_device_info=None, power_on=True,
|
||||||
reboot=False, vifs_already_plugged=False):
|
reboot=False, vifs_already_plugged=False,
|
||||||
|
disk_info=None):
|
||||||
|
|
||||||
"""Do required network setup and create domain."""
|
"""Do required network setup and create domain."""
|
||||||
block_device_mapping = driver.block_device_info_get_mapping(
|
block_device_mapping = driver.block_device_info_get_mapping(
|
||||||
|
@ -4132,9 +4168,9 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
|
|
||||||
for vol in block_device_mapping:
|
for vol in block_device_mapping:
|
||||||
connection_info = vol['connection_info']
|
connection_info = vol['connection_info']
|
||||||
disk_info = blockinfo.get_info_from_bdm(
|
info = blockinfo.get_info_from_bdm(
|
||||||
CONF.libvirt.virt_type, vol)
|
CONF.libvirt.virt_type, vol)
|
||||||
conf = self._connect_volume(connection_info, disk_info)
|
conf = self._connect_volume(connection_info, info)
|
||||||
|
|
||||||
# cache device_path in connection_info -- required by encryptors
|
# cache device_path in connection_info -- required by encryptors
|
||||||
if 'data' in connection_info:
|
if 'data' in connection_info:
|
||||||
|
@ -4172,10 +4208,12 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
network_info)
|
network_info)
|
||||||
self.firewall_driver.prepare_instance_filter(instance,
|
self.firewall_driver.prepare_instance_filter(instance,
|
||||||
network_info)
|
network_info)
|
||||||
domain = self._create_domain(
|
with self._lxc_disk_handler(instance, block_device_info,
|
||||||
xml, instance=instance,
|
disk_info):
|
||||||
launch_flags=launch_flags,
|
domain = self._create_domain(
|
||||||
power_on=power_on)
|
xml, instance=instance,
|
||||||
|
launch_flags=launch_flags,
|
||||||
|
power_on=power_on)
|
||||||
|
|
||||||
self.firewall_driver.apply_instance_filter(instance,
|
self.firewall_driver.apply_instance_filter(instance,
|
||||||
network_info)
|
network_info)
|
||||||
|
|
Loading…
Reference in New Issue