Merge "VMware: fix bug with booting from volumes" into stable/havana
This commit is contained in:
commit
2e3da55097
@ -69,7 +69,7 @@ def stub_out_db_instance_api(stubs):
|
||||
'id': values['id'],
|
||||
'uuid': values['uuid'],
|
||||
'reservation_id': utils.generate_uid('r'),
|
||||
'image_ref': values['image_ref'],
|
||||
'image_ref': values.get('image_ref'),
|
||||
'kernel_id': values['kernel_id'],
|
||||
'ramdisk_id': values['ramdisk_id'],
|
||||
'vm_state': vm_states.BUILDING,
|
||||
|
@ -158,7 +158,7 @@ class VMwareAPIVMTestCase(test.NoDBTestCase):
|
||||
self.conn = driver.VMwareAPISession()
|
||||
self.assertEqual(self.attempts, 2)
|
||||
|
||||
def _create_instance_in_the_db(self, node=None):
|
||||
def _create_instance_in_the_db(self, node=None, set_image_ref=True):
|
||||
if not node:
|
||||
node = self.node_name
|
||||
values = {'name': 'fake_name',
|
||||
@ -166,7 +166,6 @@ class VMwareAPIVMTestCase(test.NoDBTestCase):
|
||||
'uuid': "fake-uuid",
|
||||
'project_id': self.project_id,
|
||||
'user_id': self.user_id,
|
||||
'image_ref': "fake_image_uuid",
|
||||
'kernel_id': "fake_kernel_uuid",
|
||||
'ramdisk_id': "fake_ramdisk_uuid",
|
||||
'mac_address': "de:ad:be:ef:be:ef",
|
||||
@ -174,6 +173,8 @@ class VMwareAPIVMTestCase(test.NoDBTestCase):
|
||||
'node': node,
|
||||
'root_gb': 80,
|
||||
}
|
||||
if set_image_ref:
|
||||
values['image_ref'] = "fake_image_uuid"
|
||||
self.instance_node = node
|
||||
self.instance = db.instance_create(None, values)
|
||||
|
||||
@ -323,14 +324,11 @@ class VMwareAPIVMTestCase(test.NoDBTestCase):
|
||||
self.assertRaises(exception.InstanceUnacceptable,
|
||||
self._create_vm)
|
||||
|
||||
def test_spawn_attach_volume_vmdk(self):
|
||||
self._create_instance_in_the_db()
|
||||
def _spawn_attach_volume_vmdk(self, set_image_ref=True):
|
||||
self._create_instance_in_the_db(set_image_ref=set_image_ref)
|
||||
self.type_data = db.flavor_get_by_name(None, 'm1.large')
|
||||
self.mox.StubOutWithMock(block_device, 'volume_in_mapping')
|
||||
self.mox.StubOutWithMock(v_driver, 'block_device_info_get_mapping')
|
||||
ebs_root = 'fake_root'
|
||||
block_device.volume_in_mapping(mox.IgnoreArg(),
|
||||
mox.IgnoreArg()).AndReturn(ebs_root)
|
||||
connection_info = self._test_vmdk_connection_info('vmdk')
|
||||
root_disk = [{'connection_info': connection_info}]
|
||||
v_driver.block_device_info_get_mapping(
|
||||
@ -349,19 +347,23 @@ class VMwareAPIVMTestCase(test.NoDBTestCase):
|
||||
volumeops.VMwareVolumeOps.attach_volume(connection_info,
|
||||
self.instance, mox.IgnoreArg())
|
||||
self.mox.ReplayAll()
|
||||
block_device_info = {'mount_device': 'vda'}
|
||||
self.conn.spawn(self.context, self.instance, self.image,
|
||||
injected_files=[], admin_password=None,
|
||||
network_info=self.network_info,
|
||||
block_device_info=None)
|
||||
block_device_info=block_device_info)
|
||||
|
||||
def test_spawn_attach_volume_vmdk(self):
|
||||
self._spawn_attach_volume_vmdk()
|
||||
|
||||
def test_spawn_attach_volume_vmdk_no_image_ref(self):
|
||||
self._spawn_attach_volume_vmdk(set_image_ref=False)
|
||||
|
||||
def test_spawn_attach_volume_iscsi(self):
|
||||
self._create_instance_in_the_db()
|
||||
self.type_data = db.flavor_get_by_name(None, 'm1.large')
|
||||
self.mox.StubOutWithMock(block_device, 'volume_in_mapping')
|
||||
self.mox.StubOutWithMock(v_driver, 'block_device_info_get_mapping')
|
||||
ebs_root = 'fake_root'
|
||||
block_device.volume_in_mapping(mox.IgnoreArg(),
|
||||
mox.IgnoreArg()).AndReturn(ebs_root)
|
||||
connection_info = self._test_vmdk_connection_info('iscsi')
|
||||
root_disk = [{'connection_info': connection_info}]
|
||||
v_driver.block_device_info_get_mapping(
|
||||
@ -371,10 +373,11 @@ class VMwareAPIVMTestCase(test.NoDBTestCase):
|
||||
volumeops.VMwareVolumeOps.attach_volume(connection_info,
|
||||
self.instance, mox.IgnoreArg())
|
||||
self.mox.ReplayAll()
|
||||
block_device_info = {'mount_device': 'vda'}
|
||||
self.conn.spawn(self.context, self.instance, self.image,
|
||||
injected_files=[], admin_password=None,
|
||||
network_info=self.network_info,
|
||||
block_device_info=None)
|
||||
block_device_info=block_device_info)
|
||||
|
||||
def _test_snapshot(self):
|
||||
expected_calls = [
|
||||
|
@ -32,7 +32,6 @@ import uuid
|
||||
from oslo.config import cfg
|
||||
|
||||
from nova.api.metadata import base as instance_metadata
|
||||
from nova import block_device
|
||||
from nova import compute
|
||||
from nova.compute import power_state
|
||||
from nova.compute import task_states
|
||||
@ -165,6 +164,14 @@ class VMwareVMOps(object):
|
||||
4. Attach the disk to the VM by reconfiguring the same.
|
||||
5. Power on the VM.
|
||||
"""
|
||||
ebs_root = False
|
||||
if block_device_info:
|
||||
LOG.debug(_("Block device information present: %s")
|
||||
% block_device_info, instance=instance)
|
||||
block_device_mapping = driver.block_device_info_get_mapping(
|
||||
block_device_info)
|
||||
if block_device_mapping:
|
||||
ebs_root = True
|
||||
|
||||
client_factory = self._session._get_vim().client.factory
|
||||
service_content = self._session._get_vim().get_service_content()
|
||||
@ -177,14 +184,19 @@ class VMwareVMOps(object):
|
||||
# The use of nested functions in this file makes for a confusing and
|
||||
# hard to maintain file. At some future date, refactor this method to
|
||||
# be a full-fledged method. This will also make unit testing easier.
|
||||
def _get_image_properties():
|
||||
def _get_image_properties(root_size):
|
||||
"""
|
||||
Get the Size of the flat vmdk file that is there on the storage
|
||||
repository.
|
||||
"""
|
||||
_image_info = vmware_images.get_vmdk_size_and_properties(context,
|
||||
instance['image_ref'],
|
||||
instance)
|
||||
image_ref = instance.get('image_ref')
|
||||
if image_ref:
|
||||
_image_info = vmware_images.get_vmdk_size_and_properties(
|
||||
context, image_ref, instance)
|
||||
else:
|
||||
# The case that the image may be booted from a volume
|
||||
_image_info = (root_size, {})
|
||||
|
||||
image_size, image_properties = _image_info
|
||||
vmdk_file_size_in_kb = int(image_size) / 1024
|
||||
os_type = image_properties.get("vmware_ostype", "otherGuest")
|
||||
@ -204,11 +216,12 @@ class VMwareVMOps(object):
|
||||
return (vmdk_file_size_in_kb, os_type, adapter_type, disk_type,
|
||||
vif_model, image_linked_clone)
|
||||
|
||||
(vmdk_file_size_in_kb, os_type, adapter_type,
|
||||
disk_type, vif_model, image_linked_clone) = _get_image_properties()
|
||||
|
||||
root_gb = instance['root_gb']
|
||||
root_gb_in_kb = root_gb * 1024 * 1024
|
||||
|
||||
(vmdk_file_size_in_kb, os_type, adapter_type, disk_type, vif_model,
|
||||
image_linked_clone) = _get_image_properties(root_gb_in_kb)
|
||||
|
||||
if root_gb_in_kb and vmdk_file_size_in_kb > root_gb_in_kb:
|
||||
reason = _("Image disk size greater than requested disk size")
|
||||
raise exception.InstanceUnacceptable(instance_id=instance['uuid'],
|
||||
@ -393,9 +406,6 @@ class VMwareVMOps(object):
|
||||
"data_store_name": data_store_name},
|
||||
instance=instance)
|
||||
|
||||
ebs_root = block_device.volume_in_mapping(
|
||||
self._default_root_device, block_device_info)
|
||||
|
||||
if not ebs_root:
|
||||
# this logic allows for instances or images to decide
|
||||
# for themselves which strategy is best for them.
|
||||
@ -521,12 +531,11 @@ class VMwareVMOps(object):
|
||||
|
||||
else:
|
||||
# Attach the root disk to the VM.
|
||||
root_disk = driver.block_device_info_get_mapping(
|
||||
block_device_info)[0]
|
||||
connection_info = root_disk['connection_info']
|
||||
self._volumeops.attach_root_volume(connection_info, instance,
|
||||
self._default_root_device,
|
||||
data_store_ref)
|
||||
for root_disk in block_device_mapping:
|
||||
connection_info = root_disk['connection_info']
|
||||
self._volumeops.attach_root_volume(connection_info, instance,
|
||||
self._default_root_device,
|
||||
data_store_ref)
|
||||
|
||||
def _power_on_vm():
|
||||
"""Power on the VM."""
|
||||
|
Loading…
Reference in New Issue
Block a user