Merge "VMware: fix bug with booting from volumes" into stable/havana

This commit is contained in:
Jenkins 2013-10-31 07:38:20 +00:00 committed by Gerrit Code Review
commit 2e3da55097
3 changed files with 42 additions and 30 deletions

View File

@ -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,

View File

@ -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 = [

View File

@ -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."""